【开发笔记】开发一个基于wordpress和woocommerceRest的接口插件
【开发笔记】开发一个基于wordpress和woocommerceRest的接口插件
❄️2winter近期使用ReactNative开发项目,后台用的woocommerce那一套,需要写Rest接口对接,虽然woo自带的有,问题都是服务端的,客户端调用用只读密钥还行,写就没办法了,只能自己开坑写服务端的Rest接口插件了。
目前插件已完成所需功能涉及:wp hook,wp rest,wp auth,woo hook,woo rest 等。基本的token认证到注册自定义产品类型,hook已有产品定制化流程,拦截rest数据进行二次定制等。
1.wordpress插件结构
下文以booking这个插件为例,记录一下开发要注意的地方,首先看一下插件结构。
首先你需要创建一个文件夹,名称就是你的插件名称,其次,你需要创建一个同名的PHP入口文件: omiBeaver_booking.php(后面会列出内容),如果你的插件不进行市场上架发布,那么只需要这一个必须的文件即可,如果需要上架,那么你需要多一个必须文件:readme.txt 用来在wordpress市场上发布使用。其他文件则可以根据你的项目需要自行创建,我这里是开发一个预约系统的Rest插件,其中涉及,登录授权,后台面板的定制功能,这里分了
1.Apis.php(对外Rest接口)
2.BookingInit.php(程序主类)
3.omiHooks.php(插件使用的Hook聚合类)
4.Views(定制后台用到的HTML代码)
先从入口文件看
1 |
|
可以看到Plugin name这里是与文件同名的,这里是需要与插件名称一直,其他元信息用来展示在插件管理面板,如下所示:
TIPS:这里一定要注意,头部注释一定要和插件名称文件夹一致,否则压缩打包后,安装插件会无法识别。
第一次接触wp开发的小伙伴可能一下子很难接受wp的开发模式,你会发现有很多插件都是PHP与HTML混合编程,代码里充斥着很多:
1 | <div></div> |
了解hook后,就觉得很正常了,hook就像前端写React或者Vue里的生命周期,或者安卓的activity,在(wp)系统的启动后触发一系列的回调或者预定义的方法,wp内置了非常多的hook回调,你可以在系统初始化的时候执行你的代码,在系统CURD的每个操作前后甚至中途插入你的代码,而你只需要使用🌰1:
1 | add_filter('manage_macro_booking_record_posts_columns', function ($columns) { |
示例代码修改了帖子类型在后台表格上的展示效果,这里是展示用户预约记录的表,所以需要展示用户的预约状态,我注入了一个状态变化的HTML文字,另外从数据库提取的自定义字段:预约时间在展示的时候进行了一些格式化拆分。
上述eg有一些全局方法与hook稍后会说到,仅作为开头的示例展示。
1.wordpress自定义post
有了一个hook案例,可以发现可以根据系统提供的各种hook来定制自己的wp,wp常见的hook分为两种
一种是actionHook,一种是filterHook,第一种是事件触发的时候,你可以注入你的自定义代码,他是如何执行的呢,举个🌰2:假如有个hook在某个帖子保存前需要执行你的自定义代码: save_post 这个hook,使用action的hook你需要使用add_action()方法,第一个参数是需要使用的hook,第二个是hook的回调,第三个是优先级,第四个是参数个数。比如我们想在预约记录编辑后可以自定义预约时间或者状态,在回调里,我们可以写下如下:
1 | add_action('save_post', function ($post_id, $view) { |
在Wp中,当系统收到post数据后,处理完正常逻辑后会在提交前执行指定位置预设的回调
1 | //wp 保存post逻辑xxxxx |
可想而知我们在系统HTML页面上的时候,如果需要定制页面,那么只需要使用HTML页面里预设的hook即可,所以会出现php与HTML混合情况。
默认的帖子结构是不支持我们预约表单的,我们需要定制一下自己的字段与表单类型。
1.创建自定义的帖子类型
很多时候,默认的post类型不支持我们的业务,通常来说,都是倾向于写作的的字段,而预约的产品可能有次数限制,有变体选择。如果我们使用woocommerce插件这里就直接定制好了。但是如果我们购买了产品课程后续需要预约使用,预约记录就需要我们自己定制了。
1 | add_action('init', function () { |
这里注册了一个新的post类型,预约类型。参数请参阅:wp文档直达
注册以后:
正常是没有后面几个字段的,这里需要我们的自定义字段啦,请看下面!
自定义帖子类型字段
这里需要用到Meta数据,wp预设留下了可扩展的meta类型,可以在该字段里写入新的key=>value,顶级默认是数组类型。后续取出可以使用全局方法来指定key取出,无需使用array[0]格式。根据我们预约需要自定义两个字段:booking_time,booking_status,下面是在后台表单里hook增加我们的字段
1 | add_action('admin_init', function () { |
来读代码啦,首先这里使用了一个系统事件的hook,后台初始化的时候,执行一下我们的回调,我们向系统注册了一个新的post类型。
1 | add_action('init', function () { |
接下来我们需要:
1.在编辑表单支持新的字段
booking_cus_view方法,这是我们自定义的回调,这里我们拿到了当前表格的行数据,并且可以在指定row的单元格进行定制输出,这里使用了select和时间选择器(wp有默认样式),在表单name里写入新的字段名称即可,后面你可以使用保存的hook来存储这个自定义表单,如果还记得开始的🌰2,会发现:
update_post_meta($post_id, ‘booking_time’, $_POST[‘booking_time’]);
这里就是保存的hook,因为我们使用了自定义的字段,所以需要使用meta函数来存储我们的数据。到此save完成,接下来我们完成展示。
2.在后台面板展示出来
🌰1里面使用了filter hook:manage_macro_booking_record_posts_columns,注意hook的使用规范,如果是自定义post相关的hook,你需要在hook加上你的自定义类型名称,比如本案例的
1 | macro_booking_record |
在这个hook的回调我们可以对表格的输出进行控制,隐藏或者临时新增。具体看🌰1。
2.后台表格面板自定义交互事件
在上面的面板里有个状态显示,我们如果想通过后台来更改,打开编辑过于麻烦,直接点击这个按钮触发比较合适,这里就涉及到如何绑定一个JS点击事件以及触发一个内部的ajax事件。
1.自定义后台HTML绑定JS事件(载入JS文件)
如果我们按照HTML规则来写,在:
1 | echo "<span onclick='omiJS.changeBookingStatus($post_id)' style='background:$bg;padding:4px 10px;cursor: pointer;border-radius: 5px;color: #fff'>" . (get_post_meta($post_id, 'booking_status', true) == '0' ? 'wait' : 'finish') . '</span>'; |
这里触发事件的JS怎么加载的呢,起初我是直接在次数写了一个script标签来实现js代码,结果由于这里的hook会根据row的渲染重复数次,又修改成全局只存在一个实例,总觉得不妥,最后按照wp的规范实现的载入外部文件。
1 | add_action( 'admin_enqueue_scripts', function (){ |
上面这个hook,可以在后台初始化的时候载入我们的JS代码。
1 | public static function loadJs() |
上面的代码我们可以发现几个要注意的点,首先enqueue载入我们的代码文件后,还需要使用localize实现本地化,不是语言的本地化,是向后台进行JS的配置,如基础URL与随机数(防止跨站),当然也可以在特定页面加载只需判断当前页面是否是你要加载的post type类型再执行即可。
看一下这个utils文件
1 | /** |
可以看见在ajax的参数部分加入了随机数。如果只是对某个页面修改建议在后台判断页面。我这里是写的全局一个工具对象。
3.wordpress Hook开发
到此,完成了新的post类型与表单定制,表格定制输出。那么代码写在哪呢,我在哪里写入我的hook呢。
wp提供了几个常用的全局生命周期方法,插件激活,插件禁用,在入口文件里,还记得吗与文件夹插件名称同名的那个文件,在这里会被wp执行,可以在这里写入hook,或者和我一样,自定义一个类初始化注入全局hook即可,生命周期方法不是必须!
入口文件:
bookingInit类
1 |
|
Views
1 |
|
wordpress Rest 接口开发
Apis类:后面我们看一下代码
1 |
|
Api接口wp默认有提供,我们有自己逻辑需要定义,所以这里使用的自定义接口,首先我们使用一个hook来初始化路由:
1 | //init routes. |
使用全局函数:register_rest_route来注册自定义的路由,这里需要注意生成的链接格式为:
http(s)://your_host_url/wp-json/自定义前缀/路由
API代码里面基本上很清楚,就不过多介绍了,里面使用的全局方法可以在wp文档直接找到。
woocommerce 定制接口
最后关于woocommerce定制的事情,这里我只演示一个接口作为开始吧,其他同理。
woo在wp基础上进行了深度定制,提供了非常多的hook,你可以在这里找到:woocommerce hooks
这里是提一下filter hook和action的区别,这个hook主要使用在数据获取中,下面这个🌰,使用woo的数据过滤器hook对订单查询记录进行定制,我们这里给订单新增了一个字段:booking_left,可预约次数。
1 | add_filter( 'woocommerce_rest_prepare_shop_order_object', function ($data, $post, $context){ |
woocommerceRest调用下单
有时候会发现woo的功能比较分散,比如下订单,如果使用内部方法流程很多,这个时候可以使用Rest接口直接下单:
1 | public function createOrder(): array |
woocommerce和wp一样,你可以自定义下单流程的HTML内容,当然你也可以注入JS开发,上文其实有使用一个哦,发现了吗!甚至你可以使用React来开发。
有其他疑问可以留言,我有空的时候会修正文章和回复。
本文涉及的插件 OmiBeaverBooking已开源:OmiBeaverBooking
😋 有定制wordpress插件需求的可联系 winter_986@qq.com