Blog

How to Automate Your Job Search

This is a quick post on how I get freelance jobs.

Setting up Email Alerts on If This Then That (ifttt). Many job sites have RSS feeds e.g. Craigslist, job aggregator, indeed.com, simplehired.com.

Most of my jobs are from Upwork, 1-3 jobs a month, I have 2 contracts that are above 75/hr. I probably make less than $1000 per month from Upwork.
Guru.com – rare but I do go through them once a week or when my leads dry up. These jobs vary from $100 – $500. Probably 1 job every 3 months.
Reddit – subreddit:forhire, I have set up IFTTT for these. I am surprised that there quite a number of leads coming through here but so far my rates are too high for them.
My Products and Website – I get referrals for the product I had on Codecanyon. I got a few job these way.
Offline Referrals – From ex-colleagues, I got a 5 figure deal and retainer from this source.
local recruiting sites – mostly sub-contract work from other agency. The paid is equivalent to a full-time job but it only last 1 or 2 months.
Other online job boards – I set up an automated notification for all the job boards and twitter. There are a lot of jobs here but I have not been able to get any.
Cold email – No success.
As a freelancer, you need to constantly work on your lead source and exploring a new lead source. I probably spent more time looking for jobs than actually working on them so creativity and automation are key.

Custom Woocommerce email using woocommerce_email_actions hook

Most of my plugins are Woocommerce based, and many use the Woocommerce Class WC_EMAIL to sent out emails. Recently I started getting complaints about emails not being sent. After some troubleshooting, I found that adding the email trigger action was not getting added to the active array. I google around and found a new hook that I can use a filter woocommerce_email_actions. Simple replace
add_filter( 'woocommerce_init', array( $this, 'my_email_actions' ) );
public function my_email_actions() {
add_action( 'class_my_email_send', array( 'WC_Emails', 'send_transactional_email' ), 10, 1 );
}

with
add_filter( 'woocommerce_email_actions', array( $this, 'my_email_actions' ) );

public function my_email_actions() {
$email_actions[] = 'class_my_email_send';
return $email_actions;
}

Updating WordPress Plugin Updating Tested up to Tag

Sometimes we just need to test and update the Tested up to WordPress version tag fro our plugins in the open repositories.

This can be done using SVN directly.

1. Check out the existing version.
svn co https://plugins.svn.wordpress.org/future-draft/

2. Update the tag in README.txt

3. Commit
svn ci -m 'update to WordPress version 4.8.2'

Done!

MySQL commands for replace domains and server paths

Useful MySQL commands for replacing domain URL and file path.

UPDATE wp_options SET option_value = replace(option_value, 'http://www.awesome.org','http://www.awesome.dev/cwsa.org');
UPDATE wp_postmeta SET meta_value = replace(meta_value,'http://www.awesome.org','http://www.awesome.dev/cwsa.org');
UPDATE wp_posts SET post_content = replace(post_content, 'http://www.awesome.org', 'http://www.awesome.dev/cwsa.org'), guid = replace(guid, 'http://www.awesome.org','http://www.awesome.dev/cwsa.org');


UPDATE wp_options SET option_value = replace(option_value, '/public_html/awesome','/var/www/awesome');
UPDATE wp_postmeta SET meta_value = replace(meta_value,'/public_html/awesome','/var/www/awesome');
UPDATE wp_posts SET post_content = replace(post_content, '/public_html/awesome','/var/www/awesome'), guid = replace(guid, '/public_html/awesome','/var/www/awesome');

WP-CLI Guide: Install WordPress via SSH

WP-CLI is a very useful utility if you have the luxury of getting a server that comes with it plus ssh. This is very useful for those who need to constantly launch new WordPress sites.

Create a new directory then execute
wp core download

if you get an error "Error: WordPress files seem to already be present here." Add the force flag.
wp core download --path=.

Downloading WordPress 4.8.1 (en_US)...
md5 hash verified: f3dd0e033519aa363eb07e13c6676e3c
Success: WordPress downloaded.

Now configure your config file
wp core config --dbhost=localhost --dbname=forum --dbuser=wordpress --dbpass=wordpress --path=.
Again here –path=. for those who have wordpress install in the root directory.

Success: Generated 'wp-config.php' file.

Install WordPress
wp core install --url=example.com --title=Example --admin_user=supervisor --admin_password=strongpassword --admin_email=info@example.com --path=.
Error: Can’t select database. We were able to connect to the database server (which means your username and password is okay) but not able to select the `forum` database.

Database ‘forum’ is missing. You need to create the database in MySQL.

After creating the database run the command again.

Success: WordPress installed successfully.

Done!

Automated Multiple WordPress Version Setup

Automated WordPress Setup
Automated WordPress Setup

For plugin development, you need to maintain a number of WordPress versions for testing. I need to at least install 5 version of WordPress if I start with 4.7.
The setup of a normal setup is:
1. Create database, user and password
2. Download WordPress, unzip, move to expanded folder
3. Copy and rename wp-config-sample.php to wp-config.php and add-in the credentials
4. WordPress core is updated automatically, you need to remove auto update feature by adding a line in wp-config.php

The Problem
Repeating the task everything you need a clean testing environment can be tedious.

Of course, there is WP-CLI the command line interface for WordPress but many web-hosts do not have WP-CLI installed, sometimes they have a strip down version, others they simply don’t work. If your host is provided with ssh, we could write a script for these, if not a good option will be to create all the files and then send it up by FTP.

The Solutions
For now, we will work with SSH. The solution will consist of 2 parts, a script to install the files and setup the database and another to open up the browser and complete the setups.

Part 1: The Server Script
We need a script that can be executed on the server that will download WordPress version 4.7.1 – 4.8. Since the archive version URL naming is quite standard
https://wordpress.org/wordpress-4.7.1.tar.gz
https://wordpress.org/wordpress-4.7.2.tar.gz
https://wordpress.org/wordpress-4.7.3.tar.gz
https://wordpress.org/wordpress-4.7.4.tar.gz
https://wordpress.org/wordpress-4.7.5.tar.gz
https://wordpress.org/wordpress-4.8.tar.gz

We can easily use a bash script to loop through and grab them with wget or curl.

#!/bin/bash
arr=( "4.8" "4.7.5" "4.7.4" "4.7.3" "4.7.2" "4.7.1" )
## now loop through the above array
for i in "${arr[@]}"
do
curl -O https://wordpress.org/wordpress-$i.tar.gz
done

To complete the code, we need to unzip, rename the folder, add and insert our credentials to the wp-config.php
I modified a code by bgallagh3r.

We still need to add the code for creating the database. Since most web-host do not allow the use of root for MySQL, you need a user id that has the privilege of creating databases. If not, you can only create it manually through your web interface.

function createdatabase () {
MAINDB=$1
ROOTPASSWD=$3
mysql -u$2 -p${ROOTPASSWD} -e "CREATE DATABASE IF NOT EXISTS ${MAINDB} /*\!40100 DEFAULT CHARACTER SET utf8 */;"
}

During my research phase I came across some solution that generates different username and password for each site, but I prefer to keep it simple with just one username and password for all sites. I anticipate that these sites will be torn down once the testing is done.

Part 2: The Client-Side Script
We need a script to open up the browser and input, select and click through the steps. I choose Python and selenium. You can find out more here

First, download Python bindings for Selenium.
sudo pip install selenium

We need ChromeDriver that can be download here and read the ChromeDrive documentation here

from selenium import webdriver
driver = webdriver.Chrome('/path/to/chromedriver') # Optional argument, if not specified will search path.
driver.get('http://www.google.com/xhtml');

Test and make sure that the path to ChromeDrive is correct and Selenium is installed correctly. This should launch google on a new browser window.
Now let’s work on our script.

Automated WordPress Setup Part 2
Automated WordPress Setup Part 2

Now let see how the whole thing runs on the client side.

See how easy it is to automate everything with a few lines of code.

A tool to convert PSD to PNG

There is a Command-line (Terminal) tool from Telegraphics called PSDParse that parse Photoshop PSD format files and dump layers to PNG files.

psd2png.exe -w Filename.psd

usage: psd2png.exe [options] psdfile…
-h, –help show this help
-v, –verbose print more information
-q, –quiet work silently
-w, –writepng write PNG files of each raster layer (and merged composite)
-d, –pngdir dir put PNGs in directory (implies –writepng)
-m, –makedirs create subdirectory for PNG if layer name contains \’s
-l, –list write an ‘asset list’ of layer sizes and positions
-s, –split write each composite channel to individual (grey scale) PNG

Plugin for a productized service

If you are looking to launched a productized service like wpcurve.com. There are currently no plugins that support this fully.

I am cobbler together a few plugin and duct tape one for proof of concept.

The Required Plugins:
Responsive Pricing Table
WP Full Stripe Free
Contact Form 7

The Main Setup
First Setup your 3 tier offer using Responsive Pricing Table

Create all the payment type in WP Full Stripe Free.

In each payment type create a Thank You page with in contact from 7. Here you collect all the necessary information from your customer e.g. email address, web URL.

The duct tape Part
Under the 3-tier offer that you have setup in Responsive Pricing Table. On each button link, link to the payment type you have created.

On the payment form that you created in WP Full Stripe Free, add the page under “Redirect to” select the correct thank you  page.

Basically we are just creating 1 offer, 1 payment and 1 contact from for each tier that we offer.

Missing?

First recurring payment is not setup, this can be easily fix by upgrading  WP Full Stripe Free to Pro, which include recurring payment. However, I would like to allow clients to create an account, purchase a subscription, change subscription type of cancel subscription. How about support/ job tickets tracking, allow clients to upload files such as backups. Ideally I could create reports and send notifications for clients, admin and maybe staffs.

Would you be interested in a plugin that have all these features?

Deleting Woocommerce products using Mysql commands

mysql> DELETE relations.*, taxes.*, terms.*
-> FROM wp_term_relationships AS relations
-> INNER JOIN wp_term_taxonomy AS taxes
-> ON relations.term_taxonomy_id=taxes.term_taxonomy_id
-> INNER JOIN wp_terms AS terms
-> ON taxes.term_id=terms.term_id
-> WHERE object_id IN (SELECT ID FROM wp_posts WHERE post_type='product');
Query OK, 497631 rows affected (4 min 10.74 sec)

mysql>
mysql> DELETE FROM wp_postmeta WHERE post_id IN (SELECT ID FROM wp_posts WHERE post_type = 'product');

Query OK, 1419875 rows affected (13 min 16.68 sec)

mysql> DELETE FROM wp_posts WHERE post_type = 'product';
Query OK, 66618 rows affected (51.91 sec)

Very useful commands especially when you need to purge large amount of products.

Repair WordPress Table

Recently, one of my WordPress table failed.

WordPress database error Table 'wp_postmeta' is marked as crashed and last (automatic?) repair failed for query

After failing to have it repair by WordPress script, I turn to Mysql command and it worked.

repair table wp_postmeta;