Define Your Own WordPress Action Hooks

WordPress is based on the so-called Hook-System. This serves WordPress, and all extensions to involve functions in a certain place. The Hooks are not only to hook, but can also be used in custom extensions and thus create a better overview and offer additional interfaces for more possibilities to develop. Especially the second option is interesting when you create a theme, which aims to offer a variety of interfaces, or create a Plugin which can be expand by other authors or serve as a framework.
Continue reading …

Set Meta Links For WordPress Plugins

In the past I explained in the article „How To Improve WordPress Plugins“ , how you can expand Plugins with useful functions and therefore optimize their usage. One of the suggestions was a simple link to the options page of your Plugin.
With WordPress 2.8 the Plugin page will be a little bit different and now there will be a hook, which you can use to enter a link, which is even more convenient.
Continue reading …

WordPress Plugin Compatibility Checker

Right before the upcoming WordPress 2.8 you also should check out if all your Plugins are compatible with Version 2.8 before you upgrade. There is a great website which includes over 5000 Plugins, where you can see if the Plugin will work with WordPress 2.8.

Also very interesting for all Plugin developer, you can see in detail, why your Plugin is not working with the newest version or what can be done better. Really informational! Check it out!

The only thing what would make this even better, if all the Plugins would have a number and this list would have an additional column, where you see the number of a Plugin, which is not compatible with the according Plugin. But I guess, that would be too much work.

But I have to say, respect to the guys of BraveNewCode, that they keep this list up to date! Chapeau!

FirePHP and WordPress


WordPress uses a whole series of constants and variables that may be useful. Even better if you know what is in there. A clean output of the contents can be realized with the Firefox add-on FirePHP for Firebug.

To symplify and accelerate my development, I always have a plugin activated, which outputs various contents, directly above FirePHP. Hence I created a small Plugin, which contains a whole series of constants and variables, which is based on the upcoming 2.8 version of WordPress. Because I think that this can be useful, here the download to the Plugin and the content, if someone has a solution and only needs the constants and variables.


Plugin WP FirePHP

To work quickly and easily in WordPress with FirePHP, I recommend to use the Plugin. It requires no settings or something similar in the database, the code is exemplary, so that you can easily expand and areas can be commented out if some are not needed. We have a variety of content in it that are useful in WordPress, including the constants, global variables and PHP predefined variables.

Download the Plugin in SVN of WordPress: WP FirePHP. The installation is as usual, put it in the Plugin folder and activate.

Download: Plugin WP FirePHP for WordPress

Constants and variables

$wp_constants = array(
'ABSPATH'                            => ABSPATH,
'APP_REQUEST'                        => APP_REQUEST,
'ARRAY_A'                            => ARRAY_A,
'ARRAY_N'                            => ARRAY_N,
'ATOM'                               => ATOM,
'AUTH_COOKIE'                        => AUTH_COOKIE,
'AUTH_KEY'                           => AUTH_KEY,
'COOKIEHASH'                         => COOKIEHASH,
'COOKIEPATH'                         => COOKIEPATH,
'COOKIE_DOMAIN'                      => COOKIE_DOMAIN,
'CRLF'                               => CRLF,
'CUSTOM_TAGS'                        => CUSTOM_TAGS,
'DB_CHARSET'                         => DB_CHARSET,
'DB_COLLATE'                         => DB_COLLATE,
'DB_HOST'                            => DB_HOST,
'DB_NAME'                            => DB_NAME,
'DB_PASSW'                           => DB_PASSW,
'DB_PASSWORD'                        => DB_PASSWORD,
'DB_USER'                            => DB_USER,
'DOING_AJAX'                         => DOING_AJAX,
'DOING_AUTOSAVE'                     => DOING_AUTOSAVE,
'DOING_CRON'                         => DOING_CRON,
'EP_ALL'                             => EP_ALL,
'EP_ATTACHMENT'                      => EP_ATTACHMENT,
'EP_AUTHORS'                         => EP_AUTHORS,
'EP_CATEGORIES'                      => EP_CATEGORIES,
'EP_COMMENTS'                        => EP_COMMENTS,
'EP_DATE'                            => EP_DATE,
'EP_DAY'                             => EP_DAY,
'EP_MONTH'                           => EP_MONTH,
'EP_NONE'                            => EP_NONE,
'EP_PAGES'                           => EP_PAGES,
'EP_PERMALINK'                       => EP_PERMALINK,
'EP_ROOT'                            => EP_ROOT,
'EP_SEARCH'                          => EP_SEARCH,
'EP_TAGS'                            => EP_TAGS,
'EP_YEAR'                            => EP_YEAR,
'EZSQL_VERSION'                      => EZSQL_VERSION,
'FORCE_SSL_ADMIN'                    => FORCE_SSL_ADMIN,
'FORCE_SSL_LOGIN'                    => FORCE_SSL_LOGIN,
'FTP_ASCII'                          => FTP_ASCII,
'FTP_AUTOASCII'                      => FTP_AUTOASCII,
'FTP_BINARY'                         => FTP_BINARY,
'FTP_FORCE'                          => FTP_FORCE,
'IS_PROFILE_PAGE'                    => IS_PROFILE_PAGE,
'JSON_BOOL'                          => JSON_BOOL,
'JSON_END_ARRAY'                     => JSON_END_ARRAY,
'JSON_END_OBJ'                       => JSON_END_OBJ,
'JSON_FLOAT'                         => JSON_FLOAT,
'JSON_INT'                           => JSON_INT,
'JSON_IN_ARRAY'                      => JSON_IN_ARRAY,
'JSON_IN_BETWEEN'                    => JSON_IN_BETWEEN,
'JSON_IN_OBJECT'                     => JSON_IN_OBJECT,
'JSON_KEY'                           => JSON_KEY,
'JSON_NULL'                          => JSON_NULL,
'JSON_SKIP'                          => JSON_SKIP,
'JSON_START_ARRAY'                   => JSON_START_ARRAY,
'JSON_START_OBJ'                     => JSON_START_OBJ,
'JSON_STR'                           => JSON_STR,
'LANGDIR'                            => LANGDIR,
'LOGGED_IN_COOKIE'                   => LOGGED_IN_COOKIE,
'LOGGED_IN_KEY'                      => LOGGED_IN_KEY,
'MAGPIE_CACHE_AGE'                   => MAGPIE_CACHE_AGE,
'MAGPIE_CACHE_DIR'                   => MAGPIE_CACHE_DIR,
'MAGPIE_CACHE_ON'                    => MAGPIE_CACHE_ON,
'MAGPIE_DEBUG'                       => MAGPIE_DEBUG,
'MAGPIE_USE_GZIP'                    => MAGPIE_USE_GZIP,
'MAX_RESULTS'                        => MAX_RESULTS,
'MC_LOGGER_DEBUG'                    => MC_LOGGER_DEBUG,
'MC_LOGGER_ERROR'                    => MC_LOGGER_ERROR,
'MC_LOGGER_FATAL'                    => MC_LOGGER_FATAL,
'MC_LOGGER_INFO'                     => MC_LOGGER_INFO,
'MC_LOGGER_WARN'                     => MC_LOGGER_WARN,
'OBJECT'                             => OBJECT,
'OBJECT_K'                           => OBJECT_K,
'PASS_COOKIE'                        => PASS_COOKIE,
'PCLZIP_CB_PRE_ADD'                  => PCLZIP_CB_PRE_ADD,
'PCLZIP_OPT_PATH'                    => PCLZIP_OPT_PATH,
'PLUGINDIR'                          => PLUGINDIR,
'RSS'                                => RSS,
'SECURE_AUTH_KEY'                    => SECURE_AUTH_KEY,
'STATUS_INTERVAL'                    => STATUS_INTERVAL,
'TEMPLATEPATH'                       => TEMPLATEPATH,
'TEST_COOKIE'                        => TEST_COOKIE,
'USER_COOKIE'                        => USER_COOKIE,
'WPINC'                              => WPINC,
'WPLANG'                             => WPLANG,
'WP_ADMIN'                           => WP_ADMIN,
'WP_CONTENT_DIR'                     => WP_CONTENT_DIR,
'WP_CONTENT_URL'                     => WP_CONTENT_URL,
'WP_IMPORTING'                       => WP_IMPORTING,
'WP_INSTALLING'                      => WP_INSTALLING,
'WP_LANG_DIR'                        => WP_LANG_DIR,
'WP_MEMORY_LIMIT'                    => WP_MEMORY_LIMIT,
'WP_PLUGIN_DIR'                      => WP_PLUGIN_DIR,
'WP_PLUGIN_URL'                      => WP_PLUGIN_URL,
'WP_USE_THEMES'                      => WP_USE_THEMES,
'WXR_VERSION'                        => WXR_VERSION,
'XMLRPC_REQUEST'                     => XMLRPC_REQUEST

$wp_globals_a_l = array(
'$admin_page_hooks'                  => $admin_page_hooks,
'$ajax_results'                      => $ajax_results,
'$all_links'                         => $all_links,
'$allowedposttags'                   => $allowedposttags,
'$allowedtags'                       => $allowedtags,
'$authordata'                        => $authordata,
'$bgcolor'                           => $bgcolor,
'$cache_categories'                  => $cache_categories,
'$cache_lastcommentmodified'         => $cache_lastcommentmodified,
'$cache_lastpostdate'                => $cache_lastpostdate,
'$cache_lastpostmodified'            => $cache_lastpostmodified,
'$cache_userdata'                    => $cache_userdata,
'$category_cache'                    => $category_cache,
'$class'                             => $class,
'$comment'                           => $comment,
'$comment_cache'                     => $comment_cache,
'$comment_count_cache'               => $comment_count_cache,
'$commentdata'                       => $commentdata,
'$current_user'                      => $current_user,
'$day'                               => $day,
'$debug'                             => $debug,
'$descriptions'                      => $descriptions,
'$error'                             => $error,
'$feeds'                             => $feeds,
'$id'                                => $id,
'$is_apache'                         => $is_apache,
'$is_IIS'                            => $is_IIS,
'$is_macIE'                          => $is_macIE,
'$is_winIE'                          => $is_winIE,
'$l10n'                              => $l10n,
'$locale'                            => $locale,
'$link'                              => $link
$wp_globals_m_r = array(
'$m'                                 => $m,
'$map'                               => $map,
'$max_num_pages'                     => $max_num_pages,
'$menu'                              => $menu,
'$mode'                              => $mode,
'$month'                             => $month,
'$month_abbrev'                      => $month_abbrev,
'$monthnum'                          => $monthnum,
'$more'                              => $more,
'$multipage'                         => $multipage,
'$names'                             => $names,
'$newday'                            => $newday,
'$numpages'                          => $numpages,
'$page'                              => $page,
'$page_cache'                        => $page_cache,
'$paged'                             => $paged,
'$pagenow'                           => $pagenow,
'$pages'                             => $pages,
'$parent_file'                       => $parent_file,
'$preview'                           => $preview,
'$previousday'                       => $previousday,
'$previousweekday'                   => $previousweekday,
'$plugin_page'                       => $plugin_page,
'$post'                              => $post,
'$post_cache'                        => $post_cache,
'$post_default_category'             => $post_default_category,
'$post_default_title'                => $post_default_title,
'$post_meta_cache'                   => $post_meta_cache,
'$postc'                             => $postc,
'$postdata'                          => $postdata,
'$posts'                             => $posts,
'$posts_per_page'                    => $posts_per_page,
'$previousday'                       => $previousday,
'$request'                           => $request,
'$result'                            => $result,
'$richedit'                          => $richedit
$wp_globals_s_v = array(
'$single'                            => $single,
'$submenu'                           => $submenu,
'$table_prefix'                      => $table_prefix,
'$targets'                           => $targets,
'$timedifference'                    => $timedifference,
'$timestart'                         => $timestart,
'$timeend'                           => $timeend,
'$updated_timestamp'                 => $updated_timestamp,
'$urls'                              => $urls,
'$user_ID'                           => $user_ID,
'$user_email'                        => $user_email,
'$user_identity'                     => $user_identity,
'$user_level'                        => $user_level,
'$user_login'                        => $user_login,
'$user_pass_md5'                     => $user_pass_md5,
'$user_url'                          => $user_url
$wp_globals_w = array(
'$weekday'                           => $weekday,
'$weekday_abbrev'                    => $weekday_abbrev,
'$weekday_initial'                   => $weekday_initial,
'$withcomments'                      => $withcomments,
'$wp'                                => $wp,
'$wp_broken_themes'                  => $wp_broken_themes,
'$wp_db_version'                     => $wp_db_version,
'$wp_did_header'                     => $wp_did_header,
'$wp_did_template_redirect'          => $wp_did_template_redirect,
'$wp_file_description'               => $wp_file_description,
'$wp_filter'                         => $wp_filter,
'$wp_importers'                      => $wp_importers,
'$wp_plugins'                        => $wp_plugins,
'$wp_themes'                         => $wp_themes,
'$wp_object_cache'                   => $wp_object_cache,
'$wp_query'                          => $wp_query,
'$wp_queries'                        => $wp_queries,
'$wp_rewrite'                        => $wp_rewrite,
'$wp_roles'                          => $wp_roles,
'$wp_similiesreplace'                => $wp_similiesreplace,
'$wp_smiliessearch'                  => $wp_smiliessearch,
'$wp_version'                        => $wp_version,
'$wpcommentspopupfile'               => $wpcommentspopupfile,
'$wpcommentsjavascript'              => $wpcommentsjavascript

Analyze WordPress Performance – Plugin!

Recently Joost mentioned in a post on, how he used my Plugin “Debug Queries” to optimize his WordPress database performance (BTW, thanks for the patch).

Performance of WordPress can be quickly and easily negative effected by using some Plugins. You don’t have to be an expert to know, that more function will provide more load. However, provides the simplicity of creating a Plugin for WordPress, which have made it so popular and I very much appreciate, a problem – You don’t have to be a professional developer to create a Plugin, but an optimized syntax lead to a much improved performance of a WordPress installation.

But the real problem: How to find the weak point in your blog?

You can use some tools to analyze performance, for example the Add-on Firebug in Firefox, especially with YSlow. This helps to find scripts which slowing down your blog and vulnerabilities in a code. Also makes sense that “many” scripts, which get installed with some Plugins, should not be load by wp_head but in wp_footer. Scripts should be placed in the footer to improve the performance.

However, the analysis via disabling / enabling all Plugins is a hassle. It would be useful, to examine the different queries and look at what function they refer.

WordPress offers the possibility to display the total number of queries, as well as the time needed. With the following syntax, preferably put in the footer of the page, this is done quickly.

<?php echo $wpdb->num_queries; ?>q, <?php timer_stop(1); ?>s

But the variable $wpdb offers more to look into the /wp-includes/wp-db.php.

if (!defined('SAVEQUERIES'))
define('SAVEQUERIES', false);
class wpdb {
var $show_errors = true;
var $num_queries = 0;
var $last_query;
var $col_info;
var $queries;
var $prefix = '';
// Our tables
var $posts;
var $users;
var $categories;
var $post2cat;
var $comments;
var $links;
var $options;
var $postmeta;
var $usermeta;
var $terms;
var $term_taxonomy;
var $term_relationships;
var $tables = array('users', 'usermeta', 'posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options', 'postmeta', 'terms', 'term_taxonomy', 'term_relationships');
var $charset;
var $collate;

You will notice the constant SAVEQUERIES which is not defined in wp-config.php. Setting this constant to TRUE, it leaves the door open for other possibilities.
But I don’t want to get in too much details, because it would be too much for just one post. Who has an interest can find a whole range of information in the said file.

My goal was not to get the total number of queries in the blog as a result, but the individual queries including their syntax, because then I can find the problem explicitly in the code.

To ensure that this will work easily and quickly on every blog, I created a Plugin and just have to enable it, if I want to get an analysis. In addition, the analysis will only start and the result displayed when an administrator is logged in.

The result may look like this for example:


16. Time: 0.000431060791016
Query: SELECT object_id, term_taxonomy_id FROM fb122_term_relationships INNER JOIN fb122_posts ON object_id = ID WHERE term_taxonomy_id IN (6,5,1) AND post_type = 'post' AND post_status = 'publish'
Call from: wp-includes\taxonomy.php(2093): wpdb->get_results()
17. Time: 0.00243401527405
Query: SELECT t.*, tt.* FROM fb122_terms AS t INNER JOIN fb122_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('link_category') AND tt.count > 0 ORDER BY ASC
Call from: wp-includes\taxonomy.php(777): wpdb->get_results()
18. Time: 0.00080418586731
Query: SELECT * , IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated FROM fb122_links INNER JOIN fb122_term_relationships AS tr ON (fb122_links.link_id = tr.object_id) INNER JOIN fb122_term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id WHERE 1=1 AND link_visible = 'Y' AND ( tt.term_id = 2 ) AND taxonomy = 'link_category' ORDER BY link_name ASC
Call from: wp-includes\bookmark.php(255): wpdb->get_results()
* Total query time: 0.02111s for 18 queries.
* Page generated in 0.36373s, 94.20% PHP, 5.80% MySQL

The work certainly is not necessarily pleasant, but I can find the real problems in the database query and maybe improve the corresponding query or deactivate it. The Plugin uses some more information than the above tutorial, so it is understandable and more informational.

Debug Queries (plugin)

After activating the plugin, the individual queries will be written in the footer of the page, as an HTML comment. So you must analyze the source code to retrieve the values. The values are analyzed and displayed only when an administrator is logged in.

You can Download Debug Queries here!

Further Plugins to analyze and improve your WordPress database

Bye Bye my-hacks.php?

Soon the new 2.8 version of WordPress will be released, but the hype is not as much as it was some years ago, when version 2.0 was released for example.

But the new version brings many new things, fixes a large number of problems and WordPress is in my view, more open than in the prior versions. One of the points that users should be aware of is the fact that the option for the support of the my-hacks.php removed. 2003 this file was announced as a feature, and now it’s going to be removed silently. WordPress has a sophisticated interface system, you can start at various points and bring in new functionality, so that the developer team decided that there is no longer need to support this solution. Alternatives and possibilities of further usage will briefly shown here.

Continue reading …