first commit

This commit is contained in:
Admin 2025-12-31 14:49:50 +07:00
commit 29c27dae04
13 changed files with 1218 additions and 0 deletions

View File

@ -0,0 +1,28 @@
jQuery(function ($) {
$("#import_api").on("click", function () {
$.post(
ajaxurl,
{
action: "wpi_import_api",
url: $("#api_url").val(),
},
alert
);
});
$("#import_csv").on("click", function () {
const file = $("#csv_file")[0].files[0];
const form = new FormData();
form.append("action", "wpi_import_csv");
form.append("file", file);
$.ajax({
url: ajaxurl,
type: "POST",
data: form,
processData: false,
contentType: false,
success: alert,
});
});
});

View File

@ -0,0 +1,56 @@
<?php
class WPI_Admin_Page
{
public function __construct()
{
add_action('admin_menu', [$this, 'menu']);
add_action('wp_ajax_wpi_import_api', [$this, 'import_api']);
add_action('wp_ajax_wpi_import_csv', [$this, 'import_csv']);
}
public function menu()
{
add_menu_page(
'Product Importer',
'Product Importer',
'manage_woocommerce',
'wpi-importer',
[$this, 'render']
);
}
public function render()
{
?>
<h1>Woo Product Importer</h1>
<h2>Import from API</h2>
<input type="text" id="api_url" placeholder="API URL">
<button id="import_api">Import API</button>
<h2>Import from CSV</h2>
<input type="file" id="csv_file">
<button id="import_csv">Import CSV</button>
<?php
}
public function import_api()
{
$url = sanitize_text_field($_POST['url']);
$importer = new WPI_API_Importer();
$result = $importer->import($url);
wp_send_json_success($result);
}
public function import_csv()
{
if (empty($_FILES['file'])) {
wp_send_json_error('No file');
}
$importer = new WPI_CSV_Importer();
$result = $importer->import($_FILES['file']['tmp_name']);
wp_send_json_success($result);
}
}

View File

@ -0,0 +1,66 @@
<?php
class WPI_API_Importer
{
private static function api_url($url)
{
$base_url = WPI_Config_Model::get_config('base_api');
return $base_url . $url;
}
public static function products(array $args = [])
{
$page = isset($args['page'])
? (int) $args['page']
: (int) WPI_Config_Model::get_config('current_page', 1);
$limit = isset($args['limit'])
? (int) $args['limit']
: (int) WPI_Config_Model::get_config('limit_per_time', 20);
$import_api = WPI_Config_Model::get_config('import_api');
$authen_key = WPI_Config_Model::get_config('authen_key');
if (!$import_api || !$authen_key) {
WPI_Logger::log('Missing API config');
return;
}
$url = add_query_arg([
'page' => $page,
'perPage' => $limit,
], $import_api);
WPI_Logger::log("Calling API: {$url}");
return wp_remote_get(self::api_url($url), [
'timeout' => 30,
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $authen_key,
],
]);
}
public static function categories()
{
$url = WPI_Config_Model::get_config('categories_api');
$authen_key = WPI_Config_Model::get_config('authen_key');
if (!$url || !$authen_key) {
WPI_Logger::log('Missing API config');
return;
}
return wp_remote_get(self::api_url($url), [
'timeout' => 30,
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $authen_key,
],
]);
}
}

View File

@ -0,0 +1,227 @@
<?php
class WPI_Cron
{
const HOOK = 'wpi_import_products_cron';
const TRIGGER_HOOK = 'wpi_trigger_import_cron';
const SYNC_CATEGORIES_HOOK = 'wpi_sync_categories_cron';
public static function init()
{
add_filter('cron_schedules', [self::class, 'add_schedule']);
add_action(self::HOOK, [self::class, 'run']);
add_action(self::TRIGGER_HOOK, [self::class, 'trigger']);
add_action(self::SYNC_CATEGORIES_HOOK, [self::class, 'sync_categories']);
}
public static function add_schedule($schedules)
{
if (!isset($schedules['every_minute'])) {
$schedules['every_minute'] = [
'interval' => 60,
'display' => 'Every Minute'
];
}
return $schedules;
}
public static function activate()
{
// if (!wp_next_scheduled(self::HOOK)) {
// wp_schedule_event(time(), 'every_minute', self::HOOK);
// }
// // Trigger cron (2h sáng mỗi ngày)
// if (!wp_next_scheduled(self::TRIGGER_HOOK)) {
// $timestamp = strtotime('tomorrow 02:00');
// wp_schedule_event(
// $timestamp,
// 'daily',
// self::TRIGGER_HOOK
// );
// }
}
public static function deactivate()
{
wp_clear_scheduled_hook(self::HOOK);
wp_clear_scheduled_hook(self::TRIGGER_HOOK);
}
public static function run()
{
if (!class_exists('WooCommerce')) {
WPI_Logger::log('WooCommerce not active');
return;
}
if (!WPI_Config_Model::get_config('status_cron')) {
WPI_Logger::log('Status cron is OFF');
return;
}
if (WPI_Config_Model::get_config('sync_status')) {
WPI_Logger::log('Sync already running');
return;
}
$import_api = WPI_Config_Model::get_config('import_api');
$authen_key = WPI_Config_Model::get_config('authen_key');
if (!$import_api || !$authen_key) {
WPI_Logger::log('Missing API config');
return;
}
$limit = (int) WPI_Config_Model::get_config('limit_per_time', 20);
$page = (int) WPI_Config_Model::get_config('current_page', 1);
WPI_Config_Model::set_config('sync_status', 1);
try {
$response = WPI_API_Importer::products([
'page' => $page,
'limit' => $limit,
]);
if (is_wp_error($response)) {
WPI_Logger::log('API Error: ' . $response->get_error_message());
return;
}
$code = wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
WPI_Logger::log("HTTP Code: {$code}");
if ($code !== 200) {
WPI_Logger::log("API failed: {$body}");
return;
}
$data = json_decode($body, true)['data'];
if (!is_array($data)) {
WPI_Logger::log('Invalid JSON response');
return;
}
WPI_Logger::log('Fetched ' . count($data) . ' items');
$category_map = WPI_Category_Mapper::get_category_map();
WPI_Logger::log(json_encode($category_map));
foreach ($data as $item) {
$import_data = WPI_Product_Map::from_api($item, $category_map);
$validation = WPI_Product_Validator::validate($import_data);
if (!$validation['valid']) {
WPI_Logger::log(
'Skip product SKU ' . ($import_data['sku'] ?? 'N/A') .
' | Errors: ' . implode(' | ', $validation['errors'])
);
continue;
}
WPI_Logger::log_product_item($import_data);
WPI_Product_Mapper::upsert_from_api($import_data);
}
WPI_Config_Model::set_config('current_page', $page + 1);
if (count($data) < $limit) {
WPI_Config_Model::set_config('status_cron', 0);
WPI_Config_Model::set_config('current_page', 1);
}
WPI_Logger::log("Page {$page} done");
} finally {
WPI_Config_Model::set_config('sync_status', 0);
}
}
public static function trigger()
{
if (WPI_Config_Model::get_config('sync_status')) {
WPI_Logger::log('Trigger skipped: sync is running');
return;
}
WPI_Logger::log('Trigger import cron ON');
WPI_Config_Model::set_config('status_cron', 1);
WPI_Config_Model::set_config('current_page', 1);
}
public static function sync_categories()
{
if (!class_exists('WooCommerce')) {
WPI_Logger::log('WooCommerce not active');
return;
}
if (!WPI_Config_Model::get_config('categories_status_cron')) {
WPI_Logger::log('Status sync categories cron is OFF');
return;
}
if (WPI_Config_Model::get_config('categories_sync_status')) {
WPI_Logger::log('Sync categories already running');
return;
}
// Lock
WPI_Config_Model::set_config('categories_sync_status', 1);
try {
$response = WPI_API_Importer::categories();
if (is_wp_error($response)) {
WPI_Logger::log('API Error: ' . $response->get_error_message());
return;
}
$code = wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
WPI_Logger::log("HTTP Code: {$code}");
if ($code !== 200) {
WPI_Logger::log("API failed: {$body}");
return;
}
$json = json_decode($body, true);
if (empty($json['status']) || empty($json['data']) || !is_array($json['data'])) {
WPI_Logger::log('Invalid API response structure');
return;
}
WPI_Logger::log('Fetched ' . count($json['data']) . ' root categories');
WPI_Category_Mapper::upsert_wp_categories_from_tree(
$json['data'],
0,
'product_cat'
);
WPI_Logger::log('Category sync completed successfully');
} finally {
// Unlock ONLY
WPI_Config_Model::set_config('categories_sync_status', 0);
}
}
}

View File

@ -0,0 +1,64 @@
<?php
class WPI_Logger
{
public static function log($message)
{
$dir = WP_CONTENT_DIR . '/uploads/wpi-import';
if (!file_exists($dir)) {
wp_mkdir_p($dir);
}
$file = $dir . '/wpi-cron.log';
$time = current_time('Y-m-d H:i:s');
file_put_contents(
$file,
"[{$time}] {$message}\n",
FILE_APPEND
);
}
public static function log_product_item($item)
{
$log_file = WP_CONTENT_DIR . '/uploads/wpi-import/api-product-preview.log';
if (!file_exists(dirname($log_file))) {
wp_mkdir_p(dirname($log_file));
}
$time = current_time('Y-m-d H:i:s');
file_put_contents(
$log_file,
"================ ITEM {$item['sku']} | {$time} ================\n" .
print_r($item, true) . "\n\n",
FILE_APPEND
);
}
public static function log_category_item(array $category)
{
$log_file = WP_CONTENT_DIR . '/uploads/wpi-import/api-category-preview.log';
if (!file_exists(dirname($log_file))) {
wp_mkdir_p(dirname($log_file));
}
$time = current_time('Y-m-d H:i:s');
$id = $category['id'] ?? 'N/A';
$name = $category['name'] ?? 'N/A';
$parent_id = $category['parent_id'] ?? 0;
file_put_contents(
$log_file,
"================ CATEGORY {$id} | {$name} | {$time} ================\n" .
print_r($category, true) . "\n\n",
FILE_APPEND
);
}
}

View File

@ -0,0 +1,87 @@
<?php
class WPI_Product_Map
{
/**
* Map raw API item standardized product data
*/
public static function from_api(
array $item,
array $category_map
): array {
return [
'sku' => $item['sku'] ?? null,
'name' => $item['name'] ?? '',
'price' => (float) ($item['price'] ?? 0),
'stock' => (int) ($item['stock'] ?? 0),
'description' => $item['description'] ?? '',
'short_description' => $item['short_description'] ?? '',
'brand' => $item['brand'] ?? null,
'categories' => self::map_categories($item, $category_map),
'images' => self::map_images($item),
];
}
protected static function map_categories(
array $item,
array $category_map
): array {
if (empty($item['categories']) || !is_array($item['categories'])) {
return [];
}
$wp_category_ids = [];
foreach ($item['categories'] as $cat) {
if (empty($cat['id'])) {
continue;
}
$external_id = (string) $cat['id'];
// map external id → wp term id
if (isset($category_map[$external_id])) {
$wp_category_ids[] = $category_map[$external_id];
} else {
// log category chưa map được (rất quan trọng)
WPI_Logger::log(
"[CATEGORY_MAP] Missing category external_id={$external_id} ({$cat['name']})"
);
}
}
return array_values(array_unique($wp_category_ids));
}
protected static function map_images(array $item): array
{
if (empty($item['images']) || !is_array($item['images'])) {
return [];
}
$default = [];
$others = [];
foreach ($item['images'] as $img) {
if (empty($img['url'])) {
continue;
}
if (!empty($img['is_default'])) {
$default[] = $img['url'];
} else {
$others[] = $img['url'];
}
}
// default image lên trước
return array_merge($default, $others);
}
}

View File

@ -0,0 +1,50 @@
<?php
class WPI_Product_Validator
{
/**
* Validate product data after mapping
*
* @return array [bool $is_valid, array $errors]
*/
public static function validate(array $data): array
{
$errors = [];
// Required fields
if (empty($data['sku'])) {
$errors[] = 'SKU is required';
}
if (empty($data['name'])) {
$errors[] = 'Product name is required';
}
// Price
if (!isset($data['price']) || !is_numeric($data['price'])) {
$errors[] = 'Price must be numeric';
} elseif ($data['price'] < 0) {
$errors[] = 'Price must be >= 0';
}
// Stock
if (!isset($data['stock']) || !is_numeric($data['stock'])) {
$errors[] = 'Stock must be numeric';
}
// Images
if (!empty($data['images']) && !is_array($data['images'])) {
$errors[] = 'Images must be an array';
}
// Categories
if (!empty($data['categories']) && !is_array($data['categories'])) {
$errors[] = 'Categories must be an array';
}
return [
'valid' => empty($errors),
'errors' => $errors
];
}
}

View File

@ -0,0 +1,118 @@
<?php
class WPI_Category_Mapper
{
public static function upsert_wp_categories_from_tree(
array $categories,
int $parent_id = 0,
string $taxonomy = 'category'
) {
foreach ($categories as $item) {
if (empty($item['id']) || empty($item['name'])) {
continue;
}
$external_id = (string) $item['id'];
$name = $item['name'];
$slug = sanitize_title($name);
// Log category item
WPI_Logger::log_category_item($item);
/**
* Find existing term by description (external id)
*/
$existing_term = self::find_term_by_description(
$external_id,
$taxonomy
);
if ($existing_term) {
$term_id = (int) $existing_term->term_id;
// Update name / slug / parent if needed
wp_update_term($term_id, $taxonomy, [
'name' => $name,
'slug' => $slug,
'parent' => $parent_id,
]);
} else {
/**
* Insert new term
*/
$result = wp_insert_term($name, $taxonomy, [
'slug' => $slug,
'parent' => $parent_id,
'description' => $external_id,
]);
if (is_wp_error($result)) {
WPI_Logger::log('[CATEGORY_SYNC_ERROR] ' . $result->get_error_message());
continue;
}
$term_id = (int) $result['term_id'];
}
/**
* Recursive children
*/
if (!empty($item['children']) && is_array($item['children'])) {
self::upsert_wp_categories_from_tree(
$item['children'],
$term_id,
$taxonomy
);
}
}
}
/**
* Find term by description (external ID)
*/
private static function find_term_by_description(
string $description,
string $taxonomy
) {
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
'number' => 1,
'meta_query' => [],
'description__like' => $description,
]);
return !empty($terms) ? $terms[0] : null;
}
public static function get_category_map(
string $taxonomy = 'product_cat'
): array {
$map = [];
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
if (is_wp_error($terms) || empty($terms)) {
return $map;
}
foreach ($terms as $term) {
$external_id = trim($term->description);
if ($external_id === '') {
continue;
}
$map[(string) $external_id] = (int) $term->term_id;
}
return $map;
}
}

View File

@ -0,0 +1,227 @@
<?php
class WPI_Product_Mapper
{
public static function upsert($data)
{
if (empty($data['sku'])) return;
$product_id = wc_get_product_id_by_sku($data['sku']);
$product = $product_id
? wc_get_product($product_id)
: new WC_Product_Simple();
$product->set_name($data['name'] ?? '');
$product->set_sku($data['sku']);
$product->set_regular_price($data['price'] ?? 0);
$product->set_stock_quantity($data['stock'] ?? 0);
$product->set_manage_stock(true);
if (!empty($data['description'])) {
$product->set_description(wp_kses_post($data['description']));
}
if (!empty($data['short_description'])) {
$product->set_short_description(wp_kses_post($data['short_description']));
}
return $product->save();
}
protected static function attach_images(int $product_id, array $urls)
{
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$gallery_ids = [];
foreach ($urls as $index => $url) {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
continue;
}
$attachment_id = media_sideload_image($url, $product_id, null, 'id');
if (is_wp_error($attachment_id)) {
continue;
}
if ($index === 0) {
set_post_thumbnail($product_id, $attachment_id);
} else {
$gallery_ids[] = $attachment_id;
}
}
if ($gallery_ids) {
update_post_meta(
$product_id,
'_product_image_gallery',
implode(',', $gallery_ids)
);
}
}
public static function upsert_from_api(array $data)
{
if (empty($data['sku'])) return;
$product_id = self::upsert($data);
if (!$product_id) return;
if (!empty($data['brand'])) {
self::sync_brand($product_id, $data['brand']);
}
if (!empty($data['categories'])) {
self::sync_categories($product_id, $data['categories']);
}
if (!empty($data['images'])) {
self::sync_images($product_id, $data['images']);
}
return $product_id;
}
protected static function sync_categories(int $product_id, array $categories)
{
if (empty($categories)) return;
$term_ids = [];
foreach ($categories as $cat_id) {
// chỉ nhận số
if (is_numeric($cat_id)) {
$term_ids[] = (int) $cat_id;
}
}
if (!$term_ids) return;
// gán trực tiếp, KHÔNG tạo mới
wp_set_object_terms(
$product_id,
array_unique($term_ids),
'product_cat'
);
}
protected static function sync_images(int $product_id, array $images)
{
if (empty($images)) return;
$urls = array_filter(array_map('trim', $images));
if (!$urls) return;
self::attach_images($product_id, $urls);
}
protected static function sync_brand(int $product_id, string $brand)
{
$brand = trim($brand);
if (!$brand) return;
$taxonomy = 'product_brand';
// Kiểm tra taxonomy tồn tại
if (!taxonomy_exists($taxonomy)) {
return;
}
// Check brand đã tồn tại chưa
$term = term_exists($brand, $taxonomy);
// Chưa có → tạo mới
if (!$term) {
$term = wp_insert_term($brand, $taxonomy);
}
if (is_wp_error($term)) {
return;
}
$term_id = (int) $term['term_id'];
// Gán brand cho product
wp_set_object_terms($product_id, [$term_id], $taxonomy);
// Đảm bảo attribute xuất hiện trong product
$product = wc_get_product($product_id);
if (!$product) return;
$attributes = $product->get_attributes();
if (!isset($attributes[$taxonomy])) {
$attr = new WC_Product_Attribute();
$attr->set_name($taxonomy);
$attr->set_options([$brand]);
$attr->set_visible(true);
$attr->set_variation(false);
$attributes[$taxonomy] = $attr;
$product->set_attributes($attributes);
$product->save();
}
}
protected static function create_wp_categories_from_tree(
array $categories,
int $parent_id = 0,
string $taxonomy = 'category'
) {
foreach ($categories as $item) {
if (empty($item['name']) || empty($item['id'])) {
continue;
}
$name = $item['name'];
$slug = sanitize_title($name);
$description = (string) $item['id']; // 👈 external ID
// Check if term exists under same parent
$existing = term_exists($slug, $taxonomy, $parent_id);
if ($existing) {
$term_id = is_array($existing)
? $existing['term_id']
: $existing;
// Update description if changed
wp_update_term($term_id, $taxonomy, [
'description' => $description,
]);
} else {
$result = wp_insert_term($name, $taxonomy, [
'slug' => $slug,
'parent' => $parent_id,
'description' => $description,
]);
if (is_wp_error($result)) {
error_log('[CATEGORY_SYNC] ' . $result->get_error_message());
continue;
}
$term_id = $result['term_id'];
}
// Recurse children
if (!empty($item['children']) && is_array($item['children'])) {
self::create_wp_categories_from_tree(
$item['children'],
$term_id,
$taxonomy
);
}
}
}
}

View File

@ -0,0 +1,21 @@
<?php
function wpi_create_config_table()
{
global $wpdb;
$table = $wpdb->prefix . 'wpi_configs';
$charset = $wpdb->get_charset_collate();
$sql = "CREATE TABLE {$table} (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
config_key VARCHAR(191) NOT NULL UNIQUE,
config_value LONGTEXT NULL,
description VARCHAR(255) NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
) {$charset};";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql);
}

View File

@ -0,0 +1,84 @@
<?php
class WPI_Config_Model
{
private static function table()
{
global $wpdb;
return $wpdb->prefix . 'wpi_configs';
}
/**
* Check config exists
*/
private static function exists(string $key): bool
{
global $wpdb;
return (bool) $wpdb->get_var(
$wpdb->prepare(
"SELECT 1 FROM " . self::table() . " WHERE config_key = %s LIMIT 1",
$key
)
);
}
/**
* Insert or update config
*/
public static function set_config(string $key, $value, string $description = null)
{
global $wpdb;
$table = self::table();
$now = current_time('mysql');
$data = [
'config_value' => wp_json_encode($value),
'updated_at' => $now,
];
if ($description !== null) {
$data['description'] = $description;
}
if (self::exists($key)) {
// UPDATE only
$wpdb->update(
$table,
$data,
['config_key' => $key],
['%s', '%s', '%s'],
['%s']
);
} else {
// INSERT new
$wpdb->insert(
$table,
array_merge($data, [
'config_key' => $key,
'created_at' => $now,
]),
['%s', '%s', '%s', '%s']
);
}
}
/**
* Get config (auto json decode)
*/
public static function get_config(string $key, $default = null)
{
global $wpdb;
$value = $wpdb->get_var(
$wpdb->prepare(
"SELECT config_value FROM " . self::table() . " WHERE config_key = %s",
$key
)
);
return $value !== null ? json_decode($value, true) : $default;
}
}

View File

@ -0,0 +1,35 @@
- Run cron
<!-- Run simple -->
<!-- Cron run import product -->
wp cron event run wpi_import_products_cron --allow-root <!-- Call by cron -->
wp eval "do_action('wpi_import_products_cron');" --allow-root <!-- Call by CLI -->
<!-- Cron sync categories -->
wp cron event run wpi_sync_categories_cron --allow-root <!-- Call by cron -->
wp eval "do_action('wpi_sync_categories_cron');" --allow-root <!-- Call by CLI -->
<!-- Cron triger auto sync -->
wp cron event run wpi_trigger_import_cron --allow-root <!-- Call by cron -->
wp eval "do_action('wpi_trigger_import_cron');" --allow-root <!-- Call by CLI -->
- Run Cron tabs
0 2 \* \* \* cd /var/www/html && wp cron event run wpi_trigger_import_cron --allow-root >> /var/log/wp-trigger-import.log 2>&1
- - - - - cd /var/www/html && wp cron event run wpi_import_products_cron --allow-root >> /var/log/wp-import-products.log 2>&1
- CLI WP
# Xoá toàn bộ products
wp post delete \
$(wp post list --post_type=product --field=ID --allow-root) \
--force --allow-root
# Xoá toàn bộ product categories
wp term delete product_cat \
$(wp term list product_cat --field=term_id --allow-root) \
--allow-root

View File

@ -0,0 +1,155 @@
<?php
/**
* Plugin Name: WP Product Importer
* Description: Import WooCommerce products from API or CSV (Cron supported)
* Version: 1.0.0
* Author: You
*/
if (!defined('ABSPATH')) exit;
/**
* Constants
*/
define('WPI_PATH', plugin_dir_path(__FILE__));
define('WPI_URL', plugin_dir_url(__FILE__));
/**
* =========================
* Require core files
* =========================
*/
// Migrations
require_once WPI_PATH . 'includes/migrations/create-config-table.php';
// Models
require_once WPI_PATH . 'includes/models/class-wpi-config-model.php';
// Helper
require_once WPI_PATH . 'includes/helpers/class-product-helper.php';
require_once WPI_PATH . 'includes/helpers/class-category-helper.php';
// Core classes
require_once WPI_PATH . 'includes/class-api-importer.php';
require_once WPI_PATH . 'includes/class-cron.php';
require_once WPI_PATH . 'includes/class-logger.php';
require_once WPI_PATH . 'includes/class-admin-page.php';
require_once WPI_PATH . 'includes/class-product-map.php';
require_once WPI_PATH . 'includes/class-product-validator.php';
/**
* =========================
* Init plugin
* =========================
*/
add_action('plugins_loaded', function () {
// Admin UI
// if (is_admin()) {
// new WPI_Admin_Page();
// }
// Init cron only if WooCommerce active
if (class_exists('WooCommerce')) {
WPI_Cron::init();
}
});
/**
* =========================
* Plugin activation
* =========================
*/
register_activation_hook(__FILE__, function () {
if (!class_exists('WooCommerce')) {
deactivate_plugins(plugin_basename(__FILE__));
wp_die('WooCommerce is required for WP Product Importer');
}
// Create DB tables
wpi_create_config_table();
// Default configs
WPI_Config_Model::set_config(
'base_api',
'https://distidata.nswteam.net/api/ecom',
'Api path to get data import'
);
WPI_Config_Model::set_config(
'import_api',
'/scraping-product',
'Api path to get data import'
);
// Default configs
WPI_Config_Model::set_config(
'categories_api',
'/category',
'Api path to get categories'
);
WPI_Config_Model::set_config(
'authen_key',
'abc',
'Authentication key'
);
WPI_Config_Model::set_config(
'limit_per_time',
30,
'Item sync per time'
);
WPI_Config_Model::set_config(
'current_page',
1,
'Current page sync'
);
WPI_Config_Model::set_config(
'sync_status',
0,
'Status sync process'
);
WPI_Config_Model::set_config(
'status_cron',
1,
'Status cron sync'
);
WPI_Config_Model::set_config(
'categories_sync_status',
0,
'Status sync categories process'
);
WPI_Config_Model::set_config(
'categories_status_cron',
1,
'Categoroies status cron'
);
// Activate cron
WPI_Cron::activate();
error_log('[WPI] Plugin activated');
});
/**
* =========================
* Plugin deactivation
* =========================
*/
register_deactivation_hook(__FILE__, function () {
WPI_Cron::deactivate();
error_log('[WPI] Plugin deactivated');
});