Blog posts under the programming tips tag https://webdevstudios.com/tags/programming-tips/ WordPress Design and Development Agency Mon, 15 Apr 2024 16:01:58 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://webdevstudios.com/wp-content/uploads/2022/07/cropped-wds-icon.white-on-dark-60x60.png Blog posts under the programming tips tag https://webdevstudios.com/tags/programming-tips/ 32 32 58379230 How to Migrate a Widget to a Custom Post Type https://webdevstudios.com/2016/12/20/how-to-migrate-a-widget-to-custom-post-type/ https://webdevstudios.com/2016/12/20/how-to-migrate-a-widget-to-custom-post-type/#respond Tue, 20 Dec 2016 15:30:28 +0000 https://webdevstudios.com/?p=13769 Recently, one of my favorite themes, Zerif Lite, was suspended from the WordPress repo. As I was reading about the issues involved, it got me thinking: Just how hard is it to migrate a widget to a Custom Post Type? According to ThemeIsle, this was one of the factors which led to their decision, arguing that “changing this Read More How to Migrate a Widget to a Custom Post Type

The post How to Migrate a Widget to a Custom Post Type appeared first on WebDevStudios.

]]>
Recently, one of my favorite themes, Zerif Lite, was suspended from the WordPress repo. As I was reading about the issues involved, it got me thinking: Just how hard is it to migrate a widget to a Custom Post Type? According to ThemeIsle, this was one of the factors which led to their decision, arguing that “changing this in an existing theme means that whoever’s currently using it will get their site messed up.” Let me be clear: I refuse to take sides here, as there are valid points from both parties, so let’s leave the drama somewhere else. For now, let’s move forward and do something productive. Let’s migrate those old widgets.

Understanding How It Works

First and foremost, to figure this type of thing out, you absolutely must understand (at least very basically) the WordPress Template Hierarchy. Looking at the theme files, there’s the front-page.php file, which we know from looking at the hierarchy; it’s one of the first pages to load when viewing the homepage. We also know by looking at the customizer, for which Zerif was so popular, one of the widget sections is labeled “Our Focus.”

When we look through the front-page.php file, we immediately see the following code, around line 194:

    zerif_before_our_focus_trigger();

        get_template_part( 'sections/our_focus' );
        
    zerif_after_our_focus_trigger();

Luckily for us, the developer made the names quite logical. This snippet uses get_template_part() which is a core WordPress method (if you didn’t already know). This method literally includes a file, if it’s available, relative to the current file location. So, since we’re in the theme root, we now need to open up the sections/our_focus.php file.

Well, we know this section in the customizer uses widgets to create these sections, but we also know widgets are typically called by dynamic_sidebar(). Guess what. That’s just what we have around line 30:

                if ( is_active_sidebar( 'sidebar-ourfocus' ) ) :
                    dynamic_sidebar( 'sidebar-ourfocus' );
                else:

Picking It Apart

To understand how the widget orders are created, we first need to understand how dynamic_sidebar() ensures widgets are in order, and where the data for each widget is stored. You can view this function on trac for more context.

Well, we’re going to have to create a plugin or something similar to get this going, so let’s start with a simple singleton class:

<?php
/**
 * Plugin Name:     Widget to CPT
 * Plugin URI:      http://plugish.com
 * Description:     A simple how-to for migrating widgets to a CPT
 * Author:          JayWood
 * Author URI:      http://plugish.com
 * Version:         0.1.0
 */

class JW_Widget_to_CPT {

    /**
     * Instance of JW_Widget_to_CPT
     * @var JW_Widget_to_CPT
     */
    public static $instance = null;

    public static function init() {
        if ( null == self::$instance ) {
            self::$instance = new self();
        }
        
        return self::$instance;
    }

    public function hooks() {
        // All hooks here.
    }
}

function jw_widget_to_cpt() {
    return JW_Widget_to_CPT::init();
}
add_action( 'plugins_loaded', array( jw_widget_to_cpt(), 'hooks' ) );

Looking through the dynamic sidebar method, we first see two globals: $wp-registered_sidebars and $wp_registered_widgets respectively.

So, how do we figure out what they show?

I wrote a post awhile back about debugging WordPress with tips and snippets. You may want to check that out.

The example below shows you how to do this:

    public function hooks() {
        // All hooks here.
        add_action( 'init', array( $this, 'kill_it' ) );
    }

    public function kill_it() {
        global $wp_registered_sidebars, $wp_registered_widgets;

        error_log( print_r( compact( 'wp_registered_sidebars', 'wp_registered_widgets' ), 1 ) );
    }

This will produce two arrays in your debug log. Sidebar: You are using logging, aren’t you? If not, that’s covered in my aforementioned article, as well. Go read it!

The first array is all sidebars that are registered it looks something like so:

[16-Sep-2016 02:30:47 UTC] Array
(
    [wp_registered_sidebars] => Array
        (
...
            [sidebar-ourfocus] => Array
                (
                    [name] => Our focus section widgets
                    [id] => sidebar-ourfocus
                    [description] =>
                    [class] =>
                    [before_widget] =>
                    [after_widget] =>
                    [before_title] => <h2 class="widgettitle">
                    [after_title] => </h2>

                )
...

The second array is a list of registered widgets, which looks like so:

[wp_registered_widgets] => Array
        (
...
            [ctup-ads-widget-1] => Array
                (
                    [name] => Zerif - Our focus widget
                    [id] => ctup-ads-widget-1
                    [callback] => Array
                        (
                            [0] => zerif_ourfocus Object
                                (
                                    [id_base] => ctup-ads-widget
                                    [name] => Zerif - Our focus widget
                                    [widget_options] => Array
                                        (
                                            [classname] => widget_ctup-ads-widget
                                            [customize_selective_refresh] =>
                                        )

                                    [control_options] => Array
                                        (
                                            [id_base] => ctup-ads-widget
                                        )

                                    [number] => 4
                                    [id] => ctup-ads-widget-4
                                    [updated] =>
                                    [option_name] => widget_ctup-ads-widget
                                )

                            [1] => display_callback
                        )

                    [params] => Array
                        (
                            [0] => Array
                                (
                                    [number] => 1
                                )

                        )

                    [classname] => widget_ctup-ads-widget
                    [customize_selective_refresh] =>
                )
...

Now, just one more thing. We need to figure out exactly how these widgets are ordered within each sidebar. Well, luckily there’s a function for that; it’s called wp_get_sidebars_widgets(), and the output from this method on a default install is like so:

[16-Sep-2016 02:59:09 UTC] Array
(
    [wp_inactive_widgets] => Array
        (
        )

    [sidebar-1] => Array
        (
            [0] => search-2
            [1] => recent-posts-2
            [2] => recent-comments-2
            [3] => archives-2
            [4] => categories-2
            [5] => meta-2
        )

    [sidebar-aboutus] =>
    [zerif-sidebar-footer] =>
    [zerif-sidebar-footer-2] =>
    [zerif-sidebar-footer-3] =>
    [sidebar-ourfocus] => Array
        (
            [0] => ctup-ads-widget-1
            [1] => ctup-ads-widget-2
            [2] => ctup-ads-widget-3
            [3] => ctup-ads-widget-4
        )

    [sidebar-testimonials] => Array
        (
            [0] => zerif_testim-widget-1
            [1] => zerif_testim-widget-2
            [2] => zerif_testim-widget-3
        )

    [sidebar-ourteam] => Array
        (
            [0] => zerif_team-widget-1
            [1] => zerif_team-widget-2
            [2] => zerif_team-widget-3
            [3] => zerif_team-widget-4
        )

)

Okay, So Now What?

Now comes the fun!

We now know what all the data arrays look like, so we now have some context as to what dynamic_sidebar() is actually doing. Time to dive in!

Figuring out the type of data you’re expecting is probably the most important aspect to reverse engineering how something works. Keep in mind, we’re looking for all widgets in the sidebar-ourfocus dynamic sidebar location.

Digging deeper into the dynamic_sidebar() method, we can skip over a few checks and right down to the foreach loop it is running. We now see that it’s comparing registered widgets to the widget order array we pulled; if for some reason the widget is no longer registered, it just will not display:

        if ( !isset($wp_registered_widgets[$id]) ) continue;

By this point, we know the ID of the widgets under the “Our Focus” section are ‘ctup-ads-widget-X,’ where X is like an index (not to be confused with array keys). So, now we have the IDs, and know that the dynamic sidebar now renders the output of the widget. We have to dive into widgets and see just exactly how the widget data is saved.

Looking around the Zerif Lite theme, you’ll find the “Our Focus” was located in the main functions file under the class name of zerif_ourfocus, which extends the main WP_Widget class. Simple enough, but take note of the update method and its instance keys:

  • Text ( text )
  • Title ( title )
  • Link ( link )
  • Image ( image_uri )
  • Custom Media ID ( custom_media_id )

Now, at this point, I took a shortcut.

WordPress tutorials, WordPress how-to, WordPress education, learn WordPress, Zerif Lite theme, #WPdrama, WordPress drama, Zerif LIte banned, WordPress banned Zerif Lite, ThemeIsle banned Zerif Lite, migrate a widget to a custom post type, how to work with custom post types

From my history with WordPress, I know that widget options are stored in the options table, so again, putting two and two together, I figured I could run a query on the database to find exactly what the option key was. Knowing that widget names are used in the option names, here’s my query:

select * from wp_options where option_name like "%ctup%";

Which gave me this amazingly jumbled mess…but still, it’s serialized data, and still useful if you utilize a tool like Unserialize.com. If you didn’t know that existed, it’s super handy (and you can thank Brad Parbs for that little gem!).

Where did I get that ‘ctup’ in my SQL query? That’s part of the widget ID which you can see in the functions file. Granted, if there were more widgets which used a similar string, I’d have a harder time finding the options, but that’s not the case here.

Finally a Resolution…

So, what do we know so far?

  • We know how the IDs are associated across multiple arrays.
  • We also now know what our options look like for each individual widget.

“What’s left?” you ask. Well, the actual migration, of course. We need to get the data from point A to point B.

We first need to get the the list of widgets in our sidebar. We know the sidebar is labeled sidebar-ourfocus, so let’s grab that from the widgets array we previously created. We’re also going to go ahead and grab the options for our widget ID.

We also want to make sure we set up an option to check, to avoid migrating this stuff more than once. So, let’s create a simple migrate method, but don’t hook into it just yet.

    public function migrate() {

        if ( get_option( 'zl_has_imported', false ) ) {
            return;
        }

        $widgets        = wp_get_sidebars_widgets();
        $widget_set     = $widgets['sidebar-ourfocus'];
        $widget_options = get_option( 'widget_ctup-ads-widget' );

    }

Now possibly the simplest part of all, the loop to migrate the widgets to the CPT. First off here, we need to loop over all widgets in the sidebar-ourfocus array we just grabbed. Let’s look at the full loop, and I’ll explain:

        foreach ( $widget_set as $index => $widget ) {

            // Grab the ID of the widget
            $widget_array = explode( '-', $widget );

            /**
             * Now we grab the number ( key ) from the widget
             * So ctup-ads-widget-1 for example will give us just the number 1
             */
            $widget_key = end( $widget_array );

            /**
             * The above grabbed key is associated with the array keys in the
             * widget options, so we use that one here.
             */
            $widget_data = $widget_options[ $widget_key ];

            /**
             * Now that we have all our widget data
             * we build up the insertion arguments
             * for wp_insert_post()
             */
            $insert_args = array(
                'post_type'    => 'focus',
                'post_status'  => 'publish',
                'menu_order'   => $index,
                'post_title'   => $widget_data['title'],
                'post_content' => $widget_data['text'],
                'meta_input'   => array(
                    'link'      => $widget_data['link'],
                    'image_uri' => $widget_data['image_uri']
                ),
            );

            wp_insert_post( $insert_args );
        }

        update_option( 'zl_has_imported', true );

At first, we do a little trickery to grab the widget IDs, which correspond to the keys in the widget options data we grabbed earlier. There’s a nifty function in PHP to grab the end of an array, who would’ve guess it was called end()? This little gem sets the internal pointer of an array to the last element in the array, and returns it; a bit easier than other ways of grabbing last array items, I’d say.

Finally, the insertion arguments are pretty straightforward, dare I say. We’re storing the link and image_uri fields as custom post data. But notice the menu_order argument. This is because we want to retain the order in which the widgets were originally displayed.

Finally, after the loop, our posts should be imported; let’s update that option with true, so we don’t accidentally import the widgets again.

But, Wait! That’s an Invalid Post Type.

Yup, you are correct. Registering post types is the easiest thing to do, so I admittedly just copy and pasted from the codex, and changed a few things. Since we’re going to be here, we can also go ahead and hook into our migrate method.

Here’s your snippet for that, including the hooks method, which you obviously need:

    public function hooks() {
        // All hooks here.
        add_action( 'init', array( $this, 'migrate' ) );
        add_action( 'init', array( $this, 'register_post_type' ) );
    }

    public function register_post_type() {
        $labels = array(
            'name'               => _x( 'Focus', 'post type general name', 'your-plugin-textdomain' ),
            'singular_name'      => _x( 'Focus', 'post type singular name', 'your-plugin-textdomain' ),
            'menu_name'          => _x( 'Focus', 'admin menu', 'your-plugin-textdomain' ),
            'name_admin_bar'     => _x( 'Focus', 'add new on admin bar', 'your-plugin-textdomain' ),
            'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
            'add_new_item'       => __( 'Add New Focus', 'your-plugin-textdomain' ),
            'new_item'           => __( 'New Focus', 'your-plugin-textdomain' ),
            'edit_item'          => __( 'Edit Focus', 'your-plugin-textdomain' ),
            'view_item'          => __( 'View Focus', 'your-plugin-textdomain' ),
            'all_items'          => __( 'All Focus', 'your-plugin-textdomain' ),
            'search_items'       => __( 'Search Focus', 'your-plugin-textdomain' ),
            'parent_item_colon'  => __( 'Parent Focus:', 'your-plugin-textdomain' ),
            'not_found'          => __( 'No focus found.', 'your-plugin-textdomain' ),
            'not_found_in_trash' => __( 'No focus found in Trash.', 'your-plugin-textdomain' )
        );

        $args = array(
            'labels'             => $labels,
            'description'        => __( 'Description.', 'your-plugin-textdomain' ),
            'public'             => true,
            'publicly_queryable' => true,
            'show_ui'            => true,
            'show_in_menu'       => true,
            'query_var'          => true,
            'rewrite'            => array( 'slug' => 'focus' ),
            'capability_type'    => 'post',
            'has_archive'        => true,
            'hierarchical'       => true,
            'menu_position'      => null,
            'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments', 'page-attributes' )
        );

        register_post_type( 'focus', $args );
    }

Conclusion

Migrating widgets to a CPT (while a really weird request), can be done. This article was written as a proof of concept on how it can be handled. Now, admittedly, for migrations I use WP-CLI, and hardly ever do migrations on init. In fact, if you don’t know about WP-CLI already, you should really check it out. Overall, this was a quick and dirty example of how to handle a widget to CPT migration, purely because I like to solve puzzles, and I like showing you how to do the same.

Overall, I hope this was helpful and insightful into the beast that is WordPress. As a developer, there is always more than one way to do something, so take this article with a grain of salt and modify as you see fit.

Get the full source code for this plugin.

The post How to Migrate a Widget to a Custom Post Type appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2016/12/20/how-to-migrate-a-widget-to-custom-post-type/feed/ 0 13769
Level Up With jQuery Dimensions https://webdevstudios.com/2016/09/28/level-up-jquery-dimensions/ https://webdevstudios.com/2016/09/28/level-up-jquery-dimensions/#comments Wed, 28 Sep 2016 15:30:29 +0000 https://webdevstudios.com/?p=12873 It’s hard to believe that I’m well into my second year of being a front-end dev here at WDS. It has been an awesome experience and I’m truly blessed to work with such a great group of people. Halfway through 2015, I officially caught the bug known as Javascript and I started really trying to learn Read More Level Up With jQuery Dimensions

The post Level Up With jQuery Dimensions appeared first on WebDevStudios.

]]>
It’s hard to believe that I’m well into my second year of being a front-end dev here at WDS. It has been an awesome experience and I’m truly blessed to work with such a great group of people. Halfway through 2015, I officially caught the bug known as Javascript and I started really trying to learn the language. This inevitably also meant expanding my knowledge of jQuery.

As a quick aside, you might be asking, “jQuery in 2016? Really?” My answer to this is HECK yes. According to BuiltWith, 80% of the top 1 million websites use jQuery.

Learning Javascript is more of a marathon than a sprint.

It’s becoming more and more clear along the way there are concepts and techniques that will really go far in leveling my skill-set as a front-end developer. Two of these concepts are dimensions and offsets. For me, it’s not so much about implementing the code for these concepts but having an in-depth knowledge of their meaning.

It wasn’t until recently that I started experimenting with the real power of each concept. Use them in conjunction and you can do some pretty crazy DOM manipulation!

For this post, we will focus on dimensions and follow up with another post on offsets.

jQuery provides six functions that we can use to get the height and width of an element. Your first response might be why is there a need for six functions just to get the height and width of an element? The answer…the box model. Height and width can vary depending on if you are including padding, borders, and margins.

Let’s take a brief look at each function jQuery provides along with a quick explanation. Remember: Like other jQuery functions, these are both getters and setters. Passing in a value to the function makes them a setter.

Height

.height() – Will return the height of the content. In the image below, the content is the dark grey area.

.innerHeight() – Returns the height of the content + padding.

.outerHeight() – This will return the value of the content + padding + border.

.outerHeight( true ) – Returns the value of content + padding + border + margin.

height-c

Width

.width() – Returns the width of the content. The dark grey area in the image below.

.innerWidth() – Returns the width of the content + padding.

.outerWidth() – Returns the width of the content + padding + border.

.outerWidth( true ) – Returns the width of the content + padding + border + margin

width-c

How About a Use Case?

There have been many times when I’ve needed to transform a primary desktop menu into both a ‘tablet’ or ‘mobile’ menu depending on the width of the browser. You can make this happen seamlessly with a combination of CSS and jQuery. The approach is simple. Fire an event that will change the CSS appropriately and perform any other DOM manipulations when the browser size is above or below a certain breakpoint.

Here is a nifty little function that will do exactly what we need it to. (Thanks for Aubrey for this nice utility function.)

/**
 * Check if window width is equal or less than breakpoint
 * 
 * @param breakpoint Width to check against
 **/
function screenLessThan ( breakpoint ) {
    
    // Get the width of the current window
    var windowWidth = $( window ).width();

    // Return true/false if window with is equal or smaller than breakpoint
    // parseInt() is being used to ensure we are working with integers
    return ( parseInt( windowWidth ) <= parseInt( breakpoint ) );
}

We can leverage the function above to allow us to make certain changes based on the current size of the browser! In the gif below, we are making both the background color and text change based on breakpoints that the function above is checking against.

mobile tablet desktop

Checkout the CodePen below to view the full code. Also, feel free to let me know of ways this code could be optimized!

The Takeaway

Learning and understanding what each of these dimension functions do will level up your skill-set! I’d recommend taking a bit of time to play around with them by combining them with different events. Having familiarity with them is HUGE in my book.

The post Level Up With jQuery Dimensions appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2016/09/28/level-up-jquery-dimensions/feed/ 1 12873
My Local: Getting Started with Laravel Homestead https://webdevstudios.com/2016/09/13/getting-started-laravel-homestead/ https://webdevstudios.com/2016/09/13/getting-started-laravel-homestead/#comments Tue, 13 Sep 2016 17:08:40 +0000 https://webdevstudios.com/?p=13630 Developers have their own way of working, and I’m no exception. With a half a dozen apps running at any given time to make my code structure, workflow, and deployments as smooth as possible, I depend on simple easy-to-use tools to get things done. However, the one thing that is constantly changing is the local Read More My Local: Getting Started with Laravel Homestead

The post My Local: Getting Started with Laravel Homestead appeared first on WebDevStudios.

]]>
Developers have their own way of working, and I’m no exception. With a half a dozen apps running at any given time to make my code structure, workflow, and deployments as smooth as possible, I depend on simple easy-to-use tools to get things done. However, the one thing that is constantly changing is the local work environment. This is all based on preference, personal tastes, and your job. I build websites on WordPress with Laravel Homestead.

My local development environment for this is Laravel Homestead. Homestead is free and runs in VirtualBox (or VMware), on Vagrant and includes, Ubuntu 16.04, Git, PHP 7.0, HHVM, Nginx, MySQL, MariaDB, Sqlite3, Postgres, Composer, Node (With PM2, Bower, Grunt, and Gulp), Redis, Memcached and Beanstalkd.

Setup Homestead

To start, let’s install VirtualBox or VMWare AND Vagrant. I prefer VirtualBox because it’s lightweight, comes with Vagrant out of the box, and most importantly, it’s free.

$ cd ~/home/vagrant/Code/wordpress-site 

Next, we’re going to clone homestead into our root user directory and initialize Homestead to create our configuration file and define our provider–in my case, VirtualBox.

$ git clone https://github.com/laravel/homestead.git Homestead
$ bash init.sh

After you’re set up, we can setup our configuration file and local file structure. I’ll base this on how I work, but generally, how you organize your files are up to you.

Open your Terminal.app and type homestead edit which will open the homestead.yaml file in your favorite code editor.

---
ip: "192.168.15.15"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Dropbox/Private/Working
      to: /home/vagrant/Code

sites:
    - map: wordpress-site.dev
      to: /home/vagrant/Code/wordpress-site
      
databases:
    - wp_1

variables:
    - key: APP_ENV
      value: local

# blackfire:
#     - id: foo
#       token: bar
#       client-id: foo
#       client-token: bar

# ports:
#     - send: 93000
#       to: 9300
#     - send: 7777
#       to: 777
#       protocol: udp

I’m not going to go over everything here, just the parts that make Homestead go. They’ve added some bells and whistles like ports, variables and Blackfire support—which makes it easy to test PHP performance—but you can Google those.

From the top:

  • ip is automatically pulled in from your machine – leave this alone.
  • memory is set to 2048 by default.
  • authorize and keys reference your SSH keys. You can learn more about that here.
  • folders contains two parts map and to. map is the relative location on your computer, in my case ~/Dropbox/Private/Working. I like having a good 24/7 backup of working files, hence Dropbox. to refers to the default vagrant folder location. You can use the default location, I just find it easier and nicer to work out of the folders I want to work out of. Ya know control!
  • sites here’s where the fun starts. These are my local WordPress installs.
  • databases are the matching databases for each of your sites. Name them whatever you’d like.
  • variables, blackfire and ports don’t need to be touched, but you can read more about those here.

Next thing you’ll want to do is map your new site URL to your ip in your hosts file so that you can use your URL.

$ sudo vim /etc/hosts

 

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost

192.168.15.15   wordpress-site.dev

Save and you’re good to go.

Now, unlike MAMP (see below), one thing that Homestead doesn’t have is a visual phpMyAdmin interface—everything is command-line. However, here is where I recommend SequelPro for accessing, editing, and maintaining your Homestead databases. Access is super simple by using the configuration below:

Name: Homestead
Host: 127.0.0.1
Username: homestead
Password: secret
Database: (name optional)
Port: 33060

Homestead SequelPro Setup

From here, you can do anything you can do via ssh and command line with a simple GUI interface.

## Install WordPress
Easy as 1, 2, 3. I’ll do it with command-line, but you can just drag and drop files just the same.

$ cd ~/home/vagrant/Code/wordpress-site 
$ wp core download

? Boom–you’re ready to setup WordPress. Go to http://wordpress-site.dev (or whatever you’ve named your website) and follow the WordPress setup the way you normally would.

Note: If you’re building static sites, you can just drop files into your root and you’re ready to rock–no 1, 2, 3 needed.

Some Extras

Good for all databases:

Db Username: root
Db Password: secret

memory in the homestead.yaml files is set to 2048 by default, but I recommend 1024 to have a fast local machine without taking too many resources away from other tasks. On my Macbook Air 2011, I found that 2048 took too much away from other apps and slowed down my computer considerably if I was trying to use Adobe Photoshop or Chrome with ninety tabs side by side. 512 works just fine if you’re only running one or two sites.

Things I Learned Recently

I use Homestead for smaller projects, one-offs, and personal website tasks—it’s still much quicker for me than any other local environment setup.

Recently, however, I had to make a switch to MAMP for a project that was showing issues on my local environment. After all, Vagrant is notorious for being a tad buggy from time to time, so it made sense that the issue was caused locally. Despite resetting and spinning up a new local the problem persisted. Long story short the issue was in the code and not my local working environment, but by that time I’d made the switch to MAMP to ensure my local was the same as my coworkers.

Though I still swear by Homestead for simplicity and ease of use, I did notice a few things with MAMP to my surprise. MAMP v 4.0 upgrade was clean and easy to use. Most importantly, however, the CPU and memory load on my computer was almost half of what it was with Homestead running on Virtualbox. As a result, the little fans on my Macbook Air haven’t spun up once since I moved over to MAMP. I have a feeling that a more powerful computer might not have the same issues, but it was an interesting find considering my sordid past with MAMP 2.x.

The Alternatives

My colleagues tend to recommend MAMP Pro v 4.0 as a solid local work environment. Having played with it a little recently, I agree that it’s worth checking out. It is a paid program, and a solid platform with easy-to-use GUI features and easy to maintain databases. It provides everything you need to keep frameworks up to date and running smoothly.

Some friends of mine use Wamp Server, which is something akin to MAMP’s free option. Not as robust certainly, but it gets the job done.

ScotchBox is more or less like Homestead. It runs on Vagrant, and VirtualBox, but limits you to only one virtual machine or WordPress install at a time (unless you want to get into configuring Ubuntu). That doesn’t work for me, since I work on multiple web projects at once and often have to spin up a new one quickly. The actual setup and configuration is a bit more complicated than is necessary, so it requires some additional effort. If you’re into trying new things, it’s worth checking out, but after my own exploration, I determined it’s just not for me.

I’ve even known a dev or two to use services like DigitalOcean to spin up a quick WordPress install and go to town. This isn’t technically a local install as you’re running off of their servers, but it’s private and available anywhere from any computer with the right credentials. The downside to DigitalOcean can be its intense learning curve if you’re not familiar with backend server setups. These self-maintained droplets can quickly fly off the shelf if permissions get altered, or if security precautions aren’t properly executed.

If you’re looking for a local dev environment that, after setup, is super quick to spin up and maintain, my vote is Homestead. What’s your favorite local setup?

The post My Local: Getting Started with Laravel Homestead appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2016/09/13/getting-started-laravel-homestead/feed/ 3 13630
The Six Questions Developers Need to Ask Before Turning in Tasks https://webdevstudios.com/2016/09/01/six-questions-developers-need-to-ask/ https://webdevstudios.com/2016/09/01/six-questions-developers-need-to-ask/#respond Thu, 01 Sep 2016 17:05:30 +0000 https://webdevstudios.com/?p=13578 Everyday I spend time working on products for our great clients, I specifically spend a great deal of it writing code and building features. But I’m not just creating new features, I’m also creating new opportunities…opportunities to break that product. Here are the questions developers need to ask before turning in their tasks, and how they’re going to help Read More The Six Questions Developers Need to Ask Before Turning in Tasks

The post The Six Questions Developers Need to Ask Before Turning in Tasks appeared first on WebDevStudios.

]]>
Everyday I spend time working on products for our great clients, I specifically spend a great deal of it writing code and building features. But I’m not just creating new features, I’m also creating new opportunities…opportunities to break that product. Here are the questions developers need to ask before turning in their tasks, and how they’re going to help you code smarter.

  1. How can I break this?
  2. Where’s Murphy hiding?
  3. Who do I trust?
  4. What’s dangerous?
  5. What are the real limits?
  6. Who is this for?

For example, what could go wrong with this example?

<?php _e( 'What could go wrong here?' ); ?>

Well, it turns out, a lot.

Developers, ask yourself these six questions before turning in any task

Have you ever tried breaking this by adding malicious scripts in language file? Turns out an innocent function, like this, opens a huge opportunity for people to break things. This was my own revelation a few weeks ago, and it dawned on me that I do not spend enough time trying to break things and learning the skills I need to detect these hidden opportunities in my code. The first step was simply realizing that with every new feature, comes new opportunities, but the following are a few steps I’ve been taking before I complete and turn in any new feature.

How can I break this? (Go break it)

A man hackingDuring the drudge of daily tasks and code commits, we often can overlook the need to go in and actually break things we build. The definition of hacking isn’t necessarily malicious; it’s simply taking something and re-purposing it for a different reward. MacGyver was famous for this kind of hacking! That said, hacking is commonly used to break things, and that’s what we’re looking to fix, which is why we should try to break our own stuff.

It takes more than just trusting functions and methods to get the job done. You have to actually get in there and try and break what it is you just made. I feel we aren’t encouraged enough to go in there (and especially spend the time) and be a hacker. But I call all developers out! Become a hacker daily! Break your stuff! In doing so, you are going to build better products, serve your clients better, increase the reliability of your company, and, ultimately, become a better developer.

I also encourage CEOs, business owners, leads, and project managers to change the rhetoric behind security to go beyond just coding, but making the actual act of hacking your own solutions a part of the development process. Tell your developers to ask themselves, before turning in a task or pull request, “How can I break this?” And give developers permission to take the time to become a hacker.

Where’s Murphy hiding?

Anything that can go wrong, will go wrong. – Murphy’s Law

So we’re trying to hack our new feature, and we find a way that a user can pass a combination of query arguments, and somehow, logged in as a subscriber, could possibly run a server-intensive script we just built over and over. I feel (admittedly, through my own experience) we tell ourselves too much that they would never figure out how to do that, and we move on. But someone will!

I’ve just created a problem that will happen in the future. Thinking of these findings as problems that will undoubtedly happen, no matter how unlikely we think it is, will help us keep the internet and clients safe. It allows us to strategize.

Who do I trust?

Developers can be too trusting, and we shouldn’t be. Never trust anyone.

<?php _e( 'What could go wrong here?' ); ?>

In our example here, we might admit that the only one who could really cause a problem are the people who translate. Maybe they’re our own people, maybe they’re strangers, or maybe they’re future translators that a client hired six months down the road that know nothing about WordPress. Whoever it is, I say, they automatically get the “I don’t trust you” stamp of non-approval. It’s strange, but developers have to live in a very untrustworthy world, and we’re better developers for it! Having an skeptical approach will lead you to creating more secure code and features. Take your paranoia and make something rock solid.

What’s dangerous?

Skull and bones poison

In the spirit of Murphy’s Law and trusting no one, you have to see information itself as a potential transmitters for viruses, illnesses, and things that cause bad things to happen and blow up the Internet. Data and information are dangerous! By shifting your view of information to something dangerous, and hiding some disease inside, we can be better devs.

An example.

$image = get_the_post_thumbnail();
echo $image;

In this example, we might view $image as completely innocent and trustworthy.

But it’s not.

Did you know that get_the_post_thumbnail() has a filter? Yeah, it’s post_thumbnail_html and anyone can filter the output and push out a harmful script! $image is dangerous; variables are dangerous! How do you know someone with server access didn’t inject a Must-Use plugin that filters that output?

If we put on our Hat Of Mistrust, we’ll be aware that leaving that variable alone is risky, and take action:

$image = get_the_post_thumbnail();
echo wp_kses_post( $image );

This should allow img tags that are allowed in the WordPress post editor, and if anyone tries to inject a harmful script, it won’t let them. We need to start seeing information as potentially dangerous, and ask ourselves if it is, because we don’t know all the filters or ways people can turn information against us. Using critical thinking and strategy in the ways we work helps us stay one step ahead of people who either don’t know or possess malintent.

If we were really paranoid, we might write something like:

$image = get_the_post_thumbnail();
echo ( is_string( $image ) && stristr( $image, '<img' ) ) ? wp_kses_post( $image ) : '';

What are the real limits?

Another question I think developers rarely ask themselves are, “What are the real limits?”

Really thinking about this question can produce interesting answers.

For instance, what is the limit of get_posts? At first, you might think, well -1 (I did). Set that posts_per_page to -1 and we’ll get all the things, yeah baby! But, a smarter developer might find that…

  • The server’s execution time is a limit
  • The server’s memory is a limit
  • 15, the limit is 15; there will always be 15

We should be thinking about real limits, not just limits in code, and what happens when these limits are reached. Like the server’s execution time or memory limits resulting in a 503. Or, getting fifteen posts–no harm there, right? Have you ever asked yourself how many posts_per_page actually result in a timeout or a 503 on your server? It’s a good question.

Our job as developers is to eliminate the harmful effects of reaching real limits and we need to be aware of what these limits are and make sure we’re not breaking them.

Who is this for?

Zoolander, what is this a center for ants?The last question I pose developers to ask is,

“Who is this for?”

I think every feature should have a name associated with it. Is it all administrators, or all authors? Is it just Jane or Joe? Is it the United States? Are they English speakers or Spanish speakers? Who are these people!?

Knowing (or even guessing at) who will be using our features, by giving our features ownership, helps make sure we’re prepared to create features with privilege in mind.

Even if your answer is “everyone,” we probably should be looking hard at the detailed, real time answers. For instance, “everyone” includes many languages; how many Spanish speakers need to use your product? Do you have a plan to have your content translated? What about A11y? That includes everyone too! Thinking of your features as privileged and belonging to someone helps us take more responsibility with our features, who has access, and who shouldn’t. This also allows you expand your reach and make sure that people who might otherwise be excluded in a generic “everyone” can access what you made.

What about you?

Do you have any tactics that help you build more secure features? What are some ways you work secure features into your build?

The post The Six Questions Developers Need to Ask Before Turning in Tasks appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2016/09/01/six-questions-developers-need-to-ask/feed/ 0 13578
Winning With Code Reviews https://webdevstudios.com/2016/08/25/winning-code-reviews/ https://webdevstudios.com/2016/08/25/winning-code-reviews/#respond Thu, 25 Aug 2016 17:36:34 +0000 https://webdevstudios.com/?p=13339 Here at WebDevStudios we put a lot of emphasis on code quality. After handing off a product to a client, we never know who may be looking at and/or maintaining our code. We want to be proud and confident that the next person will not have an OMGWTFBBQ-head-smashing-into-keyboard moment, but one of delightful surprise. How Read More Winning With Code Reviews

The post Winning With Code Reviews appeared first on WebDevStudios.

]]>
Here at WebDevStudios we put a lot of emphasis on code quality. After handing off a product to a client, we never know who may be looking at and/or maintaining our code. We want to be proud and confident that the next person will not have an OMGWTFBBQ-head-smashing-into-keyboard moment, but one of delightful surprise.

How do we consistently create and maintain a high level of quality code? Through peer code reviews.

All developers at WebDevStudios are encouraged to request code reviews and to provide their own feedback to others on their code review requests.

Peer code reviews have enhanced the code quality at WebDevStudios by leaps and bounds. Now instead of coding in a hole, all the developers are actively striving to write good, clean code that will pass a code review the first time. Instead of feedback coming in the form of correction from a (busy) lead it has become a game amongst the developers to see who can write the most elegant and bug free code the first time out the gate. As a result, the coding standards and practices at WebDevStudios have grown and enhanced.

This all sounds good, but how does it work in practice?

When we receive a new project, it goes through an architecting phase that identifies all the key elements that will be required. These elements are then further broken down into their respective features. We utilize the Git code versioning system and its branching model to create a unique branch per feature, which we have detailed in a previous post titled An Alternative Git Flow for Client Work.

After a developer has finished a feature and before merging it back into the main branch, a code review is requested. Doing the code review at this step allows the reviewer to see all of the changes made on the feature branch compared to the main branch quite easily. The reviewer can then switch between branches to verify the feature code works and, if so desired, merge the feature into other branches to review against.

Reviews may be done by more than one other developer and have sometimes spurred incredible conversation and debate on the merits of performing an operation this way versus that way.

Code reviews promote healthy culture

As developers we are very proud of our code. Code is our form of art–where we express our inner Rembrandt. As such, critique of our artistry can be a stinging blow to our egos. I have seen instances where developers have nearly come to (virtual) blows when one suggests a change to the other’s code. Creating a healthy culture for code reviews counters any negative feelings that may arise.

We are all on the same team and we all have the same goal: To deliver the highest quality product to the client. When I was young my mother used to tell me, “If you do not have anything nice to say do not say anything at all.” We have applied the same motto to our code reviews. Feedback is never negative, but always constructive. By using positive language and helpfully showing each other new tricks and techniques, the skills of WDS devs have increased across the board and we have grown closer as a team.

Code reviews enhance security

Let’s admit it: All of us have written some code with a vulnerability issue. The most common of which is SQL injection points through unsanitized input. While coding, it is easy to become wrapped up in getting the feature done and lose sight of all the security implications of what you are writing. Having another set of eyes review the code can help to identify weaknesses.

This is further backed up by looking at a few of the major exploits that have been found in the WordPress ecosystem this year alone. Many of them were not found by probing the application, but by looking at the released source code and finding some place allowing unsecured input.

Code reviews increase social recognition and a feeling of self-worth

This may sound strange but there is powerful psychology behind code reviews. Providing code reviews causes us to feel good about helping out another, and receiving a code review that does not indicate anything needs to be updated in your code becomes almost a drug unto itself. Developers tend to amp up their game to “beat” the reviewers. Even us lead developers have our code reviewed, and I can tell you that nothing excites the team more than poking holes in code of the “best” developers on the team. (…Yeah, I had a code review only critiquing my use of white space…).

aziz ansari gif, code reviews, the importance of code reviews, why do code reviews, what is a code review, should lead developers do code reviews, how to do a code review, what's the point of a code review

Is it really worth the extra time?

When working on client projects time is of the essence, so we had to ask ourselves, “Is this worth the extra time it will take to develop a feature?”

The resounding answer is YES!

The increase in code quality and skills of the developers alone makes code reviews worth it, and the added benefit is finding bugs to be squashed well before being introduced in production.

According to a 2002 report by the National Institute of Standards and Technology a bug found post-production takes 18.7 hours to find and fix while a bug found during a code review takes just 3.2 hours to fix! That is 15.5 hours saved! What “extra time” are you worried about!?

Go forth and review thine code

As you can see, the idea behind code reviews is a simple one but it has BIG benefits. I want to encourage you to begin integrating code reviews into your workflow.

You may not have a team like we do here at WebDevStudios, but if you are reading this, you are part of the team of the community. WebDevStudios is just one fish in this pond that we call WordPress. Together, we are all striving to enhance this product that we use and love. Now get out there and start doing those code reviews!

I would love to hear about your experiences with code reviews in the comments and how your company or organization has implemented them.

The post Winning With Code Reviews appeared first on WebDevStudios.

]]>
https://webdevstudios.com/2016/08/25/winning-code-reviews/feed/ 0 13339