Cheat sheet
This is Ryan’s pseudo public cheat sheet. It gets updated sporadically with things that he forgets.
JS arrow functions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Sass
sass --watch style.scss:style.min.css --style compressed
Switch PHP versions
sudo update-alternatives --set php /usr/bin/php7.4
Custom wp_nav_menu() without a walker
Walker classes are a pain in the butt and non-intuitive. This allows you to create a simple menu without the clutter.
The title seems to vary depending on if it matches the post title or not.
<?php $menu_items = wp_get_nav_menu_items( 'Main Menu' ); foreach ( $menu_items as $key => $menu_item ) { if ( isset( $menu_item->title ) ) { $title = $menu_item->title; } else { $title = $menu_item->post_title; } echo "\n\t\t"; echo '<li><a href="' . esc_url( $menu_item->url ) . '" title="' . esc_attr( $menu_item->post_title ) . '">' . esc_html( $title ) . '</a></li>'; }
Convert jpg to webp
sudo apt install webp
#!/bin/bash clear i=0; for filename in *.jpg; do echo $filename": "$i; fileslug=${filename::-4} cwebp $filename -o $fileslug.webp i=$((i + 1)) done
Detecting a specific page root via PHP
Pages like /search/var/
or /search/?var=something
will be detected by this.
<?php $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI' ); $root_path = '/search/'; $root_length = strlen( $root_path ); if ( $root_path === mb_substr( $request_uri, 0, $root_length ) ) { echo 'This is that page'; die; }
Maybe allows for auto-SFTP with password
sshpass -p 'somepasswordhere' sftp -r 2020/* something@sftp.somethung.com:/public_html/wp-content/uploads/2020/
Diff between two directories
diff -qr before/public_html/ after/public_html/ > diff.txt
Migrating WordPress database
wp search-replace 'domain.com' 'example.com' --skip-columns=guid --all-tables; wp search-replace 'https://example.com' 'http://example.com' --skip-columns=guid --all-tables; wp search-replace 'https:\/\/example.com' 'http:\/\/example.com' --skip-columns=guid --all-tables; grep -rl domain.com . | xargs sed -i 's/domain.com/example.com/g'; wp transient delete --all;
REQUEST_URI
In PHP, do not access directly, use this instead:
<?php filter_input( INPUT_SERVER, 'REQUEST_URI' ); ?>
<?php $get = filter_input( INPUT_GET, 'strattic-search-refresh' ); if ( isset( $get ) ) { // Do something here. } ?>
Bail out if on specific URL (and ignoring sub-paths/query vars)
<php $request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI' ); $path = '/somepath/'; if ( $path !== substr( $request_uri, 0, strlen( $path ) ) ) { return; }
Unzip specific folder
unzip dump.zip 'wp-content/uploads/2017/*' -d public_html/wp-content/uploads/2017/
Unzip to a specific folder
unzip backup.zip -d public_html/;
Zip specific folder
zip -r file.zip /directory_name
rsync
Copy all files in remote directory to current local directory.
rsync -chavzP -e "ssh -p 22" username@somehost.whatever:/var/www/html/ ./
Curl with http auth
curl -u username:password -I https://domain.com
Background terminal process
If your program is already running you can pause it with Ctrl-Z, pull it into the background with bg and then disown it, like this (copy/paste them in so that they’re entered before the task pops to foreground again):
bg; disown; exit;
SFTP command line
sftp user@bla.com get -r public_html/ put -r *
– uploading
then use the “background terminal process” tip above if you need to shut the window whilst the transfer is happening.
MySQL migrations
Fixes weird encoding problems. I have no idea why this is like this, why it is only necessary sometimes or why they’re just not set to normal UTF-8 by default. And I have no idea what the other UTF-8’s even are. Basically I know nothing about this, just that changing these strings fixes problems on import:P
sed -i 's/utf8mb4/utf8/g' your_file.sql sed -i 's/utf8_unicode_ci/utf8_general_ci/g' your_file.sql sed -i 's/utf8_unicode_520_ci/utf8_general_ci/g' your_file.sql
JS entities
This decodes HTML entities in JavaScript. Super useful if you need to get rid of HTML entities from your content. Inserting them into a generated element automatically converts them for you.
/** * Decodes HTML and converts entities back to their real form. * * @param string html The encoded text. * @return string html The decoded text without entities. */ function decode_html( html ) { var txt = document.createElement( 'textarea' ); txt.innerHTML = html; return txt.value; }
JS logger – only shows in dev environments
/** * Console logger. * Only logs when in dev environments. * * @param string text The string to log. */ function log( text ) { if ( 'domain.com' === window.location.hostname || 'www.domain.com' === window.location.hostname ) { return; // Do nothing if on any of the above domains. } console.log( text ); }
ffmpeg
Concatenate all files in folder together (make sure file names are in order first):
ffmpeg -f concat -safe 0 -i <(for f in ./*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
Reencode with keyframe every 10 frames, for editing
ffmpeg -i GH012185.MP4 -vcodec libx264 -x264-params keyint=10:scenecut=0 -acodec copy 1.mp4
Bash for reencoding every keyframe ….
#!/bin/bash for filePath in kathmandu-videos/*.MP4; do [ -e "$filePath" ] || continue fileName=$(basename -- "$filePath") extension="${fileName##*.}" name="${fileName%.*}" ffmpeg -i kathmandu-videos/"$name.$extension" -vcodec libx264 -x264-params keyint=10:scenecut=0 -acodec copy kathmandu-videos-reencoded/"$name".mp4 done
Compress video
ffmpeg -i filename.mp4 -b:v 7000k -vcodec h264 -acodec aac filename-compressed.mp4
Stabilise a file
ffmpeg -i shaky.mp4 -vf vidstabdetect=stepsize=6:shakiness=8:accuracy=9:result=transform_vectors.trf -f null - ffmpeg -i shaky.mp4 -vf vidstabtransform=input=transform_vectors.trf:zoom=1:smoothing=30,unsharp=5:5:0.8:3:3:0.4 -vcodec libx264 -preset slow -tune film -crf 18 -acodec copy stabilised.mp4
increase brightness
ffmpeg -i 71.MP4 -vf eq=brightness=0.2 -c:a copy 71.mp4
Increase brightness, saturation and contrast
ffmpeg -i input.mp4 -vf eq=brightness=0.2:saturation=1.5:contrast=1.3 -c:a copy output.mp4
flip vertical
ffmpeg -i 58b.mp4 -vf "transpose=2,transpose=2" 58d.mp4
flip vertical – with reencode with keyframe every 10 frames, for editing
ffmpeg -i kathmandu-videos-reencoded/GH012364.mp4 -vf "transpose=2,transpose=2" -vcodec libx264 -x264-params keyint=10:scenecut=0 -acodec copy kathmandu-clips/day8-walking-7.mp4
Concatenating lots of files:
ffmpeg -i 'concat:1.m2v|2.m2v|3.m2v|4.m2v|5.m2v|6.m2v|7.m2v|8.m2v|9.m2v|10.m2v|11.m2v|12.m2v|13.m2v|14.m2v|15.m2v|16.m2v|17.m2v|18.m2v|19.m2v|20.m2v|21.m2v|22.m2v|23.m2v|24.m2v|25.m2v|26.m2v|27.m2v|28.m2v|29.m2v|30.m2v|31.m2v|32.m2v|33.m2v|34.m2v|35.m2v|36.m2v|37.m2v|38.m2v|39.m2v|40.m2v|41.m2v|42.m2v|43.m2v|44.m2v|45.m2v|46.m2v|47.m2v|48.m2v|49.m2v|50.m2v|51.m2v|52.m2v|53.m2v|54.m2v|55.m2v|56.m2v|57.m2v|58.m2v|59.m2v|60.m2v|61.m2v|62.m2v|63.m2v|64.m2v|65.m2v|66.m2v|67.m2v|68.m2v|69.m2v|70.m2v|71.m2v|72.m2v|73.m2v|74.m2v|75.m2v|76.m2v|77.m2v|78.m2v|79.m2v|80.m2v|81.m2v|82.m2v|83.m2v|84.m2v' -vcodec libx264 output.m2v
slow down
ffmpeg -i 86.mp4 -filter:v "setpts=0.3*PTS" 86b.mp4
crop to 1080p
ffmpeg -i 10.mp4 -filter:v "crop=1920:1080:0:0" 10b.mp4
Zoom into a section of the screen
ffmpeg -i x.MP4 -vf "scale=2*iw:-1, crop=iw/4:ih/4:27000:1300" x3.MP4
Clip the first 1 second and keep the five seconds after that
ffmpeg -i long.mp4 -ss 00:00:01.0 -c copy -t 00:00:5.0 short.mp4
Rotate 180 degrees
ffmpeg -i a.mp4 -vf "transpose=2,transpose=2" b.mp4
Rotate 90 degrees
0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip
ffmpeg -i a.mp4 -vf "transpose=1" b.mp4
Lossless .mkv codec:
-c:v libx264 -preset ultrafast -crf 0
ffmpeg -i x.mp4 -ss 00:01:25.0 -c copy -t 01:08:0.0 x1.mp4
ffmpeg -i x.ogg -ss 00:00:40.8 -c copy -t 01:08:0.0 x1.ogg
Extract audio
ffmpeg -i x1.mp4 -vn -acodec copy x2.aac
Merge two audios together
ffmpeg -i x1.ogg -i x2.aac -filter_complex amerge -c:a libmp3lame -q:a 4 x3.mp3
Merge audio and video together
ffmpeg -i x1.mp4 -i x3.mp3 -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 x-f2.mp4
Trim to suit (start at 41 seconds, and total length is 1 min 8 secs)
ffmpeg -i x-f2.mp4 -ss 00:00:41.0 -c copy -t 01:08:0.0 x-f3.mp4
Compress file for upload
ffmpeg -i x-f4.mp4 -b:v 7000k -vcodec h264 -acodec aac x-compressed.mp4
Server config
https://geek.hellyer.kiwi/tools/server-setup/
PDF Unite
pdfunite belfast-ryanair1.pdf belfast-ryanair2.pdf belfast-ryanair.pdf
Compressing images
* `sudo apt-get install jpegoptim`
* `sudo apt-get install optipng`
** Batch process **
* `jpegoptim /srv/www/uploads/*.jpg`
* `optipng /srv/www/uploads/*.png`
* iterate through every subdirectory of the current folder:
* `find -type f -name “*.jpg” -exec jpegoptim –strip-all {} \;`
* `find -type f -name “*.jpeg” -exec jpegoptim –strip-all {} \;`
* `find -type f -name “*.png” -exec optpng {} \;`
** Copy all the images out of a directory after compression (for copying back to server conveniently).
* `find imagetest/ -type f \( -iname ‘*.jpg’ -o -iname ‘*.png’ \) -print0 |xargs -0 tar c |(cd imagetestimages ; tar x)`
*
** Apply JPEG compression **
* `jpegoptim -m75 /srv/www/uploads/*.jpg`
** Limiting image width using ImageMagick **
mogrify -resize ‘600×400>’ *.jpg
Resetting a Git branch
This is useful for when you get the error “Your branch is ahead of ‘origin/master’ by 3 commits.
“.
# Loop through every file and process the ones with relevant image extensions.
for FILE in $(find_files .); do
FILEWITHOUTDOT=”${FILE:1}”
NAME=`echo “$FILEWITHOUTDOT” | cut -d’.’ -f1`
EXTENSION=`echo “$FILEWITHOUTDOT” | cut -d’.’ -f2`
if [ “$EXTENSION” = “jpg” ]; then
echo $FILE
jpegoptim $FILE
elif [ “$EXTENSION” = “png” ]; then
echo $FILE
optipng $FILE
fi
done
echo ” ”
echo “COMPLETE!”
git reset --hard origin/master
Git diff via Meld
git difftool -d qa feature/inactive_site_dialog
WordPress debug log
define(‘WP_DEBUG_LOG’, true);
define(‘WP_DEBUG’, true);
Sticks errors into
/wp-content/debug.log
BtSync
# sudo dpkg-reconfigure btsync
SCP
Use this for moving complete folders between servers:
scp -r -P 22 remoteuser@thehostname:/remote_path/html/ /local_path/html/
Manually creating excerpts
Use wp_trim_words(). Do NOT use wp_trim_excerpt().
http://codex.wordpress.org/Function_Reference/wp_trim_words
Using Grunt
- package.json and Gruntfile.js needed
- Install each module …
sudo npm install grunt-wp-i18n
- (If you don’t have the module in your package.json file) Add the module to “node_modules” …
sudo npm install grunt-wp-i18n --save-dev
- Install all modules in the package.json file …
sudo npm install
- This installs a bunch of stuff it seems …
sudo npm install load-grunt-tasks --save-dev
- I think you need to run this before Grunt becomes useful …
npm install -g grunt-cli
- Actually run a command …
sudo grunt makepot
- Add this to grunt.js to run multiple commands at once …
grunt.registerTask('default', ['jsvalidate','makepot','jshint']);
sed
sed -i 's/before_/after_/g' /path/file.sql
Add a Git submodule
git submodule add git@github.com:ryanhellyer/xxx.git
git submodule init
git submodule update
Create MySQL database
mysql -u root -p66536653 -h localhost -e "create database dbname";
Get diff file from SVN
svn diff -r r101 > diff-r102.txt
Between two revisions:
svn diff -r 157:158 > diff-r158.txt
Switching and merging
svn switch --ignore-ancestry ^/trunk .
svn switch --ignore-ancestry ^/branches/staging .
svn merge -c 173 ^/trunk
Info from specific revision
svn log -v -r 118 https://svn.ryan.hellyer.kiwi/
This will provide output like the following:
R118 | rhellyer | 2014-02-27 08:58:50 +0100 (Do, 27 Feb 2014) | 1 line Changed paths: M /branches/staging M /branches/staging/css/global.css M /branches/staging/js/scripts.js Merging CSS and JS changes from trunk R118 into staging
// Checkout specific revision
svn co -r <revision_you_like> repo_url out_folder_name
ie: svn co -r 138 https://svn.ryan.hellyer.kiwi/projectname .
Bash
http://www.tomjn.com/531/wordpress-bash-magic/
Model .gitignore
*.sass-cache pingdom.php wp-config.php wp-content/upgrade .htaccess wp-content/uploads /wp-content/debug.log /migration/error.log *.sql.gz # OS or Editor folders /.idea/ .DS_Store .cache .project .settings .tmproj nbproject Thumbs.db .vim /wp-content/cache/ /wp-content/plugins/p3-profiler /wp-content/mu-plugins/p3-profiler.php /nginx.conf
Fix file permissions/ownership
Run from current directory.
sudo chown ryan:www-data * -R; sudo find . -type d -exec chmod 755 {} \; sudo find . -type f -exec chmod 644 {} \;
Pull img src’s from HTML
<?php preg_match_all( '/<img[^>]+>/i', $html, $imgTags ); for ( $i = 0; $i < count( $imgTags[0] ); $i++ ) { preg_match( '/src="([^"]+)/i', $imgTags[0][$i], $imgage ); $result[] = str_ireplace( 'src="', '', $imgage[0] ); } ?>
Setting variables – shorthand
Useful for setting variables without dicking around longhand.
$type = isset( $option['type'] ) ? $option['type'] : '';
Crude dump of code for rewrite rules
/** * Class constructor. */ public function __construct() { // Load the parent constructor parent::__construct(); add_action( 'init', array( $this, 'rewrites' ) ); add_filter( 'locale', array( $this, 'switch_lang' ) ); // Add query var for 'lang' add_filter( 'query_vars', function( $vars ) { $vars[] = 'lang'; return $vars; } ); } /** * Switch the language. */ public function switch_lang( $lang ) { // Grab lang to use $request_uri_bits = explode( '/', $_SERVER['REQUEST_URI'] ); // Split up URI $request_uri_bits = array_filter( $request_uri_bits ); // Remove empty values $lang_slug = end( $request_uri_bits ); // Grab last string $lang_slug = get_query_var( 'lang' ); // Grab the ISO foreach( $this->langs as $iso => $language ) { if ( $language['slug'] == $lang_slug ) { $lang = $iso; } } if ( ! isset( $lang ) ) { return; // Bail out since language not set } else { // Change language based on slug used return $lang; } } /** * Add rewrite rules. */ public function rewrites() { add_rewrite_rule( 'questionnaire/([^/]+)/([^/]+)/?$', 'index.php?questionnaire=$matches[1]&lang=$matches[2]', 'top' ); }
Redis
To find out Redis stats, keys used, memory resources used etc.
# redis-cli info
Asynchronous http requests in PHP
/** * Asynchronous curl request. * * From https://stackoverflow.com/questions/124462/how-to-make-asynchronous-http-requests-in-php. */ function async_curl( $background_process = '' ) { $ch = curl_init( $background_process ); curl_setopt_array( $ch, array( CURLOPT_HEADER => 0, CURLOPT_RETURNTRANSFER => true, CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms. CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute. CURLOPT_VERBOSE => 1, CURLOPT_HEADER => 1 ) ); $out = curl_exec( $ch ); curl_close( $ch ); return true; }