Posts from November 2008

The problems of get_posts() and custom post_type’s

Allright, Generally i’d not complain, I’d just make up a new Trac ticket and patch it.. But i’m seriously sick of this defect of WP_Query, A number of times i’ve just given up attempting to achieve my goal and doing it some other method which wouldnt involve hacking up everything..

The problem?

Add a new record to the WP_Posts table, with a custom post_type, now try to retrieve that post. Ah, I hear you say “Thats Easy! Just pass post_type to get_posts()” WRONG!,
Well, yes, In an ideal world, that would be the case, But no, not in this case.

First, Lets add an actual record:

<br />
$url = 'http://dd32.id.au/';<br />
$content = 'DD32 is awesome!';<br />
$datas = array('post_type' => 'custom_type', 'post_status' => 'custom_status', 'post_title' => $url, 'post_name' => $url, 'guid' => md5($url), 'post_content' => $content);<br />
wp_insert_post($datas);<br />

What have i done? Just inserted a stock standard post of type ‘custom_type’ with a non-standard status. Nothing odd there.

Now, Lets retrieve that post.

First thing, Lets check that get_posts() can handle a custom post_type:

<br />
var_dump( get_posts( array('post_type' => 'custom_type') ) );<br />
---<br />
array<br />
empty<br />

Allright, That didnt work, Better check the query used:

SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'custom_type' AND (wp_posts.post_status = 'publish')  ORDER BY wp_posts.post_date DESC LIMIT 0, 5

Ah, It doenst like our post_status, Not a probblem, Letslet it load all status types:

<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any') ) );<br />
---<br />
array<br />
0 =><br />
object(stdClass)[132]<br />
public 'ID' => string '571' (length=3)<br />
public 'post_author' => string '2' (length=1)<br />
public 'post_date' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_date_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content' => string 'DD32 is awesome!' (length=16)<br />
public 'post_title' => string 'http://dd32.id.au/' (length=18)<br />
public 'post_category' => string '0' (length=1)<br />
public 'post_excerpt' => string '' (length=0)<br />
public 'post_status' => string 'custom_status' (length=13)<br />
public 'comment_status' => string 'open' (length=4)<br />
public 'ping_status' => string 'open' (length=4)<br />
public 'post_password' => string '' (length=0)<br />
public 'post_name' => string 'httpdd32idau' (length=12)<br />
public 'to_ping' => string '' (length=0)<br />
public 'pinged' => string '' (length=0)<br />
public 'post_modified' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_modified_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content_filtered' => string '' (length=0)<br />
public 'post_parent' => string '0' (length=1)<br />
public 'guid' => string '9b159fde538e1d5b84949ae427f50168' (length=32)<br />
public 'menu_order' => string '0' (length=1)<br />
public 'post_type' => string 'custom_type' (length=11)<br />
public 'post_mime_type' => string '' (length=0)<br />
public 'comment_count' => string '0' (length=1)<br />

Looks good to me, Everything seems to have been set correctly.

However, hang on, What happens when i only want to retrieve a specific item? Well, I guess we need to specify some arguements to retrieve a single record:

<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'p' => 571 ) ) );<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'page_id' => 571 ) ) );<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'name' => $url ) ) );<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'pagename' => $url ) ) );<br />

One of those should return something.. Right? Well.. Lets look:

<br />
array<br />
empty<br />
array<br />
empty<br />
array<br />
empty<br />
array<br />
empty<br />

Nope, Not a thing.. What the?

Lets go check those queries again…

<br />
8 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.ID = 571 AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC ' (length=135)<br />
1 => float 0.000998020172119<br />
2 => string 'get_posts' (length=9)<br />
9 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.ID = 571 AND wp_posts.post_type = 'page'  ORDER BY wp_posts.post_date DESC ' (length=135)<br />
1 => float 0.00107502937317<br />
2 => string 'get_posts' (length=9)<br />
10 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_name = 'httpdd32idau' AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC ' (length=153)<br />
1 => float 0.00149297714233<br />
2 => string 'get_posts' (length=9)<br />
11 =><br />
array<br />
0 => string 'SELECT ID, post_name, post_parent FROM wp_posts WHERE post_name = 'dd32idau' AND (post_type = 'page' OR post_type = 'attachment')' (length=129)<br />
1 => float 0.00108218193054<br />
2 => string 'get_page_by_path' (length=16)<br />
12 =><br />
array<br />
0 => string 'SELECT ID, post_name, post_parent FROM wp_posts WHERE post_name = 'dd32idau' AND (post_type = 'page' OR post_type = 'attachment')' (length=129)<br />
1 => float 0.000935077667236<br />
2 => string 'get_page_by_path' (length=16)<br />
13 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND (wp_posts.ID = '0') AND wp_posts.post_type = 'page'  ORDER BY wp_posts.post_date DESC ' (length=137)<br />
1 => float 0.000837087631226<br />
2 => string 'get_posts' (length=9)<br />

Well, Let me first say, No idea why the last case has caused 3 queries (which are near unique), But thats not the interesting part.. Notice the post_type? Its no longer set to our requested ‘custom_type‘ oops, Lets go back and check that code, Wait! I did specify it!.

Eugh. Thank you WP_Query, Of course you know better than I do, Sorry i questioned your judgement and requested something else!

Time to hook in and tell WP_Query I know best..

<br />
function stupid_post_type_custom_type($query) {<br />
if ( isset($query-&gt;query_vars['post_type']) &amp;&amp; 'custom_type' == $query-&gt;query_vars['post_type'] )<br />
$query-&gt;is_page = $query-&gt;is_single = $query-&gt;is_attchment = false;<br />
}<br />
$url = 'http://dd32.id.au/';</p>
<p>add_action('parse_query', 'stupid_post_type_custom_type', 10, 1);<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'p' => 571 ) ) );<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'page_id' => 571 ) ) );<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'name' => $url ) ) );<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'pagename' => $url ) ) );<br />
remove_action('parse_query', 'stupid_post_type_custom_type', 10, 1);<br />

WooHoo!

<br />
array<br />
0 =><br />
object(stdClass)[131]<br />
public 'ID' => string '571' (length=3)<br />
public 'post_author' => string '2' (length=1)<br />
public 'post_date' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_date_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content' => string 'DD32 is awesome!' (length=16)<br />
public 'post_title' => string 'http://dd32.id.au/' (length=18)<br />
public 'post_category' => string '0' (length=1)<br />
public 'post_excerpt' => string '' (length=0)<br />
public 'post_status' => string 'custom_status' (length=13)<br />
public 'comment_status' => string 'open' (length=4)<br />
public 'ping_status' => string 'open' (length=4)<br />
public 'post_password' => string '' (length=0)<br />
public 'post_name' => string 'httpdd32idau' (length=12)<br />
public 'to_ping' => string '' (length=0)<br />
public 'pinged' => string '' (length=0)<br />
public 'post_modified' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_modified_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content_filtered' => string '' (length=0)<br />
public 'post_parent' => string '0' (length=1)<br />
public 'guid' => string '9b159fde538e1d5b84949ae427f50168' (length=32)<br />
public 'menu_order' => string '0' (length=1)<br />
public 'post_type' => string 'custom_type' (length=11)<br />
public 'post_mime_type' => string '' (length=0)<br />
public 'comment_count' => string '0' (length=1)<br />
array<br />
0 =><br />
object(stdClass)[133]<br />
public 'ID' => string '571' (length=3)<br />
public 'post_author' => string '2' (length=1)<br />
public 'post_date' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_date_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content' => string 'DD32 is awesome!' (length=16)<br />
public 'post_title' => string 'http://dd32.id.au/' (length=18)<br />
public 'post_category' => string '0' (length=1)<br />
public 'post_excerpt' => string '' (length=0)<br />
public 'post_status' => string 'custom_status' (length=13)<br />
public 'comment_status' => string 'open' (length=4)<br />
public 'ping_status' => string 'open' (length=4)<br />
public 'post_password' => string '' (length=0)<br />
public 'post_name' => string 'httpdd32idau' (length=12)<br />
public 'to_ping' => string '' (length=0)<br />
public 'pinged' => string '' (length=0)<br />
public 'post_modified' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_modified_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content_filtered' => string '' (length=0)<br />
public 'post_parent' => string '0' (length=1)<br />
public 'guid' => string '9b159fde538e1d5b84949ae427f50168' (length=32)<br />
public 'menu_order' => string '0' (length=1)<br />
public 'post_type' => string 'custom_type' (length=11)<br />
public 'post_mime_type' => string '' (length=0)<br />
public 'comment_count' => string '0' (length=1)<br />
array<br />
0 =><br />
object(stdClass)[133]<br />
public 'ID' => string '571' (length=3)<br />
public 'post_author' => string '2' (length=1)<br />
public 'post_date' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_date_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content' => string 'DD32 is awesome!' (length=16)<br />
public 'post_title' => string 'http://dd32.id.au/' (length=18)<br />
public 'post_category' => string '0' (length=1)<br />
public 'post_excerpt' => string '' (length=0)<br />
public 'post_status' => string 'custom_status' (length=13)<br />
public 'comment_status' => string 'open' (length=4)<br />
public 'ping_status' => string 'open' (length=4)<br />
public 'post_password' => string '' (length=0)<br />
public 'post_name' => string 'httpdd32idau' (length=12)<br />
public 'to_ping' => string '' (length=0)<br />
public 'pinged' => string '' (length=0)<br />
public 'post_modified' => string '2008-11-12 16:47:06' (length=19)<br />
public 'post_modified_gmt' => string '2008-11-12 05:47:06' (length=19)<br />
public 'post_content_filtered' => string '' (length=0)<br />
public 'post_parent' => string '0' (length=1)<br />
public 'guid' => string '9b159fde538e1d5b84949ae427f50168' (length=32)<br />
public 'menu_order' => string '0' (length=1)<br />
public 'post_type' => string 'custom_type' (length=11)<br />
public 'post_mime_type' => string '' (length=0)<br />
public 'comment_count' => string '0' (length=1)<br />
array<br />
empty<br />

Wait!, Why is that last case still returning nothing?

Query time again..

<br />
8 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.ID = 571 AND wp_posts.post_type = 'custom_type'  ORDER BY wp_posts.post_date DESC ' (length=142)<br />
1 => float 0.00179696083069<br />
2 => string 'get_posts' (length=9)</p>
<p>11 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.ID = 571 AND wp_posts.post_type = 'custom_type'  ORDER BY wp_posts.post_date DESC ' (length=142)<br />
1 => float 0.000961065292358<br />
2 => string 'get_posts' (length=9)<br />
12 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_name = 'httpdd32idau' AND wp_posts.post_type = 'custom_type'  ORDER BY wp_posts.post_date DESC ' (length=160)<br />
1 => float 0.00102686882019<br />
2 => string 'get_posts' (length=9)<br />
13 =><br />
array<br />
0 => string 'SELECT ID, post_name, post_parent FROM wp_posts WHERE post_name = 'dd32idau' AND (post_type = 'page' OR post_type = 'attachment')' (length=129)<br />
1 => float 0.00131893157959<br />
2 => string 'get_page_by_path' (length=16)<br />
14 =><br />
array<br />
0 => string 'SELECT ID, post_name, post_parent FROM wp_posts WHERE post_name = 'dd32idau' AND (post_type = 'page' OR post_type = 'attachment')' (length=129)<br />
1 => float 0.00103116035461<br />
2 => string 'get_page_by_path' (length=16)<br />
15 =><br />
array<br />
0 => string ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND (wp_posts.ID = '0') AND wp_posts.post_type = 'custom_type'  ORDER BY wp_posts.post_date DESC ' (length=144)<br />
1 => float 0.00140690803528<br />
2 => string 'get_posts' (length=9)<br />

Ok, Seems using ‘pagename’ query parameter just isnt going to work, It’s been hard coded to work off ‘page’ or ‘attachment’ regardless, And when it finally does fall through to using custom_type.. It’s forgotten it was using pagename, and instead, is trying to use an ID..

Moral of the story? the parse_query hook is your friend; But make sure to only modify those queries which you’re using, and not all the core WP_Query queries too..

The working code:

<br />
function stupid_post_type_custom_type($query) {<br />
if ( isset($query->query_vars['post_type']) &amp;amp;&amp;amp; 'custom_type' == $query->query_vars['post_type'] )<br />
$query->is_page = $query->is_single = $query->is_attchment = false;<br />
}<br />
$url = 'http://dd32.id.au/';</p>
<p>add_action('parse_query', 'stupid_post_type_custom_type', 10, 1);<br />
var_dump( get_posts( array('post_type' => 'custom_type', 'post_status' => 'any', 'name' => $url ) ) );<br />
remove_action('parse_query', 'stupid_post_type_custom_type', 10, 1);<br />

EDIT: ARGH. Ok, WP/the Syntax Highlighter plugin have had a war, They dont like the idea of not touching stuff within the sourcecode shortcode.. I’m pretty sure i had a Trac ticket for that….

Calling Translators

This is a shoutout to all the plugin translators who’ve submitted a translation for Add From Server.

I’ve got version 2.0 in the works which is a complete rewrite of the previous version, which’ll hopefully get rid of a few long standing bugs, The main thing to note with this version, Is that it’ll be WordPress 2.7+ only.

I have decided to only support the latest stable branch of WordPress in my plugins, The main reason for this decision is that as someone who runs the latest trunk/nightly all year round, Its incredibly hard NOT to take advantage of new functionality in the latest versions of WordPress, As it is, I wait until the version is the latest stable before including those functions in my plugins though. The other pushing point, is that you need to keep your WordPress updated to the latest stable for security purposes, As with all applications, There are security flaws which are found all the time, Keeping up to date will greatly help keeping you and your blog safe.

Anyway, Back to the point, If you’ve submitted a translation, Please download Add From Server 2.0-alpha and correct the translations.

If you’re running WordPress 2.7, Then please give the plugin a test and submit any bugs you find to me at WordPress@dd32.id.au

Cheers all :)