Skip to content
电脑工程师入门

电脑工程师入门

create tomorrow, create happiness

  • 实用软件教程
    • Excel
    • WordPress
    • Powerpoint
    • PowerApps
    • PowerAutomateDesk
  • 计算机语言入门
    • PHP
    • Bootstrap
    • JavaScript
    • Python
    • HTML
    • WordPress
  • 咨询
  • Home
  • Wordpress
  • 开发wordpress插件(中级)
  • HOME
  • Wordpress
  • 开发wordpress插件(中级)

开发wordpress插件(中级)

Wordpress

接上一篇 《WordPress插件开发入门教程》,送上一篇中级教程。
暂且不谈什么是中级,这次我想创建一个原始的数据库(表),并使其可读可写。

创建与 postmeta 表关联的数据库

创建一个完全独立的表难度很大,所以让我们创建一个与帖子数据相关联的表(postsmeta)。
WordPress有一个叫做custom field的功能,但是它保存在一个叫做postmeta的表中,所以我们要创建一个和它相关的表。

在原始表中存储自定义字段的优点

当我们创建一个自定义字段时,我们设置了一个关键键,比如“price”或“pdf”,但这都保存在“postmeta”表的“meta_key”列中。这很好,因为它很灵活,但查询性不够好。所以我们把这个做成原来的表,把key设置到原来的列,如下图。

启用插件时创建数据库

您可以直接编辑数据库,但如果您的目标是分发,则从插件自动创建它会更方便。WordPress 对此具有有用的功能。首先我们要创建一个名为「custom-meta-table」的插件。
让我们在插件文件夹中创建一个文件夹和一个文件。「plugins」→「custom-meta-table」→「custom-meta-table.php」

创建插件骨架和构造函数。

<?php
/*
Plugin Name: Custom Meta Table
Description: 将自定义的项目值储存到自制的table里。
Author: SunnyDP
Version: 0.1
Author URI: https://www.flashyonder.com/
*/
 
class CustomMetaTable {
    //插件的名称
    var $table_name;
    public function __construct()
    {
        global $wpdb;
        // 在新建table上加前缀(wp_)
        $this->table_name = $wpdb->prefix . 'ex_meta';
        // 插件有效时,运行。
        register_activation_hook (__FILE__, array($this, 'cmt_activate'));
    }
}
$exmeta = new CustomMetaTable;

在[construct]中,我们指定了表名并编写了「register_activation_hook」挂钩。
「register_activation_hook」是一个仅在插件激活时运行的挂钩。
由于「cmt_activate」被指定为自变量,您可以使用该方法编写创建表的过程。

以下所有代码都将写在这个Class中。

function cmt_activate() {
    global $wpdb;
    //DB的版本
    $cmt_db_version = '1.0';
    //取得現在DB版本
    $installed_ver = get_option( 'cmt_meta_version' );
    // 生成新的DB版本
    if( $installed_ver != $cmt_db_version ) {
        $sql = "CREATE TABLE " . $this->table_name . " (
              meta_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
              post_id bigint(20) UNSIGNED DEFAULT '0' NOT NULL,
              item_name text,
              price int(11),
              UNIQUE KEY meta_id (meta_id)
            )
            CHARACTER SET 'utf8';";
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
        //在option中保存DB版本
        update_option('cmt_meta_version', $cmt_db_version);
    }
}

数据库版本存储在[option]表中供以后考虑。
如果“$cmt_db_version”的版本与此“选项”不同,则创建并更新数据库。
从第9行开始是实际建表的SQL语句。
在这里,我设置了[meta_id]列来保存自己的 ID,[post_id]列与帖子表相关联,[item_name]和[price]是自定义字段值。使用第 18 行的[dbDelta],它比较数据库差异并根据需要添加或更正表。
如果在此状态下激活插件,将添加一个新表,其名称为[wp_ex_meta]。

为自定义字段创建输入字段

接下来,为文章帖子创建一个自定义字段表单。

public function __construct()
{
    ・・・・・
    // 设定自定义字段
    add_action( 'add_meta_boxes', array($this, 'ex_metabox'));
}
 
function ex_metabox( $post ) {
    add_meta_box( 
        'exmeta_sectionid',
        'other_column',
        array($this, 'ex_meta_html'),
        'post'
    );
}
function ex_meta_html () {
    wp_nonce_field( plugin_basename( __FILE__ ), $this->table_name );
    global $post;
    global $wpdb;
 
    $get_meta = $wpdb->get_results(
        $wpdb->prepare( "SELECT * FROM
            ".$this->table_name. " WHERE
            post_id = %d", $post->ID
        )
    );
    $get_meta = isset($get_meta[0]) ? $get_meta[0] : null;
    $item_name = isset($get_meta->item_name) ? $get_meta->item_name : null;
    $price = isset($get_meta->price) ? $get_meta->price : null;
    ?>
    <div>
    <table>
        <tr>
            <th>商品名称</th>
            <td><input name="item_name" value="<?php echo $item_name ?>" /></td>
        </tr>
        <tr>
            <th>价格</th>
            <td><input name="price" value="<?php echo $price ?>" /></td>
        </tr>
    </table>
    </div>
    <?php
}

[construct]函数添加一个名为[add_meta_boxes]的动作挂钩。
在[ex_metabox]中,指定自定义字段的部分名称,和要显示的帖子类型。
在[ex_meta_html]中,描述要显示的表单。
这部分将在编辑屏幕和新帖子上显示相同的内容,因此如果数据库中有数据,它将读取数据并显示它。

保存记录

public function __construct()
{
    ・・・・・
    add_action ('save_post', array($this, 'save_meta'));
}
function save_meta($post_id) {
    if (!isset($_POST[$this->table_name])) return; 
 
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )  return;
    if ( !wp_verify_nonce( $_POST[$this->table_name], plugin_basename( __FILE__ ) ) )  return;
 
    global $wpdb;
    global $post;
 
    //不保存重复版本
    if ($post->ID != $post_id) return;
 
    $temp_item_name = isset($_POST['item_name']) ? $_POST['item_name'] : null;
    $temp_price = isset($_POST['price']) ? $_POST['price'] : null;
 
    //保存到Array中
    $set_arr = array(
        'item_name' => $temp_item_name,
        'price' => $temp_price
        );
 
    $get_id = $wpdb->get_var(
                $wpdb->prepare( "SELECT post_id FROM
                    ". $this->table_name ." WHERE 
                    post_id = %d", $post_id)
    );
    //如果没有record添加record,如果有record,更新。
    if ($get_id) {
        $wpdb->update( $this->table_name, $set_arr, array('post_id' => $post_id));
    } else {
        $set_arr['post_id'] = $post_id;
        $wpdb->insert( $this->table_name, $set_arr);
    }
    $wpdb->show_errors();
}

保存过程要启用挂钩,操作[save_post]。使用[$wpdb->update]更新数据,使用[$wpdb->insert]等方法保存新数据,所以我们在上一行中确认是否有数据库记录 。
第16行返回,如果是修改则不离开。

删除记录

删除帖子时,还应删除自定义字段值。

public function __construct()
{
    ・・・・・
    add_action ('delete_post', array($this, 'dalete_meta'));
}
function dalete_meta($post_id) {
    global $wpdb;
    $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE post_id = %d", $post_id) );
}

保存过程挂钩到操作[delete_post]。
有专门的保存方法,但删除可能没有,所以使用MySQL的DELETE命令。

在模板中显示

现在我们已经创建了管理屏幕的“创建”、“更新”和“删除”部分,让我们创建在模板中显示它们的方法。

function get_meta($post_id) {
    if (!is_numeric($post_id)) return;
    global $wpdb;
    $get_meta = $wpdb->get_results(
        $wpdb->prepare( "SELECT * FROM
            ".$this->table_name. " WHERE
            post_id = %d", $post_id
        )
    );
    return isset($get_meta[0]) ? $get_meta[0] : null;
}

当[$post_id]作为参数传递时,这将返回自定义字段的值作为对象。
例如,如果你想用[single.php]来显示,它会是这样的。

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php the_content(); ?>
<h4>自定义字段</h4>
<?php
$get_meta = $exmeta->get_meta($post->ID);
$item_name = isset($get_meta->item_name) ? $get_meta->item_name : null;
$price = isset($get_meta->price) ? $get_meta->price : null;
echo esc_html($item_name );
echo esc_html($price);
?>
<?php endwhile; else: ?>
    <p>没有文章</p>
<?php endif; ?>

反过来也有欠缺的部分,但是我觉得整体的流程是这样的。整个代码发布如下。

<?php
/*
Plugin Name: Custom Meta Table
Plugin URI: http://www.flashyonder.com
Description:自定义的字段值保存到自制的table里
Author: SunnyDP
Version: 0.1
Author URI: http://www.flashyonder.com
*/
class CustomMetaTable {
  //插件的Table名称
  var $table_name;

  public function __construct()
  {
    global $wpdb;
    // 制作table的开头添加(wp_)
    $this->table_name = $wpdb->prefix . 'ex_meta';
    // 在插件有效时,运行
    register_activation_hook (__FILE__, array($this, 'cmt_activate'));
    // 制作自定义字段
    add_action( 'add_meta_boxes', array($this, 'ex_metabox'));
    add_action ('save_post', array($this, 'save_meta'));
    add_action ('delete_post', array($this, 'dalete_meta'));
  }

  function cmt_activate() {
    global $wpdb;

    $cmt_db_version = '1.0';
    $installed_ver = get_option( 'cmt_meta_version' );
      // 如果table的版本不一样,执行以下程序。
      if( $installed_ver != $cmt_db_version ) {
        $sql = "CREATE TABLE " . $this->table_name . " (
          meta_id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
          post_id bigint(20) UNSIGNED DEFAULT '0' NOT NULL,
          item_name text,
          price int(11),
          UNIQUE KEY meta_id (meta_id)
        )
        CHARACTER SET 'utf8';";
      require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
      dbDelta($sql);
      update_option('cmt_meta_version', $cmt_db_version);
      }
  }

  function ex_metabox( $post ) {
    add_meta_box( 
      'exmeta_sectionid',
      'Other_Items',
      array($this, 'ex_meta_html'),
      'post'
    );
  }
  function ex_meta_html () {
    wp_nonce_field( plugin_basename( __FILE__ ), $this->table_name );
    global $post;
    global $wpdb;

    $get_meta = $wpdb->get_results(
      $wpdb->prepare( "SELECT * FROM
        ".$this->table_name. " WHERE
        post_id = %d", $post->ID
      )
    );
    $get_meta = isset($get_meta[0]) ? $get_meta[0] : null;
    $item_name = isset($get_meta->item_name) ? $get_meta->item_name : null;
    $price = isset($get_meta->price) ? $get_meta->price : null;
    ?>
    <div>
    <table>
      <tr>
        <th>商品名称</th>
        <td><input name="item_name" value="<?php echo $item_name ?>" /></td>
      </tr>
      <tr>
        <th>价格</th>
        <td><input name="price" value="<?php echo $price ?>" /></td>
      </tr>
    </table>
    </div>
    <?php
  }

  function save_meta($post_id) {
    if (!isset($_POST[$this->table_name])) return; 
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )  return;
      if ( !wp_verify_nonce( $_POST[$this->table_name], plugin_basename( __FILE__ ) ) )  return;

    global $wpdb;
    global $post;

    //不留下重复的版本
    if ($post->ID != $post_id) return;

    $temp_item_name = isset($_POST['item_name']) ? $_POST['item_name'] : null;
    $temp_price = isset($_POST['price']) ? $_POST['price'] : null;

    //为了保存,制作Array
    $set_arr = array(
      'item_name' => $temp_item_name,
      'price' => $temp_price
      );

    $get_id = $wpdb->get_var(
                $wpdb->prepare( "SELECT post_id FROM
                  ". $this->table_name ." WHERE 
                  post_id = %d", $post_id)
    );
    //如果没有Record,追加,如果有record,更新。
    if ($get_id) {
      $wpdb->update( $this->table_name, $set_arr, array('post_id' => $post_id));
    } else {
      $set_arr['post_id'] = $post_id;
      $wpdb->insert( $this->table_name, $set_arr);
    }
    $wpdb->show_errors();
  }

  function dalete_meta($post_id) {
    global $wpdb;
    $wpdb->query( $wpdb->prepare( "DELETE FROM $this->table_name WHERE post_id = %d", $post_id) );
  }

  function get_meta($post_id) {
    if (!is_numeric($post_id)) return;
    global $wpdb;
    $get_meta = $wpdb->get_results(
      $wpdb->prepare( "SELECT * FROM
        ".$this->table_name. " WHERE
        post_id = %d", $post_id
      )
    );
    return isset($get_meta[0]) ? $get_meta[0] : null;
  }
}
$exmeta = new CustomMetaTable;
标签:Wordpress

文章导航

❮ Previous Post: 开发WordPress 插件(初学者)
Next Post: 第一节 PowerApps的函数讲解搜索部分匹配 ❯

关联内容

Wordpress
操作简介:禁用评论
Wordpress
single.php 和 page.php 之间的区别
Wordpress
如何制作自己的面包屑
Wordpress
[图像的蓬松显示] Easy FancyBox的使用和设置方法
Wordpress
在 WinSCP 中显示隐藏文件
Wordpress
如果 WordPress 中没有 .htaccess 文件怎么办

实用软件教程

  • Powerpoint
  • Excel
  • PowerAutomateDesk
  • Wordpress
  • Powerapps

编程语言入门

  • JavaScript
  • HTML
  • PHP
  • Python
  • Bootstrap

Copy right by flashyonder.com