I sat at my blog post a few days ago and thought that if I post something about programming again, it would not interest people like i.e. my wife. That’s why I’ve come up with an alternative to what I could post what interests everybody. The solution: quotes with beautiful wallpapers.
This is not so easy. I can not sit at Photoshop every day and decorate a picture with a text and post it with hashtags on two platforms. So it had to be an automation.
WordPress backend
I have generated a post type quotes to enter my quotes. This post type I have I have generated a post type “quotes” to enter my quotes. I have additionally given these functions to this post type: given these functions:
- Post excerpt
- Post Thumbnail (min 1920px1080px)
After i was finished, I still had to customize my functions, which I use to publish my posts.
Facebook Autopost
/*
$facebook_photo_id = facebook_photo_upload(array(
'url' => UrlToFile (required),
'caption' => TextForPhoto (optional)
'post_id' => PostID (optional)
));
*/
function facebook_photo_upload( $args ){
$post_id = intval($args['post_id']);
if(
$post_id &&
($facebook_photo_id = get_post_meta( $post_id, 'facebook_post_id', true ))
) return $facebook_photo_id;
require_once('sdk/autoload.php');
$fb = new \Facebook\Facebook([
'app_id' => 'XXXXXXXXXX',
'app_secret' => 'XXXXXXXXXX',
'default_graph_version' => 'v2.10',
'default_access_token' => 'XXXXXXXXXX',
]);
$graphOptions = array(
'url' => $args['url']
);
if($args['caption']) $graphOptions['caption'] = $args['caption'];
try {
$response = $fb->post('/me/photos',$graphOptions);
} catch(\Facebook\Exceptions\FacebookResponseException $e) {
ob_start();
var_dump($e);
var_dump($args);
$facebook_post_dump = ob_get_contents();
ob_end_clean();
wp_mail(
get_option('admin_email'),
'Facebook Post Fail',
"<pre>$facebook_post_dump</pre>",
array('Content-Type: text/html; charset=UTF-8')
);
return false;
}
$facebook_photo_id = json_decode((string) $response->getBody())->id;
update_post_meta( $post_id, 'facebook_post_id', $facebook_photo_id );
return $facebook_photo_id;
}
This code just makes sure that my image is automatically uploaded to Facebook. It’s just an advanced version of what I’m explaining to you here:
Twitter Auto Post
function tweet_media( $args ) {
if($tweet_id = get_post_meta( $args['post_id'], 'tweet_id', true )) return $tweet_id;
require_once('TwitterAPIExchange.php');
$settings = array(
'oauth_access_token' => "XXXXXXXXXX",
'oauth_access_token_secret' => "XXXXXXXXXX",
'consumer_key' => "XXXXXXXXXX",
'consumer_secret' => "XXXXXXXXXX"
);
$twitter = new TwitterAPIExchange($settings);
if ($args['attachment_url']) {
$media = json_decode( (string) $twitter->buildOauth(
'https://upload.twitter.com/1.1/media/upload.json',
'POST'
)->setPostfields(array(
'media_data' => base64_encode(file_get_contents($args['attachment_url']))
))->performRequest()
);
if (!$media->media_id_string) return false;
}
$tweet = ( strlen($args['text']."\n".$args['hashtags'].(($args['link'])? "\n".$args['link'] : '')) < 280 )?
$args['text']."\n".$args['hashtags'].(($args['link'])? "\n".$args['link'] : '') :
$args['text'].(($args['link'])? "\n".$args['link'] : '');
$tweet = json_decode( (string) $twitter->buildOauth(
'https://api.twitter.com/1.1/statuses/update.json',
'POST'
)->setPostfields(array(
'status' => $tweet,
'media_ids' => $media->media_id_string
))->performRequest()
);
if ($tweet->id) {
update_post_meta( $args['post_id'], 'tweet_id', $tweet->id );
}else {
ob_start();
var_dump($tweet);
$tweet_dump = ob_get_contents();
ob_end_clean();
wp_mail(
get_option('admin_email'),
'Tweet Fail',
"<pre>$tweet_dump</pre>",
array('Content-Type: text/html; charset=UTF-8')
);
}
Here is the same as with Facebook. The image is automatically tweeted on Twitter. You can find a more detailed instruction here:
publish_quote action
function share_published_quote( $ID, $post ) {
require_once('twitter/twitter.php');
require_once('facebook/facebook.php');
$facebook_photo_id = facebook_photo_upload(array(
'url' => 'https://www.konzeptcode.com/wp-content/themes/konzeptcode-theme/inc/post-to-quote.php?blog_id='.get_current_blog_id().'&post_id='.$ID,
'caption' => $post->post_excerpt."\n".$post->post_title."\n".tags_to_hashtags($ID),
'post_id' => $ID
));
$tweet_id = tweet_media(array(
'post_id' => $ID,
'text' => $post->post_excerpt."\n".$post->post_title,
'hashtags' => tags_to_hashtags($ID),
'attachment_url' => 'https://www.konzeptcode.com/wp-content/themes/konzeptcode-theme/inc/post-to-quote.php?blog_id='.get_current_blog_id().'&post_id='.$ID
));
}
add_action( 'publish_quote', 'share_published_quote', 10, 2 );
WordPress offers actions and filters. Actions ensure that a certain function is executed in addition, if something has happened. With the filters you can manipulate the variables that are given back.
I’ve caught here as you see, the publish_quote action. This means that every time a post with the post type quote is set to public, the share_published_quote function is executed.
The image generator
I think it would be better if I show you an example picture first and then I try to explain the steps in the code with comments. So you can understand the relationships better:

<?php
// By configuring the header like this, I say that this php file should be output as an image file.
header('Content-Type: image/jpeg');
// The Essential WordPress files are being loaded
require_once("../../../../wp-load.php");
// I have a multisite so i need to switch to the right blog
switch_to_blog(intval($_GET['blog_id']));
// Initial variables get set
$post_id = intval($_GET['post_id']);
$hide_author = ($post_id)? boolval(get_post_meta($post_id, 'hide_author', true)) : boolval($_GET['hide_author']);
/* Essential variables */
$margin_bottom = 120;
$margin_left_right = 120;
$quote_size = 50;
$author_size = intval($quote_size / 1.5);
$padding = 50;
$quote = get_the_excerpt($post_id);
$author = get_the_title($post_id);
$file = get_the_post_thumbnail_url($post_id,'full');
$im = imagecreatefromjpeg($file);
$quote_font = get_template_directory().'/fonts/josefinsans/JosefinSans-Regular.ttf';
$author_font = get_template_directory().'/fonts/josefinsans/JosefinSans-Bold.ttf';
$white = imagecolorallocatealpha($im, 255, 255, 255,20);
$black = imagecolorallocate($im, 0, 0, 0);
/* image adjustment */
$imageDimensions = getimagesize($file);
$imageWidth = $imageDimensions[0];
$imageHeight = $imageDimensions[1];
$imageHeight = floor(($imageHeight/$imageWidth)*1920);
$imageWidth = 1920;
$im = imagescale($im,$imageWidth,$imageHeight);
$im = imagecrop($im,[
'x' => ($imageWidth > 1920)? ($imageWidth-1920)/2 : 0,
'y' => ($imageHeight > 1920)? ($imageHeight-1080)/2 : 0,
'width' => 1920,
'height' => 1080
]);
/* Author */
$author_text_sizes = imagettfbbox( $author_size,0 , $author_font, $author );
$author_width = $author_text_sizes[4];
$author_height = $author_text_sizes[1];
$author_position_bottom = ($hide_author)? 1080-$padding : 1080-$author_height-$margin_bottom;
/* Copyright */
$author_text_sizes = imagettfbbox( $author_size/1.5 ,0 , $author_font, 'talhasariyuerek.com' );
$author_width = $author_text_sizes[4];
$author_height = $author_text_sizes[1];
imagettftext($im, $author_size/1.5 , 0, 1920-$author_width-120+$padding, 1080-$author_height-$padding/2, $white, $author_font, 'talhasariyuerek.com');
/* Setting of word wrapping */
$words = explode(' ', $quote);
$quote = '';
$currentLine = '';
foreach ($words as $position => $word) {
if ($position === 0) {
$currentLine = $word;
} else {
$textDimensions = imagettfbbox(
$quote_size,
0,
$quote_font,
$currentLine . ' ' . $word
);
$textLeft = min($textDimensions[0], $textDimensions[6]);
$textRight = max($textDimensions[2], $textDimensions[4]);
$textWidth = $textRight - $textLeft;
if ($textWidth > 1680) {
$quote .= $currentLine;
$quote .= PHP_EOL;
$currentLine = $word;
} else {
$currentLine .= ' ';
$currentLine .= $word;
}
}
}
$quote .= $currentLine;
$text_size = imagettfbbox( $quote_size, 0, $quote_font, $quote );
$text_position_bottom = $author_position_bottom-$text_size[1]-1.5*$padding;
// Text background is created and integrated
imagefilledrectangle(
$im,
$margin_left_right-$padding, // links
$text_position_bottom-$quote_size-$padding, // Oben
1920 - 120 + $padding, // Rechts
1080 - $margin_bottom + $padding, // Unten
$white
);
// The quote is written into the picture
imagettftext($im, $quote_size, 0, $margin_left_right, $text_position_bottom, $black, $quote_font, $quote);
// If author is desired and given the author will be added
if(!$hide_author) imagettftext($im, $author_size, 0, $margin_left_right, $author_position_bottom, $black, $author_font, $author);
// Using imagepng () yields better text quality than imagejpeg()
imagejpeg($im, NULL, 100);
imagedestroy($im);