| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- <?php
- /**
- * Import class
- *
- * Handles importing product categories from CSV
- *
- * @since 1.0.0
- * @package Studiou_WC_Product_Cat_Manage
- * @subpackage Studiou_WC_Product_Cat_Manage/includes
- */
- // If this file is called directly, abort.
- if (!defined('WPINC')) {
- die;
- }
- class Studiou_WC_Product_Cat_Manage_Import {
-
- /**
- * Database handler
- *
- * @var Studiou_WC_Product_Cat_Manage_DB
- */
- private $db;
-
- /**
- * Required CSV headers
- *
- * @var array
- */
- private $required_headers = array(
- 'name',
- 'url-name',
- 'parent-name',
- 'description',
- 'display-type',
- 'visibility',
- 'protected-passwords',
- 'operation'
- );
-
- /**
- * Valid display types
- *
- * @var array
- */
- private $valid_display_types = array(
- 'default',
- 'products',
- 'subcategories',
- 'both'
- );
-
- /**
- * Valid visibility values
- *
- * @var array
- */
- private $valid_visibility = array(
- 'public',
- 'protected'
- );
-
- /**
- * Valid operation values
- *
- * @var array
- */
- private $valid_operations = array(
- 'A', // Add
- 'U', // Update
- 'D' // Delete
- );
-
- /**
- * Constructor
- *
- * @param Studiou_WC_Product_Cat_Manage_DB $db Database handler
- */
- public function __construct($db) {
- $this->db = $db;
-
- // Register AJAX handler
- add_action('wp_ajax_studiou_wcpcm_import', array($this, 'handle_import_ajax'));
- }
-
- /**
- * Handle AJAX import request
- */
- public function handle_import_ajax() {
- // Check nonce
- if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'studiou-wcpcm-nonce')) {
- wp_send_json_error(array(
- 'message' => __('Security check failed', 'studiou-wc-product-cat-manage')
- ));
- }
-
- // Check permissions
- if (!current_user_can('manage_woocommerce')) {
- wp_send_json_error(array(
- 'message' => __('You do not have sufficient permissions', 'studiou-wc-product-cat-manage')
- ));
- }
-
- // Check if file was uploaded
- if (!isset($_FILES['import_file']) || empty($_FILES['import_file']['tmp_name'])) {
- wp_send_json_error(array(
- 'message' => __('No file was uploaded', 'studiou-wc-product-cat-manage')
- ));
- }
-
- try {
- // Process the uploaded file
- $results = $this->process_import_file($_FILES['import_file']['tmp_name']);
-
- // Generate response message
- $message = $this->generate_import_results_message($results);
-
- // Return success response
- wp_send_json_success(array(
- 'message' => $message
- ));
- } catch (Exception $e) {
- wp_send_json_error(array(
- 'message' => sprintf(
- __('Import error: %s', 'studiou-wc-product-cat-manage'),
- $e->getMessage()
- )
- ));
- }
- }
-
- /**
- * Process import file
- *
- * @param string $file_path Path to uploaded CSV file
- * @return array Import results
- * @throws Exception On validation or processing error
- */
- private function process_import_file($file_path) {
- // Open file
- $file = fopen($file_path, 'r');
- if (!$file) {
- throw new Exception(__('Failed to open the uploaded file', 'studiou-wc-product-cat-manage'));
- }
-
- // Read and remove UTF-8 BOM if present
- $bom = fread($file, 3);
- if ($bom !== "\xEF\xBB\xBF") {
- // Not a BOM, rewind the file pointer
- rewind($file);
- }
-
- // Read headers
- $headers = fgetcsv($file);
- if (!$headers) {
- fclose($file);
- throw new Exception(__('Failed to read CSV headers', 'studiou-wc-product-cat-manage'));
- }
-
- // Validate headers
- $this->validate_headers($headers);
-
- // Process rows
- $results = array();
- $row_number = 1; // Header row is 1
-
- while (($row = fgetcsv($file)) !== false) {
- $row_number++;
-
- try {
- // Map row data to associative array
- $category_data = array();
- foreach ($headers as $index => $header) {
- $category_data[$header] = isset($row[$index]) ? $row[$index] : '';
- }
-
- // Validate row data
- $this->validate_row_data($category_data, $row_number);
-
- // Process based on operation
- $operation = strtoupper(trim($category_data['operation']));
-
- switch ($operation) {
- case 'A':
- $result = $this->db->create_category($category_data);
- break;
- case 'U':
- $result = $this->db->update_category($category_data);
- break;
- case 'D':
- $result = $this->db->delete_category($category_data['name']);
- break;
- default:
- throw new Exception(sprintf(
- __('Invalid operation "%s" at row %d', 'studiou-wc-product-cat-manage'),
- $operation,
- $row_number
- ));
- }
-
- $results[] = $result;
- } catch (Exception $e) {
- $results[] = array(
- 'status' => 'error',
- 'message' => sprintf(
- __('Error at row %d: %s', 'studiou-wc-product-cat-manage'),
- $row_number,
- $e->getMessage()
- )
- );
- }
- }
-
- fclose($file);
- return $results;
- }
-
- /**
- * Validate CSV headers
- *
- * @param array $headers Headers from CSV
- * @throws Exception If headers are invalid
- */
- private function validate_headers($headers) {
- // Check that all required headers are present
- foreach ($this->required_headers as $required_header) {
- if (!in_array($required_header, $headers)) {
- throw new Exception(sprintf(
- __('Missing required header: %s', 'studiou-wc-product-cat-manage'),
- $required_header
- ));
- }
- }
- }
-
- /**
- * Validate row data
- *
- * @param array $data Row data
- * @param int $row_number Row number for error messages
- * @throws Exception If data is invalid
- */
- private function validate_row_data($data, $row_number) {
- // Check required fields based on operation
- $operation = strtoupper(trim($data['operation']));
-
- if (!in_array($operation, $this->valid_operations)) {
- throw new Exception(sprintf(
- __('Invalid operation "%s" at row %d. Must be one of: A, U, D', 'studiou-wc-product-cat-manage'),
- $operation,
- $row_number
- ));
- }
-
- // Check name is required for all operations
- if (empty($data['name'])) {
- throw new Exception(sprintf(
- __('Missing required field "name" at row %d', 'studiou-wc-product-cat-manage'),
- $row_number
- ));
- }
-
- // Additional validations for Add and Update operations
- if ($operation === 'A' || $operation === 'U') {
- // URL name is required
- if (empty($data['url-name'])) {
- throw new Exception(sprintf(
- __('Missing required field "url-name" at row %d', 'studiou-wc-product-cat-manage'),
- $row_number
- ));
- }
-
- // Validate display type
- if (!empty($data['display-type']) && !in_array($data['display-type'], $this->valid_display_types)) {
- throw new Exception(sprintf(
- __('Invalid display type "%s" at row %d. Must be one of: default, products, subcategories, both', 'studiou-wc-product-cat-manage'),
- $data['display-type'],
- $row_number
- ));
- }
-
- // Validate visibility
- if (!empty($data['visibility']) && !in_array($data['visibility'], $this->valid_visibility)) {
- throw new Exception(sprintf(
- __('Invalid visibility "%s" at row %d. Must be one of: public, protected', 'studiou-wc-product-cat-manage'),
- $data['visibility'],
- $row_number
- ));
- }
-
- // If visibility is protected, passwords are required
- if (isset($data['visibility']) && $data['visibility'] === 'protected' && empty($data['protected-passwords'])) {
- throw new Exception(sprintf(
- __('Protected visibility requires at least one password at row %d', 'studiou-wc-product-cat-manage'),
- $row_number
- ));
- }
- }
- }
-
- /**
- * Generate import results message
- *
- * @param array $results Import results
- * @return string Formatted message
- */
- private function generate_import_results_message($results) {
- if (empty($results)) {
- return __('No items were processed.', 'studiou-wc-product-cat-manage');
- }
-
- $count = count($results);
- $message = sprintf(__('Imported %d items:', 'studiou-wc-product-cat-manage'), $count) . "\n";
-
- foreach ($results as $result) {
- $message .= "\t" . $result['message'] . "\n";
- }
-
- return $message;
- }
- }
|