324 lines
No EOL
12 KiB
Markdown
324 lines
No EOL
12 KiB
Markdown
---
|
||
post_title: Developing using WooCommerce CRUD objects
|
||
sidebar_label: Using CRUD objects
|
||
|
||
---
|
||
|
||
# 使用 WooCommerce CRUD 对象进行开发
|
||
|
||
CRUD 是您可以对数据库或资源执行的四种基本操作的缩写——创建、读取、更新、删除。
|
||
|
||
[WooCommerce 3.0 引入了 CRUD 对象](https://woocommerce.wordpress.com/2016/10/27/the-new-crud-classes-in-woocommerce-2-7/)用于处理 WooCommerce 数据。**在您的代码中,应尽可能使用这些对象,而不是直接更新元数据或使用 WordPress 文章对象。**
|
||
|
||
每个对象都包含其控制数据的结构化数据(属性)、每个属性的 getter 和 setter,以及与数据存储交互的保存/删除方法。数据存储处理从数据库的实际保存/读取。对象本身无需知道数据存储在哪里。
|
||
|
||
## CRUD 的优势
|
||
|
||
* 结构 - 每个对象都有预定义的结构并保持其自身数据有效。
|
||
* 控制 - 我们控制数据流以及任何所需的验证,因此我们知道何时发生更改。
|
||
* 易于开发 - 作为开发人员,您无需了解所处理数据的内部细节,只需知道其名称。
|
||
* 抽象 - 数据可以移动到其他地方,例如自定义表,而不会影响现有代码。
|
||
* 统一 - 我们可以使用相同的代码在管理员界面、REST API 和 CLI 中更新内容。一切都是统一的。
|
||
* 简化代码 - 用于更新对象的程序性代码更少,这降低了故障可能性并增加了单元测试覆盖率。
|
||
|
||
## CRUD 对象结构
|
||
|
||
[`WC_Data`](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/abstracts/abstract-wc-data.php) 类是 CRUD 对象的基本实现,所有 CRUD 对象都继承自它。最重要的属性是 `$data`(一个包含每个对象所支持属性的数组)和 `$id`(对象的 ID)。
|
||
|
||
[优惠券对象类](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-coupon.php) 是扩展 `WC_Data` 并为所有属性添加 CRUD 函数的一个很好的例子。
|
||
|
||
### 数据
|
||
|
||
`$data` 存储属性名称和默认值:
|
||
|
||
```php
|
||
/**
|
||
* 数据数组,包含默认值。
|
||
* @since 3.0.0
|
||
* @var array
|
||
*/
|
||
protected $data = array(
|
||
'code' => '',
|
||
'amount' => 0,
|
||
'date_created' => '',
|
||
'date_modified' => '',
|
||
'discount_type' => 'fixed_cart',
|
||
'description' => '',
|
||
'date_expires' => '',
|
||
'usage_count' => 0,
|
||
'individual_use' => false,
|
||
'product_ids' => array(),
|
||
'excluded_product_ids' => array(),
|
||
'usage_limit' => 0,
|
||
'usage_limit_per_user' => 0,
|
||
'limit_usage_to_x_items' => 0,
|
||
'free_shipping' => false,
|
||
'product_categories' => array(),
|
||
'excluded_product_categories' => array(),
|
||
'exclude_sale_items' => false,
|
||
'minimum_amount' => '',
|
||
'maximum_amount' => '',
|
||
'email_restrictions' => array(),
|
||
'used_by' => array(),
|
||
);
|
||
```
|
||
|
||
### Getter 与 Setter 方法
|
||
|
||
此数组(属性)中的每个键都对应一个 getter 和 setter 方法,例如 `set_used_by()` 和 `get_used_by()`。`$data` 本身是私密的,因此必须使用 getter 和 setter 方法来访问数据。
|
||
|
||
Getter 示例:
|
||
|
||
```php
|
||
/**
|
||
* 获取所有使用过当前优惠券的用户记录。
|
||
* @since 3.0.0
|
||
* @param string $context
|
||
* @return array
|
||
*/
|
||
public function get_used_by( $context = 'view' ) {
|
||
return $this->get_prop( 'used_by', $context );
|
||
}
|
||
```
|
||
|
||
Setter 示例:
|
||
|
||
```php
|
||
/**
|
||
* 设置哪些用户使用过此优惠券。
|
||
* @since 3.0.0
|
||
* @param array $used_by
|
||
* @throws WC_Data_Exception
|
||
*/
|
||
public function set_used_by( $used_by ) {
|
||
$this->set_prop( 'used_by', array_filter( $used_by ) );
|
||
}
|
||
```
|
||
|
||
`set_prop` 和 `get_prop` 是 `WC_Data` 的一部分。它们会应用各种过滤器(基于上下文)并处理变更,因此我们可以高效地仅保存已更改的属性,而不是所有属性。
|
||
|
||
关于 `$context` 的说明:当获取用于前端或显示的数据时,使用 `view` 上下文。这会对数据应用过滤器,以便扩展可以动态更改值。在后台显示要编辑的值以及保存到数据库时,应使用 `edit` 上下文。使用 `edit` 上下文不会对数据应用任何过滤器。
|
||
|
||
### 构造函数
|
||
|
||
CRUD 对象的构造函数便于从数据库读取数据。实际的读取操作并非由 CRUD 类执行,而是由其数据存储完成。
|
||
|
||
示例:
|
||
|
||
```php
|
||
/**
|
||
* 优惠券构造函数。加载优惠券数据。
|
||
* @param mixed $data 优惠券数据、对象、ID 或代码。
|
||
*/
|
||
public function __construct( $data = '' ) {
|
||
parent::__construct( $data );
|
||
|
||
if ( $data instanceof WC_Coupon ) {
|
||
$this->set_id( absint( $data->get_id() ) );
|
||
} elseif ( is_numeric( $data ) && 'shop_coupon' === get_post_type( $data ) ) {
|
||
$this->set_id( $data );
|
||
} elseif ( ! empty( $data ) ) {
|
||
$this->set_id( wc_get_coupon_id_by_code( $data ) );
|
||
$this->set_code( $data );
|
||
} else {
|
||
$this->set_object_read( true );
|
||
}
|
||
|
||
$this->data_store = WC_Data_Store::load( 'coupon' );
|
||
if ( $this->get_id() > 0 ) {
|
||
$this->data_store->read( $this );
|
||
}
|
||
}
|
||
```
|
||
|
||
请注意它如何根据传递给对象的数据设置 ID,然后调用数据存储从数据库检索数据。一旦通过数据存储读取了数据,或者未设置 ID,就会设置 `$this->set_object_read( true );`,以便数据存储和 CRUD 对象知道它已被读取。设置此标志后,系统将开始跟踪更改。
|
||
|
||
### 保存与删除
|
||
|
||
在 CRUD 子类中,保存和删除方法是可选的,因为 `WC_Data` 父类可以处理它们。当调用 `save` 时,数据存储用于将数据保存到数据库。Delete 则从数据库中移除对象。必须调用 `save` 才能使更改持久化,否则它们将被丢弃。
|
||
|
||
`WC_Data` 中的 save 方法如下所示:
|
||
|
||
```php
|
||
/**
|
||
* Save should create or update based on object existence.
|
||
*
|
||
* @since 2.6.0
|
||
* @return int
|
||
*/
|
||
public function save() {
|
||
if ( $this->data_store ) {
|
||
// 在保存到数据库前触发操作。允许您在保存前调整对象属性。
|
||
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
|
||
|
||
if ( $this->get_id() ) {
|
||
$this->data_store->update( $this );
|
||
} else {
|
||
$this->data_store->create( $this );
|
||
}
|
||
return $this->get_id();
|
||
}
|
||
}
|
||
```
|
||
|
||
根据对象是否已有 ID,使用更新/创建。ID 将在创建后设置。
|
||
|
||
delete 方法如下:
|
||
|
||
```php
|
||
/**
|
||
* Delete an object, set the ID to 0, and return result.
|
||
*
|
||
* @since 2.6.0
|
||
* @param bool $force_delete
|
||
* @return bool result
|
||
*/
|
||
public function delete( $force_delete = false ) {
|
||
if ( $this->data_store ) {
|
||
$this->data_store->delete( $this, array( 'force_delete' => $force_delete ) );
|
||
$this->set_id( 0 );
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
```
|
||
|
||
## CRUD 用法示例
|
||
|
||
### 创建新的简单产品
|
||
|
||
```php
|
||
$product = new WC_Product_Simple();
|
||
$product->set_name( 'My Product' );
|
||
$product->set_slug( 'myproduct' );
|
||
$product->set_description( 'A new simple product' );
|
||
$product->set_regular_price( '9.50' );
|
||
$product->save();
|
||
|
||
$product_id = $product->get_id();
|
||
```
|
||
|
||
### 更新现有优惠券
|
||
|
||
```php
|
||
$coupon = new WC_Coupon( $coupon_id );
|
||
$coupon->set_discount_type( 'percent' );
|
||
$coupon->set_amount( 25.00 );
|
||
$coupon->save();
|
||
```
|
||
|
||
### 获取客户信息
|
||
|
||
```php
|
||
$customer = new WC_Customer( $user_id );
|
||
$email = $customer->get_email();
|
||
$address = $customer->get_billing_address();
|
||
$name = $customer->get_first_name() . ' ' . $customer->get_last_name();
|
||
```
|
||
|
||
### 优惠券管理
|
||
|
||
本页面用于管理优惠券。您可以查看、创建、编辑和删除优惠券。
|
||
|
||
* **新增**优惠券:点击“新增”按钮,可以创建新的优惠券。
|
||
* **编辑**优惠券:点击优惠券列表中的“编辑”按钮,可以修改现有优惠券的设置。
|
||
* **删除**优惠券:点击优惠券列表中的“删除”按钮,可以删除优惠券。
|
||
|
||
### 优惠券详情
|
||
|
||
显示单个优惠券的详细信息,包括:
|
||
|
||
* **名称 (Name)**:优惠券的名称。
|
||
* **折扣 (Discount)**:优惠券的折扣类型和金额。
|
||
* **使用 (Use)**:优惠券的使用限制,例如最小订单金额、使用次数等。
|
||
* **有效期 (Expiration Date)**:优惠券的有效期。
|
||
* **其他设置 (Other Settings)**:其他自定义设置。
|
||
|
||
### 优惠券列表
|
||
|
||
显示所有优惠券的列表,包括:
|
||
|
||
* **名称 (Name)**:优惠券的名称。
|
||
* **折扣 (Discount)**:优惠券的折扣类型和金额。
|
||
* **使用次数 (Count)**:优惠券已使用的次数。
|
||
* **状态 (Status)**:优惠券的状态,例如“有效”、“已过期”、“已禁用”。
|
||
|
||
### 批量操作
|
||
|
||
您可以对多个优惠券进行批量操作,例如:
|
||
|
||
* **删除 (Delete)**:删除选中的优惠券。
|
||
* **更新 (Updating)**:更新选中的优惠券的状态。
|
||
|
||
### 导入/导出
|
||
|
||
您可以将优惠券数据从一个系统导入到另一个系统,或者将优惠券数据导出为文件。
|
||
|
||
* **导入 (Import)**:从文件导入优惠券数据。
|
||
* **导出 (Export)**:将优惠券数据导出为文件。
|
||
|
||
### 优惠券代码
|
||
|
||
以下是一些常用的优惠券代码示例:
|
||
|
||
* `%s`:占位符,表示用户可以自定义的文本。
|
||
* `{name}`:占位符,表示客户的名称。
|
||
|
||
### 邮件通知
|
||
|
||
当客户使用优惠券时,您可以发送电子邮件通知。
|
||
|
||
* **邮件 (Mail)**:发送电子邮件通知。
|
||
* **收件人 (Address)**:收件人的电子邮件地址。
|
||
* **主题 (Subject)**:电子邮件的主题。
|
||
* **正文 (Body)**:电子邮件的正文内容。
|
||
|
||
### 账单 (Billing)
|
||
|
||
显示与优惠券相关的账单信息。
|
||
|
||
* **金额 (Amount)**:优惠券的金额。
|
||
* **百分比 (Percent)**:优惠券的百分比折扣。
|
||
* **类型 (Type)**:优惠券的类型。
|
||
|
||
### 常见问题
|
||
|
||
* **如何创建新的优惠券?**
|
||
点击“新增”按钮,填写优惠券的详细信息,然后点击“保存”按钮。
|
||
* **如何修改现有优惠券?**
|
||
点击优惠券列表中的“编辑”按钮,修改优惠券的设置,然后点击“保存”按钮。
|
||
* **如何删除优惠券?**
|
||
点击优惠券列表中的“删除”按钮,确认删除操作。
|
||
* **如何使用优惠券?**
|
||
在结账时,输入优惠券代码,系统会自动应用折扣。
|
||
* **优惠券的有效期是什么?**
|
||
优惠券的有效期由您在创建优惠券时设置。
|
||
* **如何查看优惠券的使用情况?**
|
||
在优惠券详情页面,您可以查看优惠券的使用次数和状态。
|
||
* **如何导出优惠券数据?**
|
||
点击“导出”按钮,选择导出的文件格式,然后点击“下载”按钮。
|
||
* **如何导入优惠券数据?**
|
||
点击“导入”按钮,选择要导入的文件,然后点击“上传”按钮。
|
||
|
||
### 错误信息
|
||
|
||
* `Invalid coupon code.`:优惠券代码无效。
|
||
* `Coupon has expired.`:优惠券已过期。
|
||
* `Coupon has already been used.`:优惠券已使用。
|
||
* `Minimum order amount not met.`:未达到最小订单金额。
|
||
* `Coupon cannot be applied to this product.`:该优惠券无法应用于该商品。
|
||
* `Error updating coupon.`:更新优惠券时出错。
|
||
* `Error deleting coupon.`:删除优惠券时出错。
|
||
* `Error importing coupon data.`:导入优惠券数据时出错。
|
||
* `Error exporting coupon data.`:导出优惠券数据时出错。
|
||
|
||
### 提示
|
||
|
||
* 您可以使用搜索框快速查找优惠券。
|
||
* 您可以使用分页功能浏览优惠券列表。
|
||
* 您可以使用排序功能对优惠券列表进行排序。
|
||
* 您可以使用过滤器功能筛选优惠券列表。
|
||
* 如果您在使用优惠券时遇到问题,请联系客服。
|
||
* 请定期检查和更新您的优惠券,以确保其有效性。
|
||
* 您可以创建自定义的优惠券代码,以满足您的特定需求。
|
||
* 您可以 |