Category

Web Development

WordPress Dynamically generate image sizes on the fly

WordPress: How to create image sizes dynamically on the fly

By | Web Development, WordPress | No Comments

WordPress is awesome. But like any system, it’s not great at everything. One of those things is media image size management, where it just doesn’t work well.

The Problems:

WordPress uses something called “Thumbnail Image Sizes” to maintain different versions of your images in different image sizes. You define these image sizes under Settings -> Media and some custom ones in your theme, as needed.

When you upload an image in your WordPress admin, WordPress automatically generates the thumbnails as soon as the image is uploaded. This causes the following issues:

  1. The image sizes are created forever when you upload an image. In your development process, if you realize that you want to change an image size after thousands of images have been uploaded, the default way is to upload all those images all over again. Fortunately, there are plugins which automatically regenerate thumbnails, but it’s still a hassle.
  2. If you have 20 custom image sizes (maybe 2x, 3x for responsive images), and upload an image in the WordPress admin, it creates 20 thumbnail versions based on the sizes you defined in add_image_size(), even though you might only need one. That means 19 thumbnails in this example would go for a waste. Imagine if you have thousands of images where 19 image thumbnails are created as a waste! This increases the size of the media library unnecessarily.

 

Solutions:

The solution for changing image sizes as mentioned above, would be to use a plugin to automatically regenerate thumbnails either individually or for all your images. The Regenerate Thumbnails plugin does a great job of this. But this has to be manually done, and isn’t the optimal solution.

Unfortunately, there is no solution for the fact that there will be additional unnecessary images created with the add_image_size() method.

 

Using the Fly Dynamic Image Resizer:

I was so frustrated with this problem, that I decided to build my own plugin. Introducing: Fly Dynamic Image Resizer for WordPress! If you want to contribute to this plugin, you can do so on Github.

How this plugin works:

  • You can define image sizes in your theme, or just directly add the image sizes in your code
  • When a user visits a page for the first time and comes across a dynamic image, the dynamic image thumbnail is created and stored under /wp-content/uploads/fly-images/{image_id}/{image_size}
  • When users visit the page the next time onwards, they are served the newly created image
  • If you want to delete all the cached / stored image sizes, you can do so under Tools -> Fly Images
  • If you want to delete only a single image’s cached / stored image sizes, you can do so in the media library

Defining dynamic image sizes in your theme

You can add as many image sizes in your theme’s functions.php file like so:

if ( function_exists( 'fly_add_image_size' ) ) {
    fly_add_image_size( 'home_page_square', 500, 500, true );
    fly_add_image_size( 'home_page_square_2x', 1000, 1000, true );
}

Explanation of parameters:

  1. The first is the name of the size
  2. The width
  3. The height
  4. Whether you want to crop this image from the center

Method 1: Using pre-defined image sizes

If you’ve defined image sizes using the method above, you get an image like so:

fly_get_attachment_image( $attachment_id, 'your_image_size' );

So, using the example of image sizes declared above, your code would look like:

echo fly_get_attachment_image( get_post_thumbnail_id(), 'home_page_square' );

This would return a HTML image string. If you want the image as an array, you can use:

$image = fly_get_attachment_image_src( get_post_thumbnail_id(), 'home_page_square' );

Method 2: Using explicit image sizes

If you don’t want to declare any image sizes, and just want a dynamically generated image size, you can directly enter the image dimensions in the code like so:

fly_get_attachment_image( $attachment_id, array( $width, $height ), $crop );

So, if you want to get an image size of your own dimensions, your code would look like:

echo fly_get_attachment_image( get_post_thumbnail_id(), array( 500, 500 ), true );

This would return a HTML image string. If you want the image as an array, you can use:

$image = fly_get_attachment_image_src( get_post_thumbnail_id(), array( 500, 500 ), true );

Using custom image attributes

The image HTML that this plugin returns uses the attributes like “alt” from the media library. If you want to use your own, you can do it like so:

echo fly_get_attachment_image( get_post_thumbnail_id(), 'home_page_square', null, array( 'alt' => 'My custom alt value!' ) );

 

I hope this helps you in building your theme optimally 🙂

WordPress dynamically change user capabilities

By | Web Development, WordPress | No Comments

I was looking for an easy way to dynamically add or remove capabilities for users based on either their IDs or roles, but I couldn’t find any elegant solution. That is until I found a beautiful filter:

https://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap

It’s so simple, and you can just add this to your functions.php file, or use it in your own plugin:

/**
 * User Capabilities
 * 
 * @see https://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap
 */
function jb_user_capabilities( $allcaps, $cap, $args ) {
	// Get current user ID
	$user_id = get_current_user_id();

	// Get current user
	$current_user = get_user_by( 'id', $user_id );

	// Remove capabilities
	if ( in_array( 'administrator', $current_user->roles ) ) {
		$allcaps['activate_plugins'] = false;
		$allcaps['update_core'] = false;
		$allcaps['update_plugins'] = false;
		$allcaps['update_themes'] = false;
		$allcaps['switch_themes'] = false;
		$allcaps['edit_themes'] = false;
		$allcaps['install_plugins'] = false;
		$allcaps['install_themes'] = false;
		$allcaps['delete_themes'] = false;
		$allcaps['delete_plugins'] = false;
		$allcaps['edit_plugins'] = false;
		$allcaps['edit_themes'] = false;
		$allcaps['edit_files'] = false;
		$allcaps['edit_users'] = false;
		$allcaps['create_users'] = false;
		$allcaps['delete_users'] = false;
		$allcaps['list_users'] = false;
	}
	
	return $allcaps;
}
add_filter( 'user_has_cap', 'jb_user_capabilities', 10, 3 );

You can see a list of all roles and capabilities here:
https://codex.wordpress.org/Roles_and_Capabilities

Setting capabilities to “true” enables them, and setting them to “false” disables them. Simple! The above function could be useful when you want to give access to your SEO team, for example. Since this adds or removes capabilities, it is the best way to securely hide menu items in the WP Admin side.

Hope this helps, happy coding! 🙂

How to get the second level navigation only from WordPress wp_nav_menu()

How to get the second level navigation only from WordPress wp_nav_menu()

By | Web Development, WordPress | 6 Comments

We’ve all been there. There’s a perfectly good menu in the admin under Appearance -> Menus which has the whole site laid out perfectly.

Now we start coding the templates and realize that we only need sub-menu items of a particular page, of a particular level from that menu. There are two ways to do this out of the box:

  1. Create a separate menu for each requirement
  2. Create a custom Walker Class which allows you to only choose only the sub-menu from the main menu

For obvious reasons, the first option is not the best way to do it. The second option solves the problem quite well. But you can’t keep writing a walker class for every project, and not every developer – particularly new developers – is familiar with how this works.

This should be something that comes out of the box, which it does on other platforms like Joomla. When you delve into the code of WordPress and see the function responsible for this ( /wp-includes/nav-menu-template.php :: wp_nav_menu() ), you quickly realize that this function was written without any foresight for extendability.

I have solved this problem of extending this function by writing a plugin!
https://wordpress.org/plugins/wp-nav-menu-extended/

It extends the native wp_nav_menu function so you don’t need to add any special functions to the code. It just adds a few options that I felt were missing. Here are the options:

level : (integer) (required for this plugin to work) The level of the navigation menu to show. If no child_of parameter is passed, it shows all the items of this level

child_of : (string|integer) (optional) Either the title or menu item ID of the parent in the menu whose direct children are to be shown

This is how easy it is to use:

$defaults = array(
    'theme_location' => 'main_menu',
    'level' => 2,
    'child_of' => 'About Us'
);

wp_nav_menu( $defaults );

So, the child_of option can either be the title of the parent’s menu item, or the menu item ID of the parent, so that you don’t have to hardcore the title in the code. Here is one easy way to find the menu item ID:

Hover your mouse on top of the menu item that you want, and look for the item ID in the status bar. In this case it is 466.

I hope this makes it easy for you to build your site! I’ll be open to adding more features to this plugin, so feel free to write in any feature requests in the comments.

Happy coding!

How to add a color picker in the Magento admin or anywhere

How to add a color picker in the Magento admin or anywhere

By | Magento, Web Development | 8 Comments

Greetings, developers of all colors!

First of all this tutorial assumes that you already know how to make a Magento extension. Now there are many ways to add a color picker in the Magento admin (or anywhere). Here’s one “correct” and “extendable” way to do it:

First, we would need a color picker. This color picker should not use any JavaScript framework so it fits in easily with Prototype, which is used in Magento. If you don’t already know this: Magento has switched to jQuery from version 2 onwards. So it would be nice to have a color picker that would work basically anywhere.

If you’ve spent about 10 seconds trying to look for a color picker, you’ve probably stumbled upon JsColor. I’ve read a few posts that show you how to integrate it into your Magento admin, but as always, I’ve not found anything that is thorough enough. So here’s my effort to simplify it for you. Here is a bare-bones extension to help you understand how this works:

Step 1: Download this file and extract it to /app/code/local
Step 2: Download this file and extract it to /app/etc/modules
Step 3: Download this file and extract is to /app/design/adminhtml/default/default/layout
Step 4: Download this file and extract it to /js

And you’re done! (Don’t forget to clear all caches, log out and log in etc.) . Navigate to System -> Configuration -> Your Module and choose your color!

Explanation:

First, we add the JSColor file in the admin head using this file: /app/design/adminhtml/default/default/layout/yourmodule.xml

Next, let’s explore the file: /app/code/local/Yourcompany/Yourmodule/Block/Adminhtml/System/Config/Color.php

The magic happens in this line:

$color->addClass( 'color ' . $element->getClass() );

JSColor requires that the input field have a class “color” for it to work. So we add it here in this line, along with any other classes that might be required on the field. The other classes might also include classes entered in the “validate” section of your field.

In the file /app/code/local/Yourcompany/Yourmodule/etc/system.xml

<my_color translate="label">
<label>My Color</label>
<frontend_type>text</frontend_type>
<frontend_model>yourmodule/adminhtml_system_config_color</frontend_model>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<validate>required-entry</validate>
</my_color>

The “required-entry” class is added to the field after the “color” class since it is added inside “validate”.

But wait …

I can’t see the JSColor’s image when I select the color! If you can, ignore the following.

Magento has a “Merge JavaScript” option under System -> Advanced -> Developer . When this option is enabled, JSColor would break, and not show the color picker image because it can’t find the JSColor directory where the image is located. Which is why we’ve modified the JSColor file at /js/yourcompany/jscolor/jscolor.js

dir : BLANK_URL.replace( 'blank.html', 'yourcompany/jscolor/' )

Magento has a JavaScript variable called “BLANK_URL” both in the admin and front end. It points to /js/blank.html . We can use this to find out the path to the JS folder. So what we’ve done is removed “blank.html” and replaced it with “yourcompany/jscolor/” so the string would now be /js/yourmodule/jscolor/ which can now be used by JSColor to load the image.


Happy coloring!

Magento direct SQL queries with named binding

Magento direct SQL queries with named binding

By | Magento, Web Development | 2 Comments

If you’ve been coding in Magento long enough, you would have come across a situation where you need to query the database directly. For whatever reason, no judgements.

Well, here is my contribution to save you a lot of time. And this is as secure as using models to interact with your database. If you think otherwise, I’d love to hear your thoughts in the comments section.

Direct safe SQL queries in Magento using named binding for security:

Step 1: Initialize a resource to interact with the database:

$read = Mage::getSingleton( 'core/resource' )->getConnection( 'core_read' ); // To read from the database
$write = Mage::getSingleton( 'core/resource' )->getConnection( 'core_write' ); // To write to the database

 

Step 2: Choose which tables you want to connect with. Using this method also takes care of the problem of prefixed tables on some stores. It’s the safest way to go about this.

$productTable = Mage::getSingleton( 'core/resource' )->getTableName( 'catalog_product_entity' );

 

Step 3: Prepare your query

$query = "SELECT product_id FROM " . $productTable . " WHERE created_at BETWEEN :fromdate AND :todate";
$binds = array(
	'fromdate' => $unsafePostedValue1,
	'todate' => $unsafePostedValue2
);

 

Step 4: Execute your query!

$result = $read->query( $query, $binds );
while ( $row = $result->fetch() ) {
	echo 'Product ID: ' . $row['product_id'] . '<br>';
}

 

Explanation:
Our read resource takes our query and looks for something like :this . It then looks for a bind array which it then maps the value of this to :this . What’s more is that it automatically quotes and prepares all the security measures before executing the query. So you don’t need to quote the query at all! In fact, it will give you an error if you quote the query!

 

Inserting into the database:

Here’s how you insert into the database:

$query = "INSERT INTO " . $productTable . " SET product_id = :product_id";
$binds = array(
	'product_id' => $unsafePostedId
);
$write->query( $query, $binds );

 

Happy coding! 🙂

How to add custom styles in the Wordpress TinyMCE editor without a plugin

How to add custom styles in the WordPress TinyMCE editor without a plugin

By | Web Development, WordPress | 2 Comments

I’m sure you’ve run into this issue so many times if you’ve made themes whose complexity ranges from medium to tearing-your-hair-out-and-wishing-the-designer-has-diarrhea: The admin needs to be able to add a custom style to one of the elements from the WordPress editor. Sounds simple enough, and it is.

But before you go styling away, always keep this to a minimum. Although WordPress and other publishing platforms are used as Content Management Systems, the meaning of that phrase seems to be misunderstood. “Content” management is exactly that: managing content. This means the layout and styles are supposed to be kept separate from the content. But there are cases where this cannot be avoided, and those are exactly the cases for which this post was created.

As always, this is done in three easy steps:

Step 1: Edit your functions.php

If you don’t have a functions.php files in your theme, create one, and add the following code:

// Add a "styleselect" drop down menu to the editor
add_filter( 'mce_buttons_2', 'my_awesome_buttons' );
function my_awesome_buttons( $buttons ) {
    array_unshift( $buttons, 'styleselect' );
    return $buttons;
}

// Initialize our buttons
add_filter( 'tiny_mce_before_init', 'init_my_awsome_buttons' );
function init_my_awsome_buttons( $settings ) {

    $style_formats = array(
        array(
        	'title' => 'Super Div',
        	'block' => 'div',
        	'classes' => 'super-div',
        	'wrapper' => true // --- * Notice how this is a wrapper * ---
        ),
    	array(
    		'title' => 'Awesome Button Link',
    		'selector' => 'a', // --- * This means it will only work with A's * ---
    		'classes' => 'awesome-button-link'
    	)
    );

    $settings['style_formats'] = json_encode( $style_formats );

    return $settings;
}

// Add style sheet for the custom styles to the TinyMCE Editor in the Admin
function awesome_tinymce_css( $blah ) {
	$blah .= ',' . get_bloginfo('stylesheet_directory') . '/awesome.css';
	return $blah;
}
// We now tell WordPress to load our style sheet inside its editor!
add_filter( 'mce_css', 'awesome_tinymce_css' );

Step 2: awesome.css

Create an “awesome.css” and put it in your theme’s directory. We will use this files to make our awesome styles appear in the TinyMCE editor.

.super-div {
	border:1px dotted #CCC;
	padding:5px;
}
.awesome-button-link {
	display:inline-block;
	padding:5px;
	background-color:#F90;
	color:#FFF;
}

Step 3: Be awesome

Now add a new Post or Page in your WordPress admin and you can try out your newly created styles like so:

  • Add a Super Div by selecting it from the “Styles” dropdown
  • Type some text and make it a link. Remember, according to our code the Awesome Button Link only works with an ‘A’ tag
  • Once you’ve made a link, select it and apply the “Awesome Button Link” style to it
  • Impress your client!

Here’s an example of how our code works:

How to make a custom Magento payment extension for an external gateway

How to make a custom Magento payment extension for an external gateway

By | Magento, Web Development | 251 Comments

Magento is a great open source e-commerce platform and has emerged as the market leader in the recent past. However, it still has a steep learning curve and although the community is growing exponentially, I was not able to find a simple tutorial on how to make a Magento payment extension which links up to an external payment gateway.

In this tutorial, I’m going to attempt to show you how to make a bare-minimum extension, which you’ll need to complete because different payment gateways have different APIs, hooks and functionality. This is by no means a definitive guide, but my attempt to try and get you started. Please note this tutorial assumes that you already know how to build a simple custom extension and have average knowledge of Magento, MVC architecture and of course, PHP. This tutorial is for Magento versions 1.4 and above.

I have created a bare-minimum version of the extension which you need to download from the steps that follow. I hope the code will be self-explanatory. For information from Magento’s wiki click here.

Step #1: Click here to download the ZIP archive for this step. Extract it to app/code/local

Step #2: Click here to download the ZIP archive for this step. Extract it to app/design/frontend/base/default/template

Step #3: Click here to download the ZIP archive for this step. Extract it to app/etc/modules

Once you have done this, you need to follow the following steps to get it working:

  1. Open app/code/local/Myname/Mygateway/controllers/PaymentController.php and read through the inline comments carefully. The URL that the payment gateway needs to redirect to on your web site after processing the customer’s payment (based on the naming we’ve used in this example) should be: http://www.yourwebsite.com/mygateway/payment/response . This URL will trigger the responseAction() function in the PaymentController, where we will need to validate the response sent by the gateway (to make sure it’s really from there), and if validated, process the order. The validation code is generally provided by the payment gateway.
  2. Open app/design/frontend/base/default/template/mygateway/redirect.phtml . This is where we post our values to our external gateway. We can retrieve any order information and pass it on as hidden form fields, which is submitted via JavaScript.
  3. Log into your Magento admin, clear your cache, and make sure the extension is enabled and working fine by navigating to System -> Configuration -> Sales -> Payment Methods and checking if you can see it there.

It is extremely important to go through all the files to get a perfect understanding of the extension. I figured the best way to learn this is to look at a working example. This took me a long time to figure out and I hope this saves a lot of effort for someone. Happy coding!