Frameworks

How to force the_date() / get_the_date() to a specific locale

The WordPress function the_date() and get_the_date() always return the date / time in the locale format defined by the language setting of the current WordPress installation.

What if you need to get the date in a specific locale, e.g. english?

Setting the wordpress language to the target locale will successfully achieve this, but will also change the language of other parts of WordPress and is therefore often not an option.

In case you can’t do that and you have to find a programmatic solution, this is my way to force

<?php the_date('r', '', '', TRUE); ?>

to a specific locale ("C" i.e. plain english in this case)

<?php
    setlocale(LC_TIME, "C"); // Set to target locale (in which you want the date to be formatted
    echo strftime("%a, %d %b %Y %H:%M:%S %z", get_post_time('U', TRUE)); // Parse wordpress time and format it again
    setlocale(LC_TIME, "de_DE"); // Set back to the original locale!
?>

Since the_date() ignores setlocale() calls, we use PHP’s strftime() to work around this.

First, we set the target tocale (the locale for the date to be formatted in) using setlocale(LC_TIME, "C"); Replace "C" by your target locale! "C" is a good choice if you want plain english.

Then, we get the post date & time (the same date & time that is used / returned by the_date() & get_the_date()) using get_post_time('U', TRUE); . "U" means return as Unix timestamp. TRUE is very important here since it tells get_post_time() to return the timestamp as UTC. If you don’t use TRUE here, your dates will be offset by several hours (depending on your timezone) in case they are not UTC already.

After that, we run strftime() to format the timestamp. You need to insert your desired format string here. In my case, the format string is "%a, %d %b %Y %H:%M:%S %z" which is a RFC2822 date. Note that using this method, the timezone (%z) will always be +0000 since it’s formatted as a UTC date. However, the timezone offset will be correctly accounted for.

As a last step, we re-set the original locale using setlocale(LC_TIME, "de_DE"); . This avoids affecting other function, e.g. in other plugins. You need to insert the correct (original) locale here. In my case, I know the correct locale is "de_DE", but in your case this may differ.

Posted by Uli Köhler in PHP, Wordpress

How to get path to the wp_content directory in WordPress plugin

Problem:

You are writing a wordpress plugin in which you need the path to the wp-content directory on the filesystem.

Solution:

Use the WP_CONTENT_DIR constant.

$path_to_wp_content = WP_CONTENT_DIR; // e.g. "/var/sites/techoverflow.net/wp-content"

Note that WP_CONTENT_DIR has no trailing slash.

Use WP_CONTENT_DIR . "/" like this

$path_to_wp_content = WP_CONTENT_DIR . "/"; // e.g. "/var/sites/techoverflow.net/wp-content/"

to get the path to wp_content including a trailing slash.

Posted by Uli Köhler in PHP, Wordpress

How to fix WP_Query not listing any posts

Problem:

In your custom WordPress plugin or theme you have code like

$query = new WP_Query( );
while ( $query->have_posts() ) {
        $query->the_post();
        // ... your code to process the post ...
}

But $query->have_posts() is always false and the loop is never executed.

Solution:

WP_Query works only if you use an appropriate query. Using no query at all is not equivalent to list all posts!

This is likely what you want to do:

$query = new WP_Query(array('post_type' => 'post'));
Posted by Uli Köhler in PHP, Wordpress

How to recover WordPress admin access if you only have FTP access

There are well-documented solutions to recover the wordpress admin access if you have MySQL, phpMyAdmin or shell access.

This solution shows you how to create a new admin user if you don’t know the admin username or password and you don’t have any form of MySQL or shell access (only FTP access is required).

Step 1: Identify your currently active theme

This can be done by looking at the source code of your homepage (go to your domain, then Ctrl+U to show the source) and then Ctrl+F-search for wp-content/themes. It will show hits like https://mydomain.de/wp-content/themes/twentyfifteen/style.css. This means the currently active theme is twentyfifteen.

Step 2: Create a new admin user using functions.php

Now open your FTP software (I recommend FileZilla) and find your wp-content folder. Inside wp-content, go to themes and then open the folder of your currently active theme.

If the currently active theme is not listed in your wp-content/themes folder, you might have the wrong wp-content folder. Check if there are any other folders around.

When you have found your theme folder, edit functions.php and, just after the first <?php, add this block of code:

function wpb_admin_account(){
    $user = 'newadmin';
    $pass = 'saiquae9shahZus6eeri3feNae8gie';
    $email = 'admin-email@example.org';
    if ( !username_exists( $user )  && !email_exists( $email ) ) {
        $user_id = wp_create_user( $user, $pass, $email );
        $user = new WP_User( $user_id );
        $user->set_role( 'administrator' );
    }
}
add_action('init','wpb_admin_account');

Be sure to replace the username, password and email! I recommend to use a new random password and a non-generic username! The username you enter here must.

Save the file and upload it to the server.

After that, goto your homepage and reload once (this will create the new user).

Then, try to login using your newly created user (go to e.g. https://my-domain.com/wp-admin to do so!). If it doesn’t work, check if you edited the functions.php for the correct theme and try to use a different username!

Step 3: Delete the code we just created

If you just leave in the code, this will create a potential security risk. So I recommend deleting it right away!

Also, be sure to delete any admin users you don’t need afterwards.

 

Posted by Uli Köhler in PHP, Wordpress

How to use the old ‘classic’ editor in WordPress 5.0

TL;DR: Install & activate the Classic Editor plugin.

WordPress 5.0 introduced the new Gutenberg editor as the new default editor.

In order to activate the old or classic editor by default again, go to Plugins -> Install and enter classic editor in the search bar at the top right.

The first result at the top left should be this plugin:

Click Install now in the top right of that plugin to install the plugin. After it is done installing, click Activate. After doing that, the classic editor will be active by default.

Posted by Uli Köhler in Wordpress

Find WordPress category ID by category name using SQL

Problem:

You need the wordpress category ID for a given category name (e.g. My category), e.g. for a shortcode filter.

Solution:

You can use a SQL statement to find the correct category for your term (i.e. the category name, My category). Run this statement in your database administration interface, e.g. phpmyadmin.

SELECT termtax.term_taxonomy_id FROM wp_terms AS terms JOIN wp_term_taxonomy AS termtax ON terms.term_id = termtax.term_id WHERE terms.name = "My category"

Replace My category at the end by the category name you’re looking for.

Posted by Uli Köhler in Wordpress

Get the original language post ID for WPML-translated posts

Problem:

You have a post that has been translated into multiple languages using WPML.
You want to find out the ID of the original post, i.e. the equivalent post in the source langugae.

Solution:

As far as I know, there is no WPML API for this. You can, however, use $wpdb in order to query the database directly.

Here’s the SQL statement:

SELECT trans2.element_id
FROM wp_icl_translations AS trans1
INNER JOIN wp_icl_translations AS trans2
ON trans2.trid = trans1.trid
WHERE trans1.element_id = #myid#
AND trans2.source_language_code IS NULLs

where #myid# is the ID of your current (possibly translated) post.

The algorithm works like this:

  1. Find out the  translation ID (column trid) for the current post by selecting the row for the given post ID (column element_id)
  2. Find all rows with the same translation ID
  3. Select only the row where the source language is NULL – this is the original post.

You can use it like this:

global $wpdb;
$orig_lang_id = $wpdb->get_var("SELECT trans2.element_id FROM wp_icl_translations AS trans1 INNER JOIN wp_icl_translations AS trans2 ON trans2.trid = trans1.trid WHERE trans1.element_id = ".get_the_ID()." AND trans2.source_language_code IS NULL");

and then use $orig_lang_id where required. Note that $orig_lang_id is NULL if the query fails. The main reason for the query to fail is if there is no entry for the given post ID in the wp_icl_translations table.

If the current post is the source post, $orig_lang_id is the same as get_the_ID(), i.e. the current ID of the post.

In my test, the code still works (i.e. returns the correct post ID) even when creating brand-new entry without any translations being present.

Posted by Uli Köhler in Wordpress

linkchecker: Ignore WordPress XMLRPC

Problem:

You are using linkchecker to check your WordPress site, but you get the following error multiple times:

$ linkchecker https://techoverflow.net
URL        `https://techoverflow.net/xmlrpc.php'
Parent URL https://techoverflow.net/, line 8, col 1
Real URL   https://techoverflow.net/xmlrpc.php
Check time 1.394 seconds
Result     Error: 405 Method Not Allowed

Solution:

Installing a plugin that disables XMLRPC doesn’t help here –  because the XMLRPC pingback link will still be present on every page.

Instead, just tell linkchecker to ignore the XMLRPC link altogether:

linkchecker https://techoverflow.net --ignore-url=/xmlrpc.php$

 

Posted by Uli Köhler in Wordpress