如何使用重写API创建基于自定义字段的下载链接

时间:2013-01-19 作者:oscarmarcelo

对我来说,这很难做到,但我想这可以由专家轻松完成。:)

假设我有一篇文章,这是一种自定义的文章类型resources, 使用以下数据:

  • Post Slug: 海滩Custom Fields:
    • dl1file: 比基尼dl1link: 资产/文件1。邮编dl1count: 56英寸dl2file: 海滩球dl2link: 资产/文件2。邮编dl2count: 31上述帖子有多个文件可下载,所有文件都存储在自定义字段中,如下所示dlNfile, 哪里N 是数字(例如:dl1file). 此外,每个文件还有两个自定义字段dlNlink (例如:dl1link) 将在URL中使用,以及dlNcount (例如:dl1count) 将存储下载计数。

      现在,使用重写API,我需要转换site.com/?resource=beach&file=bikini (或者如果更容易,site.com/resources/beach/?file=bikini) 进入site.com/download/beach/bikini.

      当单击其中一个链接时,由于我只提供了resource, 它是后段塞,并且dlNfile, WordPress现在必须知道检索哪个帖子并确定正确的dlNfile, 在这种情况下dl1file. 然后它就会知道真正的文件名存储在dl1link 然后继续下载(site.com/assets/file1.zip) 和增量dl1count 通过1。

      <小时>EDIT: 我试过了Jesper\'s tutorial 之前,但我不想创建一个新的帖子来存储下载文件信息。

      我还提供了另一个URL想法,它不必存储URL参数resource, 这是后段塞。

1 个回复
最合适的回答,由SO网友:Milo 整理而成

完成这项工作的第一步是通过query_vars 滤器我已经给它命名了wpa82328_file, 但你可以把它变成对你更有意义的东西。file 但有点通用,因此您需要在其前面加上保证唯一的前缀:

function wpa82328_query_vars( $query_vars ){
    $query_vars[] = \'wpa82328_file\';
    return $query_vars;
}
add_filter( \'query_vars\', \'wpa82328_query_vars\' );
接下来,重写规则将传入请求转换为/download/resource/file/ 从漂亮的URL到查询变量:

function wpa82328_rewrite_rule(){
    add_rewrite_rule(
        \'^download/([^/]+)/([^/]+)/?$\',
        \'index.php?resource=$matches[1]&wpa82328_file=$matches[2]\',
        \'top\'
    );
}
add_action( \'init\', \'wpa82328_rewrite_rule\' );
这将把一切都指向主index.php 设置了资源和文件名查询变量的文件。

接下来,我们必须在运行主查询和发送头之前尽早捕获这些请求。如果我们稍后尝试这样做,则标头将已经发送,下载将无法工作。

我已经钓上了parse_request 操作,其中查询变量的ref数组作为参数传递给挂钩函数。然后,我们可以轻松地检查wpa82328_file 查询var,它将告诉我们正在请求下载。阅读代码中的注释以了解每个步骤中发生的情况:

function wpa82328_parse_request( &$wp ){

    // if the wpa82328_file query var is set
    if ( array_key_exists( \'wpa82328_file\', $wp->query_vars ) ){

        // query for the requested resource
        $args = array(
            \'name\' => $wp->query_vars[\'resource\'],
            \'post_type\' => \'resource\'
        );
        $resource = new WP_Query( $args );

        // get all of the custom fields for this resource
        $custom_fields = get_post_custom( $resource->post->ID );

        // check each custom field for a value that matches the file query var
        foreach( $custom_fields as $key => $value ):

            // if a custom field value matches, we have the correct key
            if( in_array( $wp->query_vars[\'wpa82328_file\'], $value ) ){

                echo \'file key is: \' . $key;

                // increment count
                // set proper headers
                // initiate file download

                exit(); 
            }

        endforeach;
    }
    return;
}
add_action( \'parse_request\', \'wpa82328_parse_request\' );
最后一部分是从键中提取数字,以便获得正确的计数键和资产键。我个人会把它改成最后一个数字,这样做更容易substr 按键获取数字。或者更好的方法是,我将它们存储为一个数组,位于单个键下,因此一旦找到包含请求名称的索引,您只需转到下一个索引来查找计数,然后转到下一个索引来查找资产url。

结束