#!/bin/bash
# --debug 2>&1
export PATH=/usr/local/bin:$PATH;
function auth_action {
cd $CURRENT_DIR || error 'Unable to switch directory.'
TOKEN=$(wp transient get staging_auth_token --path=$CURRENT_DIR)
if [ "$1" != "$TOKEN" ] || [ -z "$TOKEN" ]
then
wp transient delete staging_auth_token --path=$CURRENT_DIR
error 'Unable to authenticate the action.'
fi
wp transient delete staging_auth_token --path=$CURRENT_DIR
}
function create {
cd $PRODUCTION_DIR || error 'Unable to move to production directory.'
WP_VER=$(wp core version)
mkdir -p $STAGING_DIR || error 'Unable to create staging directory.'
wp db export $STAGING_DIR/.export-sql --add-drop-table --skip-themes --skip-plugins --tables=$PRODUCTION_TABLES || error 'Unable to export database.'
wp option update staging_environment production || error 'Unable to set environment.'
cd $STAGING_DIR || error 'Unable to move to staging directory.'
echo 'wp-config.php' > .gitignore
echo '.gitignore' >> .gitignore
git init || error 'Unable to initialize git.'
move_files $PRODUCTION_DIR $STAGING_DIR
wp core download --version=$WP_VER --force || error 'Unable to install WordPress in staging directory.'
wp core config --dbname=$DB --dbuser=$DB_USER --dbpass=$DB_PASS --dbprefix=staging_$DB_PREFIX --skip-themes --skip-plugins || error 'Unable to configure WordPress.'
git config --global user.email "staging@domain.com"
git config --global user.name "Endurance Staging"
sed -i -e "s/$DB_PREFIX/staging_$DB_PREFIX/g" $STAGING_DIR/.export-sql || error 'Unable to update prefix.'
wp db import $STAGING_DIR/.export-sql --skip-themes --skip-plugins || error 'Unable to import database.'
save_state 'Create Staging Environment'
rm $STAGING_DIR/.export-sql --force
wp option update staging_environment staging || error 'Unable to set environment.'
wp search-replace $PRODUCTION_URL $STAGING_URL --skip-themes --skip-plugins || error 'Unable to update URL on staging.'
wp option update staging_config "$CONFIG" --format=json --path=$STAGING_DIR || error 'Unable to import global config on staging.'
wp option update mm_coming_soon 'true' --path=$STAGING_DIR || error 'Unable to enable the coming soon page on staging.'
wp rewrite flush --path=$STAGING_DIR || error 'Unable to flush rewrite rules.'
rewrite_htaccess $STAGING_DIR
#fire email here from mojo cli to site admin
clear
echo \{\"status\" :\"success\",\"message\":\"Staging website created successfully.\",\"reload\":\"true\"\}
}
function clone {
cd $PRODUCTION_DIR || error 'Unable to move to production directory.'
STAGING_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$STAGING_DIR)
WP_VER=$(wp core version)
if [ "0" != "$USER_ID" ]
then
SESSIONS=$(wp user meta get $USER_ID session_tokens --format=json --path=$STAGING_DIR)
fi
wp db query "DROP TABLE $STAGING_TABLES;" --path=$STAGING_DIR || error 'Unable to drop staging tables.'
wp db export $STAGING_DIR/.export-sql --add-drop-table || error 'Unable to export database.'
sed -i -e "s/$DB_PREFIX/staging_$DB_PREFIX/g" $STAGING_DIR/.export-sql || error 'Unable to update prefix.'
cd $STAGING_DIR || error 'Unable to move to staging directory.'
wp db import $STAGING_DIR/.export-sql --skip-themes --skip-plugins || error 'Unable to import database.'
if [ "0" != "$USER_ID" ]
then
wp user meta update $USER_ID session_tokens "$SESSIONS" --format=json
fi
wp option update staging_environment staging || error 'Unable to set environment.'
move_files $PRODUCTION_DIR $STAGING_DIR
wp core download --version=$WP_VER --force || error 'Unable to install WordPress in staging directory.'
wp search-replace $PRODUCTION_URL $STAGING_URL --skip-themes --skip-plugins || error 'Unable to update URL on staging.'
wp option update staging_config "$CONFIG" --format=json --path=$STAGING_DIR || error 'Unable to import global config on staging.'
wp option update mm_coming_soon 'true' --path=$STAGING_DIR || error 'Unable to enable the coming soon page on staging.'
wp rewrite flush --path=$STAGING_DIR || error 'Unable to flush rewrite rules.'
save_state 'Clone From Production'
rm $STAGING_DIR/.export-sql --force
rewrite_htaccess $STAGING_DIR
clear
echo \{\"status\" :\"success\",\"message\":\"Website cloned successfully.\"\}
}
function deploy_files {
cd $STAGING_DIR || error 'Unable to move to staging directory.'
WP_VER=$(wp core version)
save_state 'Save then Deploy Files'
wp core download --version=$WP_VER --force --path=$PRODUCTION_DIR || error 'Unable to move WordPress files.'
move_files $STAGING_DIR $PRODUCTION_DIR
clear
echo \{\"status\" :\"success\",\"message\":\"Files deployed successfully.\",\"callback\":\"mm_load_revisions\"\}
}
function deploy_db {
cd $STAGING_DIR || error 'Unable to move staging directory.'
save_state 'Save then Deploy Database'
wp db query "DROP TABLE $PRODUCTION_TABLES;" --path=$STAGING_DIR || error 'Unable to drop staging tables.'
wp db export $STAGING_DIR/.export-sql --add-drop-table || error 'Unable to export database.'
sed -i -e "s/staging_$DB_PREFIX/$DB_PREFIX/g" $STAGING_DIR/.export-sql || error 'Unable to update prefix.'
wp db import $STAGING_DIR/.export-sql --path=$PRODUCTION_DIR || error 'Unable to import database.'
wp search-replace "$STAGING_URL" "$PRODUCTION_URL" --path=$PRODUCTION_DIR || error 'Unable to update URL on production.'
rm $STAGING_DIR/.export-sql --force
wp option update staging_environment production --path=$PRODUCTION_DIR || error 'Unable to set environment.'
wp option update staging_config "$CONFIG" --format=json --path=$PRODUCTION_DIR || error 'Unable to import global config on production.'
wp option delete mm_coming_soon --path=$PRODUCTION_DIR || error 'Unable to disable coming soon page.'
rewrite_htaccess $PRODUCTION_DIR
clear
echo \{\"status\" :\"success\",\"message\":\"Database deployed successfully.\",\"callback\":\"mm_load_revisions\"\}
}
function deploy_files_db {
deploy_files
deploy_db
clear
echo \{\"status\" :\"success\",\"message\":\"Files and Database deployed successfully.\",\"callback\":\"mm_load_revisions\"\}
}
function deploy_files_dbmerge {
clear
# echo \{\"status\" :\"success\",\"message\":\"Files deployed and DB merged successfully.\"\}
}
function destroy {
cd $PRODUCTION_DIR || error 'Unable to move to production directory.'
if test -d $STAGING_DIR
then
STAGING_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$STAGING_DIR)
wp db query "DROP TABLE $STAGING_TABLES;" --path=$STAGING_DIR || error 'Unable to drop staging tables.'
wp option delete staging_environment --path=$PRODUCTION_DIR || error 'Unable to reset staging environment in production.'
wp option delete staging_config --path=$PRODUCTION_DIR || error 'Unable to remove global staging config.'
rm -r $STAGING_DIR --force || error 'Unable to remove staging files.'
mkdir -p $STAGING_DIR
echo "<script type='text/javascript'>window.location = '$PRODUCTION_URL';</script>" > $STAGING_DIR/index.php
clear
echo \{\"status\":\"success\",\"message\":\"Staging website destroyed.\",\"reload\":\"true\"\}
fi
}
function move_files {
FROM="$1"
TO="$2"
rm -r $TO/wp-content/themes --force || error 'Unable to remove themes directory.'
rm -r $TO/wp-content/plugins --force || error 'Unable to remove plugins directory.'
mkdir -p $TO/wp-content/uploads || error 'Unable to create uploads folder.'
mkdir -p $TO/wp-content/themes || error 'Unable to create themes folder.'
mkdir -p $TO/wp-content/plugins || error 'Unable to create plugins folder.'
rsync -r --exclude=.git $FROM/wp-content/uploads/* $TO/wp-content/uploads || error 'Unable to move uploads folder.'
rsync -r --exclude=.git $FROM/wp-content/themes/* $TO/wp-content/themes || error 'Unable to move themes folder.'
rsync -r --exclude=.git $FROM/wp-content/plugins/* $TO/wp-content/plugins || error 'Unable to move plugins folder.'
}
function rewrite_htaccess {
LOCATION="$1"
wp eval 'global $wp_rewrite; echo $wp_rewrite->mod_rewrite_rules();' --path=$LOCATION > $LOCATION/.htaccess || error 'Unable to create htaccess'
}
function save_state {
cd $STAGING_DIR || error 'Unable to move to staging directory.'
STAGING_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$STAGING_DIR)
wp db export $STAGING_DIR/.export-sql --add-drop-table --tables=$STAGING_TABLES --path=$STAGING_DIR || error 'Unable to export database to save point.'
git add . || error 'Unable to add files to git.'
if [ -z "$1" ]
then
MESSAGE='Staging Save State'
else
MESSAGE="$1"
fi
git commit -m "$MESSAGE"
rm $STAGING_DIR/.export-sql --force
clear
echo \{\"status\" :\"success\",\"message\":\"Restoration point added.\",\"callback\":\"mm_load_revisions\"\}
}
function restore_state {
cd $STAGING_DIR || error 'Unable to move to staging directory.'
if [ -z "$1" ]
then
error 'No revision provided.'
else
EXIST=$(git cat-file -t $1)
if [ "$EXIST" == "commit" ]
then
if [ "0" != "$USER_ID" ]
then
SESSIONS=$(wp user meta get $USER_ID session_tokens --format=json)
fi
git checkout "$1" --force || error 'Unable to restore files from revision.'
STAGING_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$STAGING_DIR)
wp db query "DROP TABLE $STAGING_TABLES;" --path=$STAGING_DIR || error 'Unable to drop staging tables.'
wp db import $STAGING_DIR/.export-sql --path=$STAGING_DIR || error 'Unable to import database from save point.'
rm $STAGING_DIR/.export-sql --force
if [ "0" != "$USER_ID" ]
then
wp user meta update $USER_ID session_tokens "$SESSIONS" --format=json --path=$STAGING_DIR
fi
echo \{\"status\" :\"success\",\"message\":\"State restored successfully.\",\"callback\":\"mm_load_revisions\"\}
else
error 'Unable to locate revision.'
fi
fi
}
function revisions {
clear
cd $STAGING_DIR || error 'Unable to move to staging directory.'
LOG=$(git log --pretty=format:'%h,%ad,%s;' -10)
echo $LOG
}
function sso_staging {
if [ -z $1 ]
then
error 'No user provided.'
fi
LINK=$(wp mojo sso --url-only --id=$1 --path=$STAGING_DIR)
echo \{\"status\":\"success\",\"load_page\":\"$LINK\&redirect=admin.php\?page=mojo-staging\"\}
}
function sso_production {
if [ -z $1 ]
then
error 'No user provided.'
fi
LINK=$(wp mojo sso --url-only --id=$1 --path=$PRODUCTION_DIR)
echo \{\"status\":\"success\",\"load_page\":\"$LINK\&redirect=admin.php\?page=mojo-staging\"\}
}
function error {
echo \{\"status\":\"error\",\"message\":\"$1\"\}
exit
}
function lock_check {
LOCK=$(wp transient get mm_staging_lock --path=$PRODUCTION_DIR --quiet)
if [ -n "$LOCK" ]
then
error 'Staging action is locked by another command'
fi
}
function compatibility_check {
if [[ -z $(type wp) ]]
then
error 'WPCLI is not available.'
fi
if [[ -z $(type git) ]]
then
error 'Git is not available.'
fi
WPCLI_VER=$(sed 's/[^0-9.]*\([0-9.]*\).*/\1/' <<< $(wp --version) )
GIT_VER=$(sed 's/[^0-9.]*\([0-9.]*\).*/\1/' <<< $(git --version) )
PHP_VER=$(sed 's/[^0-9.]*\([0-9.]*\).*/\1/' <<< $(php --version) )
if [ "$( printf "0.24.0\n$WPCLI_VER" | sort -V | head -n1 )" == "$WPCLI_VER" ] && [ "$WPCLI_VER" != "0.24.0" ]
then
error "Minimum version of WPCLI not met."
fi
if [ "$( printf "5.3.0\n$PHP_VER" | sort -V | head -n1 )" == "$PHP_VER" ] && [ "$PHP_VER" != "5.3.0" ]
then
error "Minimum version of PHP-CLI not met."
fi
if [ "compat_check" == "$1" ]
then
echo \{\"status\":\"success\"\}
exit
fi
}
PRODUCTION_DIR=$3
STAGING_DIR=$4
PRODUCTION_URL=$5
STAGING_URL=$6
USER_ID=$7
DB=$(wp eval 'echo DB_NAME;' --path=$PRODUCTION_DIR)
DB_USER=$(wp eval 'echo DB_USER;' --path=$PRODUCTION_DIR)
DB_PASS=$(wp eval 'echo DB_PASSWORD;' --path=$PRODUCTION_DIR)
DB_PREFIX=$(wp eval 'global $wpdb;echo $wpdb->prefix;' --path=$PRODUCTION_DIR)
PRODUCTION_TABLES=$(wp db tables --all-tables-with-prefix --format=csv --path=$PRODUCTION_DIR)
if [[ $(pwd) == *"staging"* ]]
then
CURRENT_DIR=$STAGING_DIR
else
CURRENT_DIR=$PRODUCTION_DIR
fi
compatibility_check "$1"
#everything must auth.
auth_action $2
lock_check
CONFIG=$(wp option get staging_config --format=json --path=$PRODUCTION_DIR)
wp transient set mm_staging_lock "true" 120 --path=$PRODUCTION_DIR --quiet
$1 "$8"
wp transient delete mm_staging_lock --path=$PRODUCTION_DIR --quiet
# $1 is function
# $2 is auth TOKEN
# $3 is production dir
# $4 is staging dir
# $5 is production url
# $6 is staging url
# $7 is current user id
# $8 is function param 1