Thứ Ba, 2 tháng 11, 2021

thumbnail

Sử dụng Hướng đối tượng (OOP) trong WordPress

 Chắc hẳn bạn đã từng nghe Lập Trình Hướng Đối Tượng OOP trong PHP rồi chứ? Trong bài viết này tôi không nói chi tiết về OOP nữa, bạn có thể tham khảo trên anh Gồ giúp mình nhé.

Trọng tâm bài viết hôm nay tôi sẽ giúp bạn truy xuất dữ liệu bất kì của table nào trong database WordPress thông qua các Class một cách đơn giản nhất. Và đặc biệt “Rất dễ hiểu” 🙂

Sử dụng Hướng đối tượng (OOP) trong WordPress

Danh sách các bảng WordPress

 

Sử dụng Hướng đối tượng (OOP) trong WordPress

Cấu trúc các cột của Bảng chứa danh sách Posts của WordPress.

Nhiệm vụ của chúng ta là kết nối với các bảng và lấy dữ liệu của các dòng (row), cột (column) để sử dụng.

Let’s go

1. Bước chuẩn bị

Trước tiên bạn tạo cho tôi thư mục chứa các Class trong thư mục theme bạn đang sửa dụng, trong ví dụ này tôi đang dùng theme wpshare247.lp và cấu trúc thư mục của tôi là:

code\wp-content\themes\wpshare247.lp\dev\classes

Sử dụng Hướng đối tượng (OOP) trong WordPress

1.1 Tạo file thư viện W_SQLMaster.php

Tiếp theo tại thư mục này, bạn tạo cho tôi 1 file php có tên bất kì, ví dụ tôi tạo file với tên: W_SQLMaster.php dùng để truy vấn đến cơ sở dữ liệu thông qua $wpdb của WordPress. File này có cấu trúc như sau:

code\wp-content\themes\wpshare247.lp\dev\classes\W_SQLMaster.php

<?php
if( !class_exists('W_SQLMaster') ):
class W_SQLMaster {
const TABLE = 'null';
const ID = 'null';
private $_data = array();
//__construct
public function __construct($id = NULL) {
if($id){
$class = get_called_class();
$table = $class::TABLE;
$ID = $class::ID;
global $wpdb;
$sql = "SELECT *
FROM `".$table."`
WHERE `".$ID."` = '".$id."' ";
$rows = $wpdb->get_results($sql,ARRAY_A);
if($rows[0]){
foreach($rows[0] as $k=>$val){
$this->$k = $val;
}
}
}
}
// Giải phóng 1 đối tượng
public function unset_me(){
$properties = $this->__getAllProperties();
if($properties){
foreach($properties as $key){
$this->$key = '';
}
}
return $this;
}
// Lấy tên Class của đối tượng
public function getClass(){
return get_called_class();
}
// Lấy Id của đối tượng ( cụ thể là cột ID )
public function getId(){
$id = $this->getIDCol();
return $this->$id;
}
// Lấy tên cột ID của bảng đối tượng. Mỗi bảng có cột ID khác nhau, ví dụ: ID, id, .....
public function getIDCol(){
$class = $this->getClass();
$ID = $class::ID;
return $ID;
}
// Lấy tên table của đối tượng
public function getTable(){
$class = $this->getClass();
$table = $class::TABLE;
return $table;
}
// Tạo mới (new object) thông qua cột và giá trị của cột
public function get_instance_by_field($field, $val){
global $wpdb;
$class = get_called_class();
$table = $class::TABLE;
$id_col = $class::ID;
$sql = "SELECT `".$id_col."`
FROM `".$table."`
WHERE `".$field."` = '".$val."'
LIMIT 0,1
";
$id = $wpdb->get_var($sql);
if($id){
$obj = new $class($id);
return $obj;
}
return NULL;
}
/**
** Lấy tất cả các thuộc tính của đối tượng
**/
public function __getAllProperties(){
return array_keys($this->_data);
}
/**
** Thay đổi giá trị (Setter)
**/
public function __set ($key, $value) {
if (is_object($value)) {
$this->_data[$key] = $value;
} else {
$this->_data[$key] = addslashes($value);
}
}
/**
** Lấy giá trị của thuộc tính bất kì của đối tượng
**/
public function __get($property) {
switch ($property) {
default :
if (array_key_exists ( $property, $this->_data )) {
if (is_object ( $this->_data [$property] ))
return $this->_data [$property];
return stripslashes ( htmlspecialchars_decode ( $this->_data [$property], ENT_NOQUOTES ) );
}
return null;
break;
}
}
// Lấy dữ liệu của một đối tượng
public function getData(){
$aData = array();
$properties = $this->__getAllProperties();
if($properties){
foreach($properties as $key){
$val = $this->__get($key);
if($key=='created' && $val=='' || $key=='edited' && $val==''){
$aData[$key] = current_time('Y-m-d H:i:s', 0);
}else{
$aData[$key] = $val;
}
}
}
return $aData;
}
// Thêm
public function save(){
global $wpdb;
$class = get_called_class();
$table = $class::TABLE;
$aData = $this->getData();
$bool = $wpdb->insert($table, $aData);
if($bool){
$lastid = $wpdb->insert_id;
$objClass = new $class($lastid);
}
return $objClass;
}
// Sửa
public function update(){
global $wpdb;
$class = get_called_class();
$table = $class::TABLE;
$id = $class::ID;
$aData = $this->getData();
$bool = $wpdb->update($table, $aData, array('id'=>$this->$id));
if($bool){
$lastid = $wpdb->insert_id;
$objClass = new $class($lastid);
}
return $objClass;
}
// Xóa
public function delete(){
global $wpdb;
$class = get_called_class();
$table = $class::TABLE;
$id = $class::ID;
return $wpdb->delete( $table, array('id'=>$this->$id));
}
//End Class
}
endif;

1.2 Tạo file chứa hướng đối tượng (Class) OOP

Trong danh sách bất kì table nào của WordPress bạn cũng có thể tạo Class cho nó. Tôi sẽ ví dụ với table wp_posts ( là bảng chứa các post – page hoặc custom post type ). Chú ý prefix wp_, không phải lúc nào các bảng wordpress cũng là prefix này, bạn hãy kiểm tra trong file wp-config.php tại thư mục code để biết chính xác nhé.

wp_commentmeta
wp_comments
wp_links
wp_options
wp_postmeta
wp_posts
wp_termmeta
wp_terms
wp_term_relationships
wp_term_taxonomy
wp_usermeta

Sử dụng Hướng đối tượng (OOP) trong WordPress

Ví dụ Tôi sẽ đặt tên file Class cho wp_posts là: WpShare247_Wp_Posts.php tại thư mục code\wp-content\themes\wpshare247.lp\dev\classes

Sử dụng Hướng đối tượng (OOP) trong WordPress

 

Nội dung file OOP này như sau:

<?php
if( !class_exists('WpShare247_Wp_Posts') ):
class WpShare247_Wp_Posts extends W_SQLMaster{
const TABLE = 'wp_posts'; // Một trong các bảng tồn tại trong db wordpress
const ID = 'ID'; // ID là tên cột khóa chính của bảng trên
//constructor
public function __construct($id) {
parent::__construct($id);
}
/*Các hàm Function (Method) của Class viết tại đây */
//End Class--------------------------------------------------------------------------------------------
}
endif;

Cách khai báo:

  • const TABLE = ‘wp_posts’;  wp_posts là tên bảng trong database WordPress.
  • const ID = ‘ID’; ID là cột khóa chính trong bảng wp_posts

Sử dụng Hướng đối tượng (OOP) trong WordPress

Đến đây mọi thứ đã chuẩn bị gần như hoàn chỉnh. Hãy chuyển sang bước 2 để bắt đầu sử dụng nhé.

2. Gọi thư viện Class vào Theme WordPress

Để gọi thư viện, bạn hãy mở file functions.php và thêm đoạn code sau vào:

require_once get_parent_theme_file_path( '/dev/classes/W_SQLMaster.php' );
require_once get_parent_theme_file_path( '/dev/classes/WpShare247_Wp_Posts.php' );

3. Cách sử dụng

Để sử dụng được hướng đối tượng OOP vừa khai báo trên. Bạn hãy vào template single.php trong thư mục theme đang sử dụng. Nếu chưa có thì hãy tạo file này nhé. Single.php là template hiển thị nội dung chi tiết của 1 bài post trong WordPress.

Sử dụng Hướng đối tượng (OOP) trong WordPress

Nội dung file single.php

<?php
get_header(); ?>
<main class="content">
<div class="content-block">
<?php
while ( have_posts() ) : the_post();
$post_id = get_the_ID();
//Tạo mới đối tượng thông qua id
$WpShare247_Wp_Posts = new WpShare247_Wp_Posts( $post_id );
endwhile; // End of the loop.
?>
</div>
</main>
<?php get_footer();

Tại đây, sau khi New WpShare247_Wp_Posts, lúc này bạn có thể lấy bất kì dữ liệu cột nào của bảng wp_posts ngay tại dòng có ID =  get_the_ID() như đoạn code trên.

3.1 Truy xuất dữ liệu có sẵn của table wp_posts qua đối tượng.

<?php
get_header(); ?>
<main class="content">
<div class="content-block">
<?php
while ( have_posts() ) : the_post();
$post_id = get_the_ID();
//Tạo mới đối tượng thông qua id
$WpShare247_Wp_Posts = new WpShare247_Wp_Posts( $post_id );
//Truy xuất vào dữ liệu ngay dòng có ID là $post_id
?>
<ul class="data-post-single">
<li><?php echo $WpShare247_Wp_Posts->ID; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_author; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_title; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_content; ?></li>
<!-- Tiếp tục lấy dữ liệu các cột khác $WpShare247_Wp_Posts->column_name; ......-->
</ul>
<?php
endwhile; // End of the loop.
?>
</div>
</main>
<?php get_footer();

Bạn cũng có thể lấy bất kì dữ liệu cột nào có trong bảng wp_posts

Sử dụng Hướng đối tượng (OOP) trong WordPress

echo $WpShare247_Wp_Posts->column_name; // với column_name là tên cột

3.2 Sử dụng phương thức Method của hướng đối tượng trong WordPress.

Bạn cũng có thể sử dụng hoặc khai báo thêm nhiều method mới cho Class như sau:

Sử dụng hàm có sẵn của thư viện để lấy ID của Object 

echo 'ID của bài viết là: ' . $WpShare247_Wp_Posts->getId();

Cụ thể xem tại dòng //Gọi hàm của Object

<?php
get_header(); ?>
<main class="content">
<div class="content-block">
<?php
while ( have_posts() ) : the_post();
$post_id = get_the_ID();
//Tạo mới đối tượng thông qua id
$WpShare247_Wp_Posts = new WpShare247_Wp_Posts( $post_id );
//Truy xuất vào dữ liệu ngay dòng có ID là $post_id
?>
<ul class="data-post-single">
<li><?php echo $WpShare247_Wp_Posts->ID; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_author; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_title; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_content; ?></li>
<!-- Tiếp tục lấy dữ liệu các cột khác $WpShare247_Wp_Posts->column_name; ......-->
</ul>
<?php
//Gọi hàm của Object
echo 'ID của bài viết là: ' . $WpShare247_Wp_Posts->getId();
endwhile; // End of the loop.
?>
</div>
</main>
<?php get_footer();

3.3 Khai báo thêm Method cho Object

Ví dụ tôi cần kiểm tra bài viết đang xem có được xuất bảng hay chưa. Tôi sẽ khai báo thêm method như sau: chú ý tại dòng // Kiểm tra trạng thái bài viết này có được xuất bản hay chưa?

<?php
if( !class_exists('WpShare247_Wp_Posts') ):
class WpShare247_Wp_Posts extends W_SQLMaster{
const TABLE = 'wp_posts'; // Một trong các bảng tồn tại trong db wordpress
const ID = 'ID'; // ID là tên cột khóa chính của bảng trên
//constructor
public function __construct($id) {
parent::__construct($id);
}
/*Các hàm Function (Method) của Class viết tại đây */
// Kiểm tra trạng thái bài viết này có được xuất bản hay chưa?
public function is_publish(){
$is_publish = false;
if($this->post_status=='publish'){
$is_publish = true;
}
return $is_publish;
}
//End Class--------------------------------------------------------------------------------------------
}
endif;

Sử dụng hàm is_publish() vừa gọi trong template. chú ý tại dòng: // Kiểm tra bài viết xuất bản hay chưa?

<?php
get_header(); ?>
<main class="content">
<div class="content-block">
<?php
while ( have_posts() ) : the_post();
$post_id = get_the_ID();
//Tạo mới đối tượng thông qua id
$WpShare247_Wp_Posts = new WpShare247_Wp_Posts( $post_id );
//Truy xuất vào dữ liệu ngay dòng có ID là $post_id
?>
<ul class="data-post-single">
<li><?php echo $WpShare247_Wp_Posts->ID; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_author; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_title; ?></li>
<li><?php echo $WpShare247_Wp_Posts->post_content; ?></li>
<!-- Tiếp tục lấy dữ liệu các cột khác $WpShare247_Wp_Posts->column_name; ......-->
</ul>
<?php
//Gọi hàm của Object
echo 'ID của bài viết là: ' . $WpShare247_Wp_Posts->getId();
// Kiểm tra bài viết xuất bản hay chưa?
if($WpShare247_Wp_Posts->is_publish()){
echo 'Bài viết này đã xuất bản';
}else{
echo 'Bài viết này chưa xuất bản';
}
endwhile; // End of the loop.
?>
</div>
</main>
<?php get_footer();

Ngoài ra bằng kiến thức hướng đối tượng đã học qua bạn có thể dễ dàng tạo ra vô số các phương thức cho đối tượng này để phục vụ cho mình nhé.

4. Thêm, Xóa, Sửa đối tượng

Bằng các phương thức sau bạn có thể dễ dàng thay đổi dữ liệu bảng wp_posts của wordpress thông qua đối tượng WpShare247_Wp_Posts.

4.1 Thêm mới 1 dòng vào bảng wp_posts

<?php
$id = ''; // Giá trị rỗng
$new_post = new WpShare247_Wp_Posts($id);
$new_post->post_author = 1; // Đây là ID của tác giả bài viết
$new_post->post_date = current_time('Y-m-d H:i:s', 0);
$new_post->post_content = 'Nội dung bài viết ở đây';
$new_post->post_title = 'Tiêu đề bài viết mới';
$new_post->post_status = 'draft'; // Trạng thái bài viết, xem thêm danh sách trạng thái các post
$new_post->post_type = 'post';
//Thêm các cột khác tiếp theo ở đây
$WpShare247_Wp_Posts = $new_post->save(); // sau khi thêm thành công sẽ trả về đối tượng đã thêm

Sau khi thêm thành công sẽ trả về đối tượng đã thêm. Lúc này bạn kiểm tra bảng wp_posts sẽ thấy 1 dòng mới.

4.2 Sửa 1 dòng vào bảng wp_posts

<?php
$id = 16; // ID của dòng cần sửa
$WpShare247_Wp_Posts = new WpShare247_Wp_Posts($id);
$WpShare247_Wp_Posts->post_author = 5; // Đây là ID của tác giả bài viết mới
$WpShare247_Wp_Posts->post_date = current_time('Y-m-d H:i:s', 0);
$WpShare247_Wp_Posts->post_content = 'Nội dung mới bài viết ở đây';
$WpShare247_Wp_Posts->post_title = 'Tiêu đề mới của bài viết';
$WpShare247_Wp_Posts->post_status = 'publish'; // Trạng thái bài viết, xem thêm danh sách trạng thái các post
$WpShare247_Wp_Posts->post_type = 'post';
//Thêm các cột khác cần thay đổi tại đây.
$WpShare247_Wp_Posts = $WpShare247_Wp_Posts->update(); // Sau khi update thành công sẽ trả về đối tượng

Sau khi update thành công sẽ trả về đối tượng. Lúc này bạn kiểm tra dữ liệu bảng wp_posts tại dòng có ID = 16 sẽ thấy dữ liệu đã đổi mới.

4.3 Xóa 1 dòng trong bảng wp_posts

<?php
$id = 16; // ID của dòng cần xóa
$WpShare247_Wp_Posts = new WpShare247_Wp_Posts($id);
$is_delete = $WpShare247_Wp_Posts->delete();

Sau khi xóa thành công sẽ trả về true.

Nếu bạn đã từng tìm hiểu qua mô hình Model-View-Controller thì WpShare247_Wp_Posts nó chính là Model. Giúp cho việc truy xuất dữ liệu rất dễ dàng trong lập trình WordPress.

5. Tạo table và Class mới cho riêng mình.

Điều này là khác biệt lớn nhất trong bài viết này. Ngoài những bảng mặc định mà WordPress đã có sẵn, bạn cũng có thể tạo riêng một table cho mình để lưu trữ dữ liệu.

Ví dụ tôi cần 1 bảng chứa các báo cáo của nhân viên công ty với tên: wp_wpshare247_reports.

5.1 Tạo bảng mới bằng PhpMysql.

Bảng wp_wpshare247_reports sẽ có 5 cột: ID, title, content, user_id, created

Sử dụng Hướng đối tượng (OOP) trong WordPress

Sử dụng Hướng đối tượng (OOP) trong WordPress

Sử dụng Hướng đối tượng (OOP) trong WordPress

Sau khi tạo bảng thành công. Bạn xem lại bước 1.2 bên trên nhé. ( Vì đã hướng dẫn cụ thể bên trên rồi nên các bước dưới đây mình xin viết ngắn gọn lại ).

5.2 Tạo Class mới kết nối tới bảng.

Cụ thể ở đây tôi sẽ tạo ra Class là: WpShare247_Wp_reports ( nhớ cũng tạo ra file WpShare247_Wp_reports.php nhé ) với nội dung như sau, Class này sẽ kết nối tới bảng wp_wpshare247_reports vừa tạo.

<?php
if( !class_exists('WpShare247_Wp_reports') ):
class WpShare247_Wp_reports extends W_SQLMaster{
const TABLE = 'wp_wpshare247_reports'; // bảng cần kết nối
const ID = 'ID';
//constructor
public function __construct($id) {
parent::__construct($id);
}
//End Class--------------------------------------------------------------------------------------------
}
endif;

5.3 Tương tác dữ liệu giữa Class và bảng.

<?php
//Thêm mới báo cáo 1
$WpShare247_Wp_report_new = new WpShare247_Wp_reports("");
$WpShare247_Wp_report_new->title = 'Báo cáo hôm nay';
$WpShare247_Wp_report_new->content = 'Mô tả các công việc báo cáo hôm nay';
$WpShare247_Wp_report_new->user_id = 10; // ID của user báo cáo
$WpShare247_Wp_report_new->created = ''; // Để rỗng sẽ tự tạo với ngày hiện tại
$Obj_report = $WpShare247_Wp_report_new->save(); // Insert 1 dòng vào table
//Thêm mới báo cáo 2
$WpShare247_Wp_report_new2 = new WpShare247_Wp_reports("");
$WpShare247_Wp_report_new2->title = 'Báo cáo hôm nay 2';
$WpShare247_Wp_report_new2->content = 'Mô tả các công việc báo cáo hôm nay 2';
$WpShare247_Wp_report_new2->user_id = 15; // ID của user báo cáo
$WpShare247_Wp_report_new2->created = ''; // Để rỗng sẽ tự tạo với ngày hiện tại
$Obj_report2 = $WpShare247_Wp_report_new2->save(); // Insert 1 dòng vào table
//Thêm mới báo cáo khác thứ n.......
//Sửa báo cáo 1
$report_id = $Obj_report->ID;
$WpShare247_Wp_report_update = new WpShare247_Wp_reports($report_id);
$WpShare247_Wp_report_update->title = 'Báo cáo hôm nay bị sai tiêu đề nên sửa lại';
//Cột nào cần thay đồi thì khai báo thêm tại đây
$Obj_report = $WpShare247_Wp_report_update->update();
//Xóa báo cáo 1
$report_id = $Obj_report->ID;
$WpShare247_Wp_report_update = new WpShare247_Wp_reports($report_id);
$b = $WpShare247_Wp_report_update->delete();
if($b){
echo 'Đã xía báo cáo '. $report_id;
}

Bạn có thể gọi đoạn code trên hay khai báo Đối tượng WpShare247_Wp_reports bất kì tại các template của WordPress. Tuy nhiên tôi hứa sẽ hướng dẫn các bạn làm theo chuẩn cấu trúc mô hình MVC (Model-View-Controller) trong WordPress ở một bài gần nhất.

Như vậy tôi vừa hướng dẫn các bạn cách sử dụng hướng đối tượng OOP trong WordPress. Hi vọng bài viết sẽ giúp bạn hiểu thêm cách dùng Class nhé.

Related Posts :

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

Bài đăng tiêu biểu