Software developer survival skills

To have a career as a developer, you need to have some important basic skill sets. All (new) technologies are built on top or around some commonly used technologies. People always say, “WOW, this technology is really hot now, you should learn it!”. Yes, but to even know the basics, it will take years to learn the pre-requisites.

Take a modern framework – Symfony for example, to know the framework well, you will need to know HTTP protocols, MVC, Object oriented methodologies, HTML, CSS, Javascript, Forms, Database Relationships, PHP, Version control, Basic Linux…etc.

Technologies evolved so fast that most University curriculum could not catch up. Most of the time. people spend years learning something that you only use 1% in your real job. That is why practical training is so important.

If you are looking to become a developer, learn these skills and you can branch off to anywhere:

1. Git and Git flow
2. HTML, CSS
3. Javascript
4. MVC and Object Oriented thinking
5. Basic system administration (bash scripting)

The last most important skill is personality. Be a human and don’t be a robot.

You will need these skills irregardless whether you want to be a front or backend developer majoring in any framework like rails, angularjs, nodejs, laravel, django, symfony…etc.

Why Symfony?

Choosing the best framework for rapid development has been a topic that has been debated to death. Today, there is no longer “the best framework” because all modern day framework is scalable and robust, they learn from each other. They are all adapting very fast to new techniques of doing things.

At the time of writing, nodejs and rails continue to innovate with php chasing fast behind. They have all very similar development methodology, so knowing one framework well means you can jump between other modern day frameworks easily.

For php, its Laravel and Symfony. if you want to invest your time, I recommend symfony because it is more stable when compared to the rest. Symfony components have been used by many projects including Drupal and Laravel.

as for Django and Rails, I am leaning more towards rails.

Symfony 2 is a mature framework. A mature framework means information and libraries don’t get outdated quickly. Some framework moves so fast that the 3rd party libraries couldn’t catch up. Rails early days suffered from this. Nothing worked out of the box because googled information was often outdated. Choose a stable framework so that you don’t spend lots of time setting up the right environment and troubleshooting the libraries for example. You should be spending more productive time learning the software.

Symfony2: Installation

The official installation doc is http://symfony.com/doc/current/book/installation.html.

As a best practice, don’t install symfony in MAC or Windows, install in Linux and use Linux for development because you will be using Linux for hosting.

For consistency in development, develop in virtual machine. The spec of the virtual machine should be the same as the production server. The best way to do it is to use vagrant.

In this example, we will create a ficticious project called SongBird. First of all, we need to create a portable and consistent development environment so that we speak the same language. This is also important if you decide to outsource the development in the future. Next we need a tool like puppet to configure automate software configuration.

To get started, let’s get this symfony repo –¬†https://github.com/bernardpeh/songbird

git clone https://github.com/bernardpeh/songbird
vagrant up

This will take a long time… most of the alerts you see in the screen is harmless. this is a once off setup. Enter root password when prompted.

According to the doc, you can choose a number of ways to install symfony, most people chose the composer method. Don’t use composer or manually download, install the symfony command line instead.

vagrant ssh
# you are now in the virtual machine
sudo curl -LsS http://symfony.com/installer -o /usr/local/bin/symfony
sudo chmod a+x /usr/local/bin/symfony

To create a new project call “songbird” using the long term support version,

cd /vagrant
symfony new songbird lts
cd songbird
sed "s/'127.0.0.1'/'127.0.0.1','33.33.33.1'/g" -i web/app_dev.php
# check that all requirements met
php app/check.php
# you should see that the config has passed

In your parent host, we need to add get songbird.dev to be pointing to the vm. add this to your host file.

33.33.33.100 songbird.dev www.songbird.dev

In your parent, Test your site by going to http://songbird.dev/app_dev.php/app/example

If you see the word “Homepage”, everything is good.

Now let us commit everything before we proceed.

git init .
git add .
git commit -m"init commit"

When is hardcoding good?

Hardcoding is always seen as a bad practice. It makes the code inflexible. For example, making the code aware of the environment itself is a good thing so that we can reuse the code and avoid code duplication. Here, we are trying to copy a file to a user directory.

cp doc.txt to $HOME/

is better than

cp doc.txt to alex/

If this snippet is used in a deployment script for example, it can save a lot of time.

However if this snippet is used in a live environment, using variables might not be good because it can cause unpredictable behaviour and makes troubleshooting harder. Hence, hardcoding in production environment becomes a good thing.

Speeding up vagrant virtualbox disk access

Virtualbox driver is very slow. You can google about this all over the internet.

There are 2 ways to speed up vagrant disk access using nfs, one way is to use vagrant-bindfs plugin and another way is the traditional way to change permissions in vm. This method outlines the later.

shutdown vagrant using “vagrant halt”
In puphpet folder, update config.yaml
synced_type: nfs
then “vagrant up”
If you are seeing mount nfs error, check your /etc/hosts file. make sure 127.0.0.1 points to localhost

sudo -s, CHANGE THE ROOT PASSWD first so that you can log in again if things break.
then
change the permission for the /var/www (vagrant folder) so that they are the user_id and grp_id of the user in mac, for example,
IN your mac,
the user id is 502 and group id in 20
IN your vm,
vagrant id is 1000 and www-data id is 33
edit etc/passwd and /etc/group and change the id of 1000 to 502 and /etc/group so that the id of www-data is 20
change the own dir to that permission as well, ie /var/www and their files.
change the session dir, ie /var/lib/php/session
exit and do a “vagrant halt” and “vagrant up” again to test.

Disable postfix to send email to outside world

disabling postfix to send email to outside world is important especially in development environment. you don’t want client to receive emails when you are testing in the dev environment. Unless software is using external smtp server to send email, you can simply update postfix config (main.cf)

relayhost = 127.0.0.1

and restart postfix

Custom ajax call in woocommerce

sometimes you need to update database via ajax. wordpress has tools to make it easy. Well not that easy…

here for example, we want to create a link that when clicked, automatically change the order status of a woocommerce order and insert some notes.

In the template,

<script>
function installer_action(id,istatus) {
	jQuery.ajax({
	   type: "post",
	   url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
	   data: "action=update_order_installer_status&nonce=<?php echo wp_create_nonce('nonce_update_order_installer_status'); ?>&id="+id+"&status="+istatus,  
	   success: function(data){
	   	console.log(data);
	   		jQuery('#order_status_'+id).html(data.status);
	   		jQuery('#installer_actions_'+id).html(data.note);
	   },
	   error: function(xhr, textStatus, errorThrown) {
	     // console.log(xhr.responseText);
	   }
	});
}
</script>

Note that we have to use nonce to prevent csrf. Now we need the html for the link:

<span id="installer_actions_<?php echo $post->ID; ?>">
  <?php
    echo "<a href=\"#\" onclick=\"installer_action('$post->ID','accepted')\">Accept Request</a> | <a href=\"#\" onclick=\"installer_action('$post->ID', 'rejected')\">Reject Request</a>";
  ?>
</span>

The content in the span will be replaced by the ajax.

then in your functions.php, you have a function that deals with the ajax call and return some json. For eg.

function update_order_installer_status() {
  check_ajax_referer( 'nonce_update_order_installer_status', 'nonce' );
  // we are safe now
  $order = new WC_Order($_POST['id']);
  $new_order_status = ($_POST['status'] == 'accepted') ? 'install-accepted' : 'install-rejected' ;
  $note = "Installer ".$_POST['status']." job on ".date('j F Y, g:i a');
  $order->update_status($new_order_status);
  $order->add_order_note($note, 1);

  $notes = $order->get_customer_order_notes();
  $order->note = $notes[0]->comment_content;
  $order->status = wc_get_order_status_name($order->get_status());
  wp_send_json($order);
}

add_action( 'wp_ajax_update_order_installer_status', 'update_order_installer_status' );
add_action( 'wp_ajax_nopriv_update_order_installer_status', 'update_order_installer_status' );

Creating custom pages in woocommerce

what if you want to have a custom page in woocommerce? For example a page called abc under my-account

best way is to use shortcodes. Create a new page under my-account, ie my-account/abc and put in the shortcode [abc_shortcode]

then in functions.php

function abc_function( $atts ){
	wc_get_template( 'myaccount/abc.php' );
}
add_shortcode( 'abc_shortcode', 'abc_function' );

now you need to create the abc.php file which can contain anything

Symfony: Quick way to change bundle name

You have generated a new bundle under src/Oldnamespace/oldbundle and decided to change the bundle name or move it to a new name space. Symfony doesn’t provide any tools to do that. Sounds like a tedious job…

There is no short cut to this solution but some Bash scripting can save your lots of time. Use it at your own risk. Mass replace could replace stuff that you dont want though..

# in the bundle folder
find . -type f | while read s; do sed -i 's/Oldnamespace\OldBundle/Newnamespace\NewBundle/g' $s ; done
find . -type f | while read s; do sed -i 's/OldnamespaceOldBundle/NewnamespaceNewBundle/g' $s ; done
find . -type f | while read s; do sed -i 's/OldnamespaceOldBundle/NewnamespaceNewBundle/g' $s ; done
# now renaming dir and files
find . | grep Article | xargs rename Article Page -

Once done, change the bundle folder name and configuration in app/AppKernel.php, app/config/routing.yml, app/config/config.yml