据我所知,您的代码存在一些问题,可能会影响输出,也可能不会影响输出
在我开始之前,有几点很重要
所有代码都未经测试,需要PHP 5.4+。应首先在本地安装上测试所有代码,并将debug设置为true
我给你的是最低限度的。有些代码可以改进,所有代码都可以修改以满足您的确切需要
adverts_list
短代码
您永远不应该使用
extract()
. 就像
query_posts()
, 这是一个邪恶的函数,它可以让你在调试地狱里无所事事。
extract()
在几个版本之前从core中删除,甚至codex也进行了更新以删除它。WordPress中globals的使用已经是一团糟,然后
extract()
出现并创建更多的左右和中间。但不管怎样,我不打算详述,你应该在自己的时间阅读以下内容
并且在研究这个问题时也要做一些研究
另一个问题是使用来自属性的未初始化和未验证的值。这是一个很危险的安全漏洞,很容易被利用。
请注意,如果可以的话,应该避免使用输出缓冲从短代码返回输出。这应该是你最后的选择。而是使用返回其输出的函数对应项,而不是回显输出,并将所有内容连接到一个变量,然后返回该变量。您可以检查this post 例如。
您可能可以按如下方式重写短代码:
add_shortcode(\'adverts_list\', \'shortcode_adverts_list\');
/**
* Generates HTML for [adverts_list] shortcode
*
* @param array $atts Shorcode attributes
* @since 0.1
* @return string Fully formatted HTML for adverts list
*/
function shortcode_adverts_list( $atts ) {
wp_enqueue_style( \'adverts-frontend\' );
wp_enqueue_style( \'adverts-icons\' );
wp_enqueue_script( \'adverts-frontend\' );
// Coorect way to set attribute defaults
$attributes = shortcode_atts(
[
\'name\' => \'default\',
\'category\' => 0,
\'columns\' => 2,
\'paged\' => adverts_request("pg", 1),
\'posts_per_page\' => 20,
],
$atts
);
// Now we can set our variables and sanitize/validate
$name = filter_var( $attributes[\'name\'], FILTER_SANITIZE_STRING );
$category = filter_var( $attributes[\'category\'], FILTER_VALIDATE_INT );
$columns = filter_var( $attributes[\'columns\'], FILTER_VALIDATE_INT );
$paged = filter_var( $attributes[\'paged\'], FILTER_VALIDATE_INT );
$posts_per_page = filter_var( $attributes[\'posts_per_page\'], FILTER_VALIDATE_INT );
$query = adverts_request("query");
$location = adverts_request("location");
$meta_query = [];
if($location) {
$meta_query[] = [
\'key\' => \'adverts_location\',
\'value\' => $location,
\'compare\' => \'LIKE\'
];
}
$taxonomy = [];
if($category) {
$taxonomy = [
[
\'taxonomy\' => \'advert_category\',
\'terms\' => $category,
],
];
}
$loop = new WP_Query( [
\'post_type\' => \'advert\',
\'post_status\' => \'publish\',
\'posts_per_page\' => $posts_per_page,
\'paged\' => $paged,
\'s\' => $query,
\'meta_query\' => $meta_query,
\'tax_query\' => $taxonomy
] );
$paginate_base = get_the_permalink() . \'%_%\';
$paginate_format = stripos( $paginate_base, \'?\' ) ? \'&pg=%#%\' : \'?pg=%#%\';
// adverts/templates/list.php
ob_start();
include_once ADVERTS_PATH . \'templates/list.php\';
return ob_get_clean();
}
list.php
清除所有php垃圾邮件。只有在php和HTML之间移动时才打开和关闭php标记。当您在仍然是php的行之间移动时,使用php标记绝对没有用
值得注意的是,wp_reset_query()
应与一起使用query_posts()
, 我说过你永远不应该用它。它可能会产生意外的结果。适当的重置方法WP_Query
是wp_reset_postdata()
. 当没有帖子时,您也不想重置任何内容,因为您没有更改$post
全球的始终使用wp_reset_postdata()
在您的endwhile
和endif
声明。
为了便于调试和代码编辑器,请注意,不要使用卷曲而不是:
和endif
/endwhile
您可能可以按如下方式重写代码:
<div class="adverts-list">
<?php
if( $loop->have_posts() ) {
while ( $loop->have_posts() ) {
$loop->the_post();
include ADVERTS_PATH . \'templates/list-item.php\'
} //endwhile
wp_reset_postdata();
} else {
?>
<div class="adverts-list-empty"><em><?php _e("There are no ads matching your search criteria.", "adverts") ?></em></div>
<?php
} // endif
?>
</div>
list-item.php
唯一真正的问题是echo get_the_excerpt();
可以重写为the_excerpt()
因为这正是the_excerpt()
做
the_content
过滤不幸的是,你的短代码一团糟,而且你的短代码的使用
不能将php变量传递给短代码。您需要修改您的短代码以合并可变部分。由于这是一个插件,您不想更改插件本身。因此,最好是删除shorcode的回调函数,并用自己的回调函数替换它。
您可以使用快捷码执行以下操作:
// First, we want to remove the original callback function
remove_shortcode( \'adverts_list\', \'shortcode_adverts_list\', 11 );
// Now we add our own callback, \'custom_shortcode_adverts_list\' to the shortcode
add_shortcode( \'adverts_list\', \'custom_shortcode_adverts_list\', 12 );
/**
* Generates HTML for [adverts_list] shortcode
*
* @param array $atts Shorcode attributes
* @since 0.1
* @return string Fully formatted HTML for adverts list
*/
function custom_shortcode_adverts_list( $atts ) {
wp_enqueue_style( \'adverts-frontend\' );
wp_enqueue_style( \'adverts-icons\' );
wp_enqueue_script( \'adverts-frontend\' );
// Coorect way to set attribute defaults
$attributes = shortcode_atts(
[
\'name\' => \'default\',
\'category\' => 0,
\'columns\' => 2,
\'paged\' => adverts_request("pg", 1),
\'posts_per_page\' => 20,
],
$atts
);
// Now we can set our variables and sanitize/validate
$name = filter_var( $attributes[\'name\'], FILTER_SANITIZE_STRING );
$category = filter_var( $attributes[\'category\'], FILTER_VALIDATE_INT );
$columns = filter_var( $attributes[\'columns\'], FILTER_VALIDATE_INT );
$paged = filter_var( $attributes[\'paged\'], FILTER_VALIDATE_INT );
$posts_per_page = filter_var( $attributes[\'posts_per_page\'], FILTER_VALIDATE_INT );
$query = adverts_request("query");
$location = adverts_request("location");
$meta_query = [];
if($location) {
$meta_query[] = [
\'key\' => \'adverts_location\',
\'value\' => $location,
\'compare\' => \'LIKE\'
];
}
// We need to set $category correctly according to page
$category = ( is_tax( \'advert_category\' ) ) ? get_queried_object_id() : $category;
$taxonomy = [];
if($category) {
$taxonomy = [
[
\'taxonomy\' => \'advert_category\',
\'terms\' => $category,
],
];
}
$loop = new WP_Query( [
\'post_type\' => \'advert\',
\'post_status\' => \'publish\',
\'posts_per_page\' => $posts_per_page,
\'paged\' => $paged,
\'s\' => $query,
\'meta_query\' => $meta_query,
\'tax_query\' => $taxonomy
] );
$paginate_base = get_the_permalink() . \'%_%\';
$paginate_format = stripos( $paginate_base, \'?\' ) ? \'&pg=%#%\' : \'?pg=%#%\';
// adverts/templates/list.php
ob_start();
include_once ADVERTS_PATH . \'templates/list.php\';
return ob_get_clean();
}
我真的不知道目的是什么
$post_id = get_the_ID();
有,可能可以删除,因为我看不到它有任何用处
就DRY而言,首先检查您是否在循环中,然后返回/停止执行过滤器,这将是一个额外的好处。这节省了时间,而且速度更快
当the_content
过滤器应用于get_the_content()
在通过the_content()
. 因此,您可以简单地将短代码添加到the_content
滤器
您可以尝试以下操作:(根据需要进行调整,因为我不知道确切的用例)
add_filter( \'the_content\', function ( $content )
{
// Check if we are in the loop, if not, return
if ( !in_the_loop() )
return $content;
// If this is a single page, execute the following
if ( is_singular(\'advert\') ) {
ob_start();
include ADVERTS_PATH . \'templates/single.php\';
$content = ob_get_clean();
}
// If this is a taxonomy page, run the following
if ( is_tax( \'advert_category\' ) ) {
$content = \'[adverts_list]\';
}
return $content;
});
adverts_request()
您不应该使用未统计的值,特别是来自
$_GET
和
$_POST
变量。这是黑客用来向网站注入恶意代码的最受欢迎的地点。
ALWAYS ALWAYS 消毒和
NEVER EVER 相信任何地方的意见,甚至不要相信自己
我利用filter_input
对来自超级全局的键/值对进行santize(如果指定)和vaildate的筛选器。
另外,将值设置为参数,并确保在执行某些操作之前传递了值,以避免不必要的错误。
考虑到这一点,可以采取以下措施:
function adverts_request( $key = \'\', $default = null)
{
// Santize our $default value. I accept this is a string value, if not, adjust the filter
if ( $default !== null )
$default = filter_var( $default, FILTER_SANITIZE_STRING );
// Check if we have a value, if not return $default
if ( !$key )
return $default;
// Sanitize $key, again I accept it to be a string, adjust filter accordingly if not
$key = filter_var( $key, FILTER_SANITIZE_STRING );
// Get our value from $_POST and $_GET. Again, I accepted that $key is a string
$post_input = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
$get_input = filter_input( INPUT_GET, $key, FILTER_SANITIZE_STRING );
if( $post_input ) {
$output = $post_input;
} elseif ( $get_input ) {
$output = $get_input;
} else {
$output = $default
}
return $output
}