基于一个大数据库请求比许多小数据库请求更好的前提,我修改了自定义帖子类型“word”的WP\\u查询,并将三个表加入其中。生成的查询或多或少类似于此,并且运行良好。
SELECT wp_posts.*, verbs.*, nouns.*, definitions.*
FROM wp_posts
LEFT JOIN verbs ON ( wp_posts.ID = verbs.word_id )
LEFT JOIN nouns ON ( wp_posts.ID = nouns.word_id )
LEFT JOIN definitions ON ( wp_posts.ID = definitions.word_id )
WHERE 1=1
AND wp_posts.post_type = \'word\'
AND (wp_posts.post_status = \'publish\' OR [...] )
ORDER BY wp_posts.post_title ASC
当然,我现在对每个单词的各自定义都有重复的帖子,我将它们回滚到每个单词的一篇帖子中,并使用一组定义。
但是,由于这些结果在整个网站上以不同的方式使用,我不得不一次又一次地编写类似的逻辑。例如,在这里,我在AJAX响应中使用数据。
$query = new WP_Query( $args );
$posts = $query->get_posts();
if ( $query->post_count ) > 0 )
{
$prev_word = null;
foreach ( $posts as $key => &$row )
{
if ( !property_exists( $row, \'definitions\' ) ) $row->{\'definitions\'} = array();
$definition = array(
\'definition_id\' => $row->definition_id,
\'definition\' => $row->definition,
\'note\' => $row->note,
);
if ( is_object( $prev_word ) )
{
if ( $prev_word->post_id == $row->post_id )
{
// update the previously inserted row
$prev_word->definitions[] = $definition;
// remove the current row
unset( $row );
continue;
}
}
$row->definitions[] = $definition;
$prev_word = $row;
}
}
echo json_encode( array_values( $posts ) );
die();
我现在想做的是扩展WP\\u Query类,以便在构造时自动完成此操作。
class Words_Query extends WP_Query
{
function __construct( $args = array() )
{
$args = array_merge( $args, array(
\'post_type\' => \'word\'
) );
parent::__construct( $args );
[insert magic here?]
}
}
虽然我没有OOP方面的任何经验,但我想寻求一些帮助/指导。这样的事情可能吗?
我是否需要更新一组其他属性以反映更改。。。?例如$post\\u计数
我还需要注意什么?
谢谢
SO网友:guardiancrescent
我最终使用了the_post 钩子在设置帖子时添加定义。当然,每个帖子都需要再次访问数据库,但事实证明,处理重复条目太困难了。
function add_definitions( $post )
{
if ( \'word\' != $post->post_type ) ) return;
global $wpdb;
$query = "SELECT * FROM {$wpdb->prefix}definitions ";
$query .= "WHERE word_id = " . $post->ID;
$post->ideas = $wpdb->get_results( $query, ARRAY_A );
}
add_action( \'the_post\', \'add_definitions\' );
然而,对于那些感兴趣的人来说,下面是我如何扩展WP\\u Post类以将重复的帖子汇总到一个帖子中的。
我怀疑不推荐这种方法。
class Words_Query extends WP_Query
{
function __construct( $args = array() )
{
$args = array_merge( $args, array(
\'post_type\' => \'word\'
) );
parent::__construct( $args );
$this->posts = parent::get_posts();
if ( count( $this->posts ) > 0 )
{
$prev_word = null;
foreach ( $this->posts as $key => &$post )
{
if ( !property_exists( $post, \'definitions\' ) ) $post->{\'definitions\'} = array();
$definition = array(
\'definition_id\' => $post->definition_id,
\'definition\' => $post->definition,
\'note\' => $post->note,
);
if ( is_object( $prev_word ) )
{
if ( $prev_word->ID == $post->ID )
{
// update the previously inserted post
$prev_word->definitions[] = $definition;
// remove the current post
unset( $this->posts[$key] );
continue;
}
}
$post->definitions[] = $definition;
$prev_word = $post;
}
}
$this->posts = array_values( $this->posts );
}
var $posts = array();
}