分类
WordPress

wordpress 实现文件下载功能

本想这个功能应该不难,但却费了好些工夫。

在wordpress中想要实现点击下载,有两种方法:

 1、在下载链接上增加download=""属性

<a href="<?php echo $download_url; ?>" download="">下载</a>

但是这种方法查资料发现,只支持chrome和firefox,兼容性不好。

2、第二种方法也是费了好大劲才查找到的资料,直接上代码

<?php
// add the download ID query var which we'll set in the rewrite rule
function wpd_query_var($query_vars) {
    $query_vars[] = 'download_id';
    return $query_vars;
}
add_filter('query_vars', 'wpd_query_var');

// add rewrite rule
function wpd_rewrite() {
    add_rewrite_rule(
        'download/([0-9]+)/?$',
        'index.php?download_id=$matches[1]',
        'top'
    );
}
add_action('init', 'wpd_rewrite');

// check for download_id and output the file
function wpd_request($wp) {
    if (array_key_exists('download_id', $wp->query_vars)) {
        // 在此实现下载代码的书写
        // output your headers and file here
        // ID is in $wp->query_vars['download_id']
        // then exit to halt any further execution
        $download_id = $wp->query_vars['download_id'];
        $filename =  get_attached_file($download_id);
        if (file_exists($filename)) {
            include get_template_directory() . '/inc/download.php';
            downloadFile($filename);
        } else {
            wp_die(__('要下载的文件不存在!'));
        }
    }
}
add_action('parse_query', 'wpd_request');

下载时,引用了一个inc目录下的download.php,代码如下:

<?php
/**
 * @param $filePath //下载文件的路径
 * @param int $readBuffer //分段下载 每次下载的字节数 默认1024bytes
 * @param array $allowExt //允许下载的文件类型
 * @return void
 */
function downloadFile($filePath, $readBuffer = 1024, $allowExt = ['jpeg', 'jpg', 'peg', 'gif', 'zip', 'rar', 'txt', 'pdf']) {
    //检测下载文件是否存在 并且可读
    if (!is_file($filePath) && !is_readable($filePath)) {
        return false;
    }

    //检测文件类型是否允许下载
    $ext = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
    if (!in_array($ext, $allowExt)) {
        return false;
    }

    //设置头信息
    //声明浏览器输出的是字节流
    header('Content-Type: application/octet-stream');

    //声明浏览器返回大小是按字节进行计算
    header('Accept-Ranges:bytes');

    //告诉浏览器文件的总大小
    $fileSize = filesize($filePath); //坑 filesize 如果超过2G 低版本php会返回负数
    header('Content-Length:' . $fileSize); //注意是'Content-Length:' 非Accept-Length

    header('Content-Disposition:attachment;filename=' . basename($filePath)); //声明作为附件处理和下载后文件的名称

    //获取文件内容
    $handle = fopen($filePath, 'rb'); //二进制文件用‘rb’模式读取
    while (!feof($handle)) { //循环到文件末尾 规定每次读取(向浏览器输出为$readBuffer设置的字节数)
        echo fread($handle, $readBuffer);
    }
    fclose($handle); //关闭文件句柄
    exit;
}

这样,下载链接只要按如下写法即可实现下载:

<a href="/download/<?php echo $ids[$i]; ?>">点击下载</a>

$ids[$i] 表示 wordpress 附件的 id。

分类
WordPress

wordpress 自定义文章类型文章列表显示分类列

只需要在register_taxonomy函数的第三个参数中,添加show_admin_column=>true即可。代码如下:

<?php

/**
 * 为产品 post type 添加分类功能
 */
add_action('init', 'my_taxonomies_product', 0);
function my_taxonomies_product() {
    $labels = array(
        'name'              => _x('产品分类', 'taxonomy 名称'),
        'singular_name'     => _x('产品分类', 'taxonomy 单数名称'),
        'search_items'      => __('搜索产品分类'),
        'all_items'         => __('所有产品分类'),
        'parent_item'       => __('该产品分类的上级分类'),
        'parent_item_colon' => __('该产品分类的上级分类:'),
        'edit_item'         => __('编辑产品分类'),
        'update_item'       => __('更新产品分类'),
        'add_new_item'      => __('添加新的产品分类'),
        'new_item_name'     => __('新产品分类'),
        'menu_name'         => __('产品分类'),
    );
    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'show_admin_column' => true,
    );
    register_taxonomy('product_category', 'product', $args);
}

如果要在列表中添加自定义字段,即wp_postmeta表中的字段(通过meta_box添加的),可以使用下面的代码:

<?php
// 在列表中把加的字段显示出来
add_action("manage_posts_custom_column",  "product_custom_columns");
function product_custom_columns($column) {
    global $post;
    switch ($column) {
        case "product_director":
            echo get_post_meta($post->ID, '_product_director', true);
            break;
    }
}

add_filter("manage_edit-product_columns", "movie_edit_columns");
function movie_edit_columns($columns) {
    $columns['product_director'] = '产品分类';
    return $columns;
}
分类
WordPress

wordpress 自定义文章类型添加分类筛选功能

想实现的效果如下图:

自定义文章类型添加分类筛选功能

代码如下:

<?php
add_action('restrict_manage_posts', 'product_type_filter');
function product_type_filter() {
    global $typenow;
    $post_type = 'product'; // 发布类型
    $taxonomy = 'product_category'; // 该类型对应的分类法
    if ($typenow == $post_type) {
        $selected = isset($_GET[$taxonomy]) ? $_GET[$taxonomy] : '';
        $info_taxonomy = get_taxonomy($taxonomy);
        wp_dropdown_categories(array(
            'show_option_all' => __("所有{$info_taxonomy->label}"),
            'taxonomy' => $taxonomy,
            'name' => $taxonomy,
            'orderby' => 'name',
            'selected' => $selected,
            'value_field' => 'slug',
            'show_count' => true,
            'hide_empty' => true,
        ));
    };
}
分类
WordPress

wordpress 自定义文章类型的固定链接

自定义文章类型无法在后台设置固定链接格式,可以在 functions.php 中通过代码来实现。代码如下:

<?php
/**
 * 实现 solution 文章类型的 URL 重写
 */
add_filter('post_type_link', 'custom_solution_link', 1, 3);
function custom_solution_link($link, $post) {
    if ($post->post_type == 'solution') {
        return home_url('solution/' . $post->ID . '.html');
    } else {
        return $link;
    }
}

add_action('init', 'custom_solution_rewrites_init');
function custom_solution_rewrites_init() {
    add_rewrite_rule(
        'solution/([0-9]+)?.html$',
        'index.php?post_type=solution&p=$matches[1]',
        'top'
    );
}

比较重要的一点:

代码添加完成后,一定要在后台 “ 固定链接设置” 页面,点击一下 “保存更改” 按钮才能生效!!

分类
WordPress

使用PHP内置服务器运行wordpress造成的404问题

使用内置服务器时,无法把请求转到发 index.php 。可以通过新加一个 routing.php 文件来实现该功能。

运行 wordpress 时使用如下命令:

php -S localhost:80 routing.php

routing.php 文件的内容如下:

<?php
$root = $_SERVER['DOCUMENT_ROOT'];
$path = '/'. ltrim( parse_url( urldecode( $_SERVER['REQUEST_URI'] ) )['path'], '/' );

if ( file_exists( $root.$path ) ) {

    // Enforces trailing slash, keeping links tidy in the admin
    if ( is_dir( $root.$path ) && substr( $path, -1 ) !== '/' ) {
        header( "Location: $path/" );
        exit;
    }

    // Runs PHP file if it exists
    if ( strpos( $path, '.php' ) !== false ) {
        chdir( dirname( $root.$path ) );
        require_once $root.$path;
    } else {
        return false;
    }
} else {

    // Otherwise, run `index.php`
    chdir( $root );
    require_once 'index.php';
}

参考:

https://old.romaricpascal.is/writing-about/running-worpdress-with-php-built-in-server/

分类
WordPress

wordpress 获取文章内的第一张图片

<?php
// 获取文章第一张图片
function catch_that_image() {
    global $post, $posts;
    $first_img = '';
    ob_start();
    ob_end_clean();
    $output = preg_match_all('/<img.+?src=[\'"]([^\'"]+)[\'"].*?>/i', $post->post_content, $matches);
    if ($output) {
        $first_img = $matches[1][0];
    }

    if (empty($first_img)) {
        $first_img = bloginfo('template_url') . "/assets/images/default_image.jpeg";
    }
    return $first_img;
}
分类
WordPress

wordpress 获取某分类下的文章列表

可以直接使用 WP_Query 函数进行查询,代码如下:

<?php
$query = new WP_Query([
    'post_type' => 'product',
    'posts_per_page' => 999,
    'order' => 'ASC',
    'tax_query' => [
        [
            'taxonomy' => 'product_category',
            'field' => 'term_id',
            'terms' => $sub->term_id,
        ]
    ],
]);

if ($query->have_posts()) :
    while ($query->have_posts()) :
        $query->the_post();
?>

        <a href="<?php the_permalink() ?>"><?php the_title() ?></a>

<?php
    endwhile;
endif;
wp_reset_query();
?>

除了使用 WP_Query 方法外,还可以使用 query_posts 函数,如下:

<?php
$paged = 1;
if (get_query_var('page')) {
    $paged = get_query_var('page');
}
query_posts(array(
    'post_type'      => 'case',  // post type
    'paged'          => $paged,  // 当前是第几页
    'posts_per_page' => 9        // 每页几条
));
while (have_posts()) :
    the_post();
?>
    <a href="<?php the_permalink() ?>"> <?php the_title() ?> </a>
<?php endwhile; ?>

查询wordpress自带的默认文章类型(post):

<?php
query_posts(array(
    'category_name' => 'news', // 分类slug
    'posts_per_page' => 6, // 查询几条
));
while (have_posts()) :
    the_post();
?>
    <a href="<?php the_permalink() ?>"> <?php the_title() ?> </a>
<?php endwhile; ?>

该查询默认是按发布时间倒序排序

分类
WordPress

wordpress 查询多少天内发布的文章

该功能通过添加一个posts_where过滤器来完成:

<?php
function filter_where($where = '') {
    $where .= " AND post_date > '" . date('Y-m-d', strtotime('-60 days')) . "'";
    return $where;
}
add_filter('posts_where', 'filter_where');
query_posts($query_string);
?>

默认是60天内的文章,可更根据需要调整。

将代码添加到主循环的上面。

项目中的具体代码如下:

<?php
// 查询多少天内的文章
if (isset($_GET['arttime'])) {
    function filter_where($where = '') {
        $arttime = $_GET['arttime'];
        $where .= " AND post_date > '" . date('Y-m-d', strtotime('-' . $arttime . 'days')) . "'";
        return $where;
    }
    add_filter('posts_where', 'filter_where');
}

$paged = 1;
if (get_query_var('page')) {
    $paged = get_query_var('page');
}
$term = get_queried_object();
query_posts(array(
    'category_name'     => $term->slug, // 分类slug
    'posts_per_page'    => 10, // 每页几条
    'paged'             => $paged,  // 当前是第几页
));
while (have_posts()) :
    the_post();
?>
    <a href="<?php the_permalink() ?>" class="news-item">
        <div class="left-newlist-left">
            <span> <?php single_cat_title() ?> <i></i><?php echo get_the_date('Y-m-d'); ?></span>
            <h1><?php the_title() ?></h1>

        </div>
        <div class="right-newlist-img">
            <img src="<?php echo catch_that_image(); ?>" alt="">
        </div>
    </a>
<?php endwhile; ?>

参考链接:https://www.xingkongweb.com/9851.html

分类
Mariadb

mariadb 配置远程访问

执行命令:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

编辑:vi /etc/mysql/mariadb.conf.d/50-server.cnf

注释掉下面的行(在前面加#)

# bind-address            = 127.0.0.1

最后重启服务

systemctl restart mysql

如果找不到该配置在哪个文件里面,可以通过如下命令进行查找:

 grep -r "bind-address" /etc/mysql/*
分类
Debian

debian 11 安装 postfix

为了能让 WordPress 发送通知邮件,需要在服务器上配置MTA(Mail Transfer Agent),常见的MTA服务有 Sendmail、Postfix 等。

Sendmail 是 Unix 系统的标准邮件传输代理,而 Postfix 邮件服务器安全性更好一些。

这里我们选择的是 Postfix,用来为 WordPress 提供仅发送服务。

安装

通过如下命令安装 Postfix

apt install postfix

安装过程中,会出现配置界面。如果已安装,可以使用 dpkg-reconfigure postfix 重新打开该界面。

如下图,我们将选择 Internet Site 并按回车。

配置 postfix 类型

对于系统邮件名称,我们将使用我们网站的域名,对于本站,就是 wujie.me 。

配置 postfix 系统邮件名称

这两步配置完后,等待安装完成,WordPress 就可以发送通知邮件了。

其它配置

如果想对 Postfix 进行更详细的配置,可以配置文件 /etc/postfix/main.cf。

例如为了增强安全性,需要把 SMTP 服务改为只允许本地使用,那么可以把 inet_interfaces = all 改成 inet_interfaces = loopback-only,如下图所示:

postfix 配置为只允许本地使用 SMTP 服务

改完之后,需要重启 postfix 服务:

systemctl restart postfix