From 1ab8114235240c0e4852f6b84a1f967db5b7a389 Mon Sep 17 00:00:00 2001 From: Michel Date: Tue, 19 Nov 2024 10:01:55 -0500 Subject: [PATCH] 6.1.9 Enhanced security measures, optimized plugin functionality, and resolved minor bugs. --- .gitignore | 18 +- admin/includes/cronjobs/slm-tasks.php | 16 +- admin/includes/partials/stats.php | 40 +- admin/includes/wpestores/slm-wpestores.php | 287 --- admin/slm-about-menu.php | 22 +- admin/slm-add-licenses.php | 479 ++--- admin/slm-admin-functions.php | 306 ++-- admin/slm-dashboard-widgets.php | 125 +- admin/slm-integration-help-page.php | 90 +- admin/slm-lic-settings.php | 152 +- admin/slm-list-licenses-class.php | 319 ++-- admin/slm-manage-licenses.php | 12 +- admin/slm-subscribers.php | 90 +- i18n/languages/slm-plus.pot | 1553 +++++++++++++++++ i18n/languages/slmplus-es_ES.mo | Bin 2756 -> 0 bytes i18n/languages/slmplus-es_ES.po | 1511 ---------------- i18n/languages/slmplus.mo | Bin 2756 -> 0 bytes i18n/languages/slmplus.pot | 1228 ------------- includes/class-slm-installer.php | 8 +- includes/slm-api-listener.php | 179 +- includes/slm-init-time-tasks.php | 57 +- includes/slm-plugin-core.php | 156 +- includes/slm-utility.php | 479 +++-- includes/wp-mail-class.php | 6 +- logs/log-cron-job.txt | 2 +- logs/log.txt | 361 ++++ readme.txt | 52 +- samples/ActivateLicense.php | 69 - samples/CheckLicense.php | 68 - samples/CoreConfig.php | 114 -- samples/CreateLicense.php | 47 - samples/DeactivateLicense.php | 61 - samples/GetLicenseInfo.php | 83 - samples/LicenseAPI.php | 73 - slm-plus.php | 19 +- uninstall.php | 63 +- .../includes/create-license-orders.php | 66 +- woocommerce/includes/purchase.php | 261 +-- woocommerce/includes/slm-meta-boxes.php | 348 ++-- .../add-to-cart/slm_license.php | 56 + woocommerce/includes/wc_licenses_class.php | 122 +- .../add-to-cart/slm_license.php | 40 - 42 files changed, 3954 insertions(+), 5084 deletions(-) delete mode 100755 admin/includes/wpestores/slm-wpestores.php create mode 100644 i18n/languages/slm-plus.pot delete mode 100644 i18n/languages/slmplus-es_ES.mo delete mode 100644 i18n/languages/slmplus-es_ES.po delete mode 100644 i18n/languages/slmplus.mo delete mode 100644 i18n/languages/slmplus.pot delete mode 100644 samples/ActivateLicense.php delete mode 100644 samples/CheckLicense.php delete mode 100644 samples/CoreConfig.php delete mode 100644 samples/CreateLicense.php delete mode 100644 samples/DeactivateLicense.php delete mode 100644 samples/GetLicenseInfo.php delete mode 100644 samples/LicenseAPI.php create mode 100644 woocommerce/includes/templates/single-product/add-to-cart/slm_license.php delete mode 100644 woocommerce/templates/single-product/add-to-cart/slm_license.php diff --git a/.gitignore b/.gitignore index 91b6a44..dda102d 100755 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,20 @@ package-lock.json .Icon /node_modules/ /node_modules/* -.vscode \ No newline at end of file +.vscode +/samples/ +samples/LicenseAPI.php +samples/LicenseAPI.php +samples/GetLicenseInfo.php +samples/DeactivateLicense.php +samples/CreateLicense.php +samples/CoreConfig.php +samples/CheckLicense.php +samples/LicenseAPI.php +samples/GetLicenseInfo.php +samples/DeactivateLicense.php +samples/CreateLicense.php +samples/CoreConfig.php +samples/CheckLicense.php +samples/GetLicenseInfo.php +samples/DeactivateLicense.php diff --git a/admin/includes/cronjobs/slm-tasks.php b/admin/includes/cronjobs/slm-tasks.php index 0cf8c4c..2311e90 100644 --- a/admin/includes/cronjobs/slm-tasks.php +++ b/admin/includes/cronjobs/slm-tasks.php @@ -6,7 +6,7 @@ function slm_add_daily_cron_schedule($schedules) { // Define a daily interval (24 hours = 86400 seconds) $schedules['slm_daily'] = array( 'interval' => 86400, - 'display' => __('Every 24 Hours', 'slmplus'), + 'display' => __('Every 24 Hours', 'slm-plus'), ); return $schedules; } @@ -86,8 +86,8 @@ add_action('admin_menu', 'slm_add_manual_license_check_page'); function slm_add_manual_license_check_page() { add_submenu_page( 'tools.php', // Parent slug, 'Tools' menu - __('Run License Check', 'slmplus'), // Page title - __('Run License Check', 'slmplus'), // Menu title + __('Run License Check', 'slm-plus'), // Page title + __('Run License Check', 'slm-plus'), // Menu title 'manage_options', // Capability required 'slm-manual-license-check', // Menu slug 'slm_manual_license_check_page' // Callback function @@ -110,23 +110,23 @@ function slm_manual_license_check_page() { $expired_licenses = slm_run_license_check(); if (!empty($expired_licenses)) { - echo '

' . __('License check completed. The following licenses have expired:', 'slmplus') . '

'; + echo '

' . esc_html__('License check completed. The following licenses have expired:', 'slm-plus') . '

'; } else { - echo '

' . __('License check completed. No expired licenses found.', 'slmplus') . '

'; + echo '

' . esc_html__('License check completed. No expired licenses found.', 'slm-plus') . '

'; } } // Display the button in the admin area echo '
'; - echo '

' . __('Run License Check Manually', 'slmplus') . '

'; + echo '

' . esc_html__('Run License Check Manually', 'slm-plus') . '

'; echo '
'; wp_nonce_field('slm_manual_check_action', 'slm_manual_check_nonce'); - echo ''; + echo ''; echo '
'; // Output expired licenses if available if (!empty($expired_licenses)) { - echo '

' . __('Expired Licenses:', 'slmplus') . '

'; + echo '

' . esc_html__('Expired Licenses:', 'slm-plus') . '

'; echo ' diff --git a/admin/includes/wpestores/slm-wpestores.php b/admin/includes/wpestores/slm-wpestores.php deleted file mode 100755 index 45d336f..0000000 --- a/admin/includes/wpestores/slm-wpestores.php +++ /dev/null @@ -1,287 +0,0 @@ -log_debug("WP eStore integration - checking if a license key needs to be created for this transaction."); - $products_table_name = $wpdb->prefix . "wp_eStore_tbl"; - $slm_data = ""; - - //Check if this is a recurring payment. - if (function_exists('is_paypal_recurring_payment')) { - $recurring_payment = is_paypal_recurring_payment($payment_data); - if ($recurring_payment) { - $slm_debug_logger->log_debug("This is a recurring payment. No need to create a new license key."); - do_action('slm_estore_recurring_payment_received', $payment_data, $cart_items); - return $body; - } - } - - foreach ($cart_items as $current_cart_item) { - $prod_id = $current_cart_item['item_number']; - $item_name = $current_cart_item['item_name']; - $quantity = $current_cart_item['quantity']; - if (empty($quantity)) { - $quantity = 1; - } - $slm_debug_logger->log_debug('License Manager - Item Number: ' . $prod_id . ', Quantity: ' . $quantity . ', Item Name: ' . $item_name); - - $retrieved_product = $wpdb->get_row("SELECT * FROM $products_table_name WHERE id = '$prod_id'", OBJECT); - $package_product = eStore_is_package_product($retrieved_product); - if ($package_product) { - $slm_debug_logger->log_debug('Checking license key generation for package/bundle product.'); - $product_ids = explode(',', $retrieved_product->product_download_url); - foreach ($product_ids as $id) { - $id = trim($id); - $retrieved_product_for_specific_id = $wpdb->get_row("SELECT * FROM $products_table_name WHERE id = '$id'", OBJECT); - //$slm_data .= slm_estore_check_and_generate_key($retrieved_product_for_specific_id, $payment_data, $cart_items, $item_name); - $slm_data .= slm_estore_check_and_create_key_for_qty($retrieved_product_for_specific_id, $payment_data, $cart_items, $item_name, $quantity); - } - } else { - $slm_debug_logger->log_debug('Checking license key generation for single item product.'); - $slm_data .= slm_estore_check_and_create_key_for_qty($retrieved_product, $payment_data, $cart_items, $item_name, $quantity); - } - } - - $body = str_replace("{slm_data}", $slm_data, $body); - return $body; -} - -function slm_estore_check_and_create_key_for_qty($retrieved_product, $payment_data, $cart_items, $item_name, $quantity) -{ - $prod_key_data = ""; - for ($i = 0; $i < $quantity; $i++) { - $prod_key_data .= slm_estore_check_and_generate_key($retrieved_product, $payment_data, $cart_items, $item_name); - } - return $prod_key_data; -} - -function slm_estore_check_and_generate_key($retrieved_product, $payment_data, $cart_items, $item_name) -{ - global $slm_debug_logger; - $license_data = ''; - - if ($retrieved_product->create_license == 1) { - $slm_debug_logger->log_debug('Need to create a license key for this product (' . $retrieved_product->id . ')'); - $slm_key = slm_estore_create_license($retrieved_product, $payment_data, $cart_items, $item_name); - $license_data = "\n" . __('Item Name: ', 'slm') . $retrieved_product->name . " - " . __('License Key: ', 'slm') . $slm_key; - $slm_debug_logger->log_debug('Liense data: ' . $license_data); - $license_data = apply_filters('slm_estore_item_license_data', $license_data); - } - return $license_data; -} - -function slm_estore_create_license($retrieved_product, $payment_data, $cart_items, $item_name) -{ - global $slm_debug_logger; - global $wpdb; - $product_meta_table_name = WP_ESTORE_PRODUCTS_META_TABLE_NAME; - - //Retrieve the default settings values. - $options = get_option('slm_plugin_options'); - $lic_key_prefix = $options['lic_prefix']; - $max_domains = $options['default_max_domains']; - - //Lets check any product specific configuration. - $prod_id = $retrieved_product->id; - $product_meta = $wpdb->get_row("SELECT * FROM $product_meta_table_name WHERE prod_id = '$prod_id' AND meta_key='slm_max_allowed_domains'", OBJECT); - if ($product_meta) { - //Found product specific SLM config data. - $max_domains = $product_meta->meta_value; - } else { - //Use the default value from settings (the $max_domains variable contains the default value already). - } - //Lets check if any product specific expiry date is set - $product_meta = $wpdb->get_row("SELECT * FROM $product_meta_table_name WHERE prod_id = '$prod_id' AND meta_key='slm_date_of_expiry'", OBJECT); - if ($product_meta) { - //Found product specific SLM config data. - $num_days_before_expiry = $product_meta->meta_value; - $slm_date_of_expiry = wp_date('Y-m-d', strtotime('+' . $num_days_before_expiry . ' days')); - } else { - //Use the default value (1 year from today). - $current_date_plus_1year = wp_date('Y-m-d', strtotime('+1 year')); - $slm_date_of_expiry = $current_date_plus_1year; - } - - - $fields = array(); - $fields['license_key'] = uniqid($lic_key_prefix); - $fields['lic_status'] = 'pending'; - $fields['first_name'] = $payment_data['first_name']; - $fields['last_name'] = $payment_data['last_name']; - $fields['email'] = $payment_data['payer_email']; - $fields['company_name'] = $payment_data['company_name']; - $fields['txn_id'] = $payment_data['txn_id']; - $fields['max_allowed_domains'] = $max_domains; - $fields['date_created'] = wp_date("Y-m-d"); //Today's date - $fields['date_expiry'] = $slm_date_of_expiry; - $fields['product_ref'] = $prod_id; //WP eStore product ID - $fields['subscr_id'] = isset($payment_data['subscr_id']) ? $payment_data['subscr_id'] : ''; - - $slm_debug_logger->log_debug('Inserting license data into the license manager DB table.'); - $fields = array_filter($fields); //Remove any null values. - - - $slm_lic_table = SLM_TBL_LICENSE_KEYS; - $result = $wpdb->insert($slm_lic_table, $fields); - if (!$result) { - $slm_debug_logger->log_debug('Notice! initial database table insert failed on license key table (User Email: ' . $fields['email'] . '). Trying again by converting charset', true); - //Convert the default PayPal IPN charset to UTF-8 format - $first_name = mb_convert_encoding($fields['first_name'], "UTF-8", "windows-1252"); - $fields['first_name'] = esc_sql($first_name); - $last_name = mb_convert_encoding($fields['last_name'], "UTF-8", "windows-1252"); - $fields['last_name'] = esc_sql($last_name); - $company_name = mb_convert_encoding($fields['company_name'], "UTF-8", "windows-1252"); - $fields['company_name'] = esc_sql($company_name); - - $result = $wpdb->insert($slm_lic_table, $fields); - if (!$result) { - $slm_debug_logger->log_debug('Error! Failed to update license key table. DB insert query failed.', false); - } - } - //SLM_API_Utility::insert_license_data_internal($fields); - - $prod_args = array('estore_prod_id' => $prod_id, 'estore_item_name' => $item_name); - do_action('slm_estore_license_created', $prod_args, $payment_data, $cart_items, $fields); - - return $fields['license_key']; -} - -/* Code to handle the eStore's product add/edit interface for SLM specific product configuration */ -add_filter('eStore_addon_product_settings_filter', 'slm_estore_product_configuration_html', 10, 2); //Render the product add/edit HTML -add_action('eStore_new_product_added', 'slm_estore_new_product_added', 10, 2); //Handle the DB insert after a product add. -add_action('eStore_product_updated', 'slm_estore_product_updated', 10, 2); //Handle the DB update after a product edit. -add_action('eStore_product_deleted', 'slm_estore_product_deleted'); //Handle the DB delete after a product delete. - -function slm_estore_product_configuration_html($product_config_html, $prod_id) -{ - global $wpdb; - $product_meta_table_name = WP_ESTORE_PRODUCTS_META_TABLE_NAME; - - if (empty($prod_id)) { - //New product add - $slm_max_allowed_domains = ""; - $slm_date_of_expiry = ""; - } else { - //Existing product edit - - //Retrieve the max domain value - $product_meta = $wpdb->get_row("SELECT * FROM $product_meta_table_name WHERE prod_id = '$prod_id' AND meta_key='slm_max_allowed_domains'", OBJECT); - if ($product_meta) { - $slm_max_allowed_domains = $product_meta->meta_value; - } else { - $slm_max_allowed_domains = ""; - } - - //Retrieve the expiry date value - $product_meta = $wpdb->get_row("SELECT * FROM $product_meta_table_name WHERE prod_id = '$prod_id' AND meta_key='slm_date_of_expiry'", OBJECT); - if ($product_meta) { - $slm_date_of_expiry = $product_meta->meta_value; - } else { - $slm_date_of_expiry = ""; - } - } - - $product_config_html .= '
SLM Plus Plugin (Click to Expand)
'; - - $product_config_html .= ''; - - $product_config_html .= ''; - - $product_config_html .= '
Maximum Allowed Domains'; - $product_config_html .= ''; - $product_config_html .= '

Number of domains/installs in which this license can be used. Leave blank if you wish to use the default value set in the license manager plugin settings.

'; - $product_config_html .= '
Number of Days before Expiry'; - $product_config_html .= ' Days'; - $product_config_html .= '

Number of days before expiry. The expiry date of the license will be set based on this value. For example, if you want the key to expire in 6 months then enter a value of 180.

'; - $product_config_html .= '
'; - - return $product_config_html; -} - -function slm_estore_new_product_added($prod_dat_array, $prod_id) -{ - global $wpdb; - $product_meta_table_name = WP_ESTORE_PRODUCTS_META_TABLE_NAME; - - //Save max domain value - $fields = array(); - $fields['prod_id'] = $prod_id; - $fields['meta_key'] = 'slm_max_allowed_domains'; - $fields['meta_value'] = $prod_dat_array['slm_max_allowed_domains']; - $result = $wpdb->insert($product_meta_table_name, $fields); - if (!$result) { - //insert query failed - } - - //Save expiry date value - $fields = array(); - $fields['prod_id'] = $prod_id; - $fields['meta_key'] = 'slm_date_of_expiry'; - $fields['meta_value'] = $prod_dat_array['slm_date_of_expiry']; - $result = $wpdb->insert($product_meta_table_name, $fields); - if (!$result) { - //insert query failed - } -} - -function slm_estore_product_updated($prod_dat_array, $prod_id) -{ - global $wpdb; - $product_meta_table_name = WP_ESTORE_PRODUCTS_META_TABLE_NAME; - - //Find the existing value for the max domains field (for the given product) - $product_meta = $wpdb->get_row("SELECT * FROM $product_meta_table_name WHERE prod_id = '$prod_id' AND meta_key='slm_max_allowed_domains'", OBJECT); - if ($product_meta) { - //Found existing value so lets update it - //Better to do specific update (so the other meta values for example "download_limit_count" doesn't get set to empty). - $meta_key_name = "slm_max_allowed_domains"; - $meta_value = $prod_dat_array['slm_max_allowed_domains']; - $update_db_qry = "UPDATE $product_meta_table_name SET meta_value='$meta_value' WHERE prod_id='$prod_id' AND meta_key='$meta_key_name'"; - $results = $wpdb->query($update_db_qry); - } else { - //No value for this field was there so lets insert one. - $fields = array(); - $fields['prod_id'] = $prod_id; - $fields['meta_key'] = 'slm_max_allowed_domains'; - $fields['meta_value'] = $prod_dat_array['slm_max_allowed_domains']; - $result = $wpdb->insert($product_meta_table_name, $fields); - } - - //Find the existing value for the expiry date field (for the given product) - $product_meta = $wpdb->get_row("SELECT * FROM $product_meta_table_name WHERE prod_id = '$prod_id' AND meta_key='slm_date_of_expiry'", OBJECT); - if ($product_meta) { - //Found existing value so lets update it - //Better to do specific update (so the other meta values for example "download_limit_count" doesn't get set to empty). - $meta_key_name = "slm_date_of_expiry"; - $meta_value = $prod_dat_array['slm_date_of_expiry']; - $update_db_qry = "UPDATE $product_meta_table_name SET meta_value='$meta_value' WHERE prod_id='$prod_id' AND meta_key='$meta_key_name'"; - $results = $wpdb->query($update_db_qry); - } else { - //No value for this field was there so lets insert one. - $fields = array(); - $fields['prod_id'] = $prod_id; - $fields['meta_key'] = 'slm_date_of_expiry'; - $fields['meta_value'] = $prod_dat_array['slm_date_of_expiry']; - $result = $wpdb->insert($product_meta_table_name, $fields); - } -} - -function slm_estore_product_deleted($prod_id) -{ - global $wpdb; - $product_meta_table_name = WP_ESTORE_PRODUCTS_META_TABLE_NAME; - - $result = $wpdb->delete($product_meta_table_name, array('prod_id' => $prod_id, 'meta_key' => 'slm_max_allowed_domains')); - $result = $wpdb->delete($product_meta_table_name, array('prod_id' => $prod_id, 'meta_key' => 'slm_date_of_expiry')); -} - -/************************************/ -/*** End of WP eStore integration ***/ -/************************************/ diff --git a/admin/slm-about-menu.php b/admin/slm-about-menu.php index d107bbc..81d7fa7 100644 --- a/admin/slm-about-menu.php +++ b/admin/slm-about-menu.php @@ -13,49 +13,49 @@ function slm_about_menu() ?>

- +

-

+

-

+

- - + + - + - + - + diff --git a/admin/slm-add-licenses.php b/admin/slm-add-licenses.php index 889eacd..44a6619 100755 --- a/admin/slm-add-licenses.php +++ b/admin/slm-add-licenses.php @@ -1,6 +1,4 @@ sanitize_text_field($_POST['license_key']), - 'max_allowed_domains' => intval($_POST['max_allowed_domains']), - 'max_allowed_devices' => intval($_POST['max_allowed_devices']), - 'lic_status' => sanitize_text_field($_POST['lic_status']), - 'first_name' => sanitize_text_field($_POST['first_name']), - 'last_name' => sanitize_text_field($_POST['last_name']), - 'email' => is_email($_POST['email']) ? sanitize_email($_POST['email']) : '', - 'company_name' => sanitize_text_field($_POST['company_name']), - 'txn_id' => sanitize_text_field($_POST['txn_id']), - 'manual_reset_count' => intval($_POST['manual_reset_count']), - 'purchase_id_' => sanitize_text_field($_POST['purchase_id_']), - 'date_created' => isset($_POST['date_created']) ? SLM_API_Utility::slm_validate_date($_POST['date_created']) : date_i18n('Y-m-d'), // Default to today's date if not set - 'date_renewed' => SLM_API_Utility::slm_validate_date($_POST['date_renewed']), - 'date_activated' => SLM_API_Utility::slm_validate_date($_POST['date_activated']), - 'product_ref' => sanitize_text_field($_POST['product_ref']), - 'until' => sanitize_text_field($_POST['until']), - 'current_ver' => sanitize_text_field($_POST['current_ver']), - 'subscr_id' => sanitize_text_field($_POST['subscr_id']), - 'lic_type' => sanitize_text_field($_POST['lic_type']), - 'date_expiry' => ($_POST['lic_type'] === 'lifetime') ? date('Y-m-d', strtotime('+200 years')) : SLM_API_Utility::slm_validate_date($_POST['date_expiry']), - 'item_reference' => sanitize_text_field($_POST['item_reference']), - 'slm_billing_length' => sanitize_text_field($_POST['slm_billing_length']), - 'slm_billing_interval' => sanitize_text_field($_POST['slm_billing_interval']), - 'reminder_sent' => intval($_POST['reminder_sent']), - 'reminder_sent_date' => SLM_API_Utility::slm_validate_date($_POST['reminder_sent_date']), + 'license_key' => isset($_POST['license_key']) ? sanitize_text_field(wp_unslash($_POST['license_key'])) : '', + 'max_allowed_domains' => isset($_POST['max_allowed_domains']) ? intval(wp_unslash($_POST['max_allowed_domains'])) : 0, + 'max_allowed_devices' => isset($_POST['max_allowed_devices']) ? intval(wp_unslash($_POST['max_allowed_devices'])) : 0, + 'lic_status' => isset($_POST['lic_status']) ? sanitize_text_field(wp_unslash($_POST['lic_status'])) : '', + 'first_name' => isset($_POST['first_name']) ? sanitize_text_field(wp_unslash($_POST['first_name'])) : '', + 'last_name' => isset($_POST['last_name']) ? sanitize_text_field(wp_unslash($_POST['last_name'])) : '', + 'email' => isset($_POST['email']) && is_email(wp_unslash($_POST['email'])) ? sanitize_email(wp_unslash($_POST['email'])) : '', // Ensure unslash before sanitization + 'company_name' => isset($_POST['company_name']) ? sanitize_text_field(wp_unslash($_POST['company_name'])) : '', + 'txn_id' => isset($_POST['txn_id']) ? sanitize_text_field(wp_unslash($_POST['txn_id'])) : '', + 'manual_reset_count' => isset($_POST['manual_reset_count']) ? intval(wp_unslash($_POST['manual_reset_count'])) : 0, + 'purchase_id_' => isset($_POST['purchase_id_']) ? sanitize_text_field(wp_unslash($_POST['purchase_id_'])) : '', + 'date_created' => isset($_POST['date_created']) ? SLM_API_Utility::slm_validate_date(sanitize_text_field(wp_unslash($_POST['date_created']))) : date_i18n('Y-m-d'), // Default to today's date if not set + 'date_renewed' => isset($_POST['date_renewed']) ? SLM_API_Utility::slm_validate_date(sanitize_text_field(wp_unslash($_POST['date_renewed']))) : '', + 'date_activated' => isset($_POST['date_activated']) ? SLM_API_Utility::slm_validate_date(sanitize_text_field(wp_unslash($_POST['date_activated']))) : '', + 'product_ref' => isset($_POST['product_ref']) ? sanitize_text_field(wp_unslash($_POST['product_ref'])) : '', + 'until' => isset($_POST['until']) ? sanitize_text_field(wp_unslash($_POST['until'])) : '', + 'current_ver' => isset($_POST['current_ver']) ? sanitize_text_field(wp_unslash($_POST['current_ver'])) : '', + 'subscr_id' => isset($_POST['subscr_id']) ? sanitize_text_field(wp_unslash($_POST['subscr_id'])) : '', + 'lic_type' => isset($_POST['lic_type']) ? sanitize_text_field(wp_unslash($_POST['lic_type'])) : '', + 'date_expiry' => isset($_POST['lic_type']) && $_POST['lic_type'] === 'lifetime' ? gmdate('Y-m-d', strtotime('+200 years')) : (isset($_POST['date_expiry']) ? SLM_API_Utility::slm_validate_date(sanitize_text_field(wp_unslash($_POST['date_expiry']))) : ''), + 'item_reference' => isset($_POST['item_reference']) ? sanitize_text_field(wp_unslash($_POST['item_reference'])) : '', + 'slm_billing_length' => isset($_POST['slm_billing_length']) ? sanitize_text_field(wp_unslash($_POST['slm_billing_length'])) : '', + 'slm_billing_interval' => isset($_POST['slm_billing_interval']) ? sanitize_text_field(wp_unslash($_POST['slm_billing_interval'])) : '', + 'reminder_sent' => isset($_POST['reminder_sent']) ? intval(wp_unslash($_POST['reminder_sent'])) : 0, + 'reminder_sent_date' => isset($_POST['reminder_sent_date']) ? SLM_API_Utility::slm_validate_date(sanitize_text_field(wp_unslash($_POST['reminder_sent_date']))) : '', ]; // Check for required fields if (empty($data['email']) || empty($data['date_created']) || ($data['lic_type'] !== 'lifetime' && empty($data['date_expiry'])) || empty($data['lic_type'])) { - echo '

' . __('Required fields are missing.', 'slmplus') . '

'; + echo '

' . esc_html__('Required fields are missing.', 'slm-plus') . '

'; } else { // Insert or update the data in the database if ($id) { $wpdb->update(SLM_TBL_LICENSE_KEYS, $data, ['id' => $id]); - echo '

' . __('License updated successfully.', 'slmplus') . '

'; + echo '

' . esc_html__('License updated successfully.', 'slm-plus') . '

'; } else { $wpdb->insert(SLM_TBL_LICENSE_KEYS, $data); - echo '

' . __('License created successfully.', 'slmplus') . '

'; - echo '' . __('View License', 'slmplus') . '

'; + echo '

' . esc_html__('License created successfully.', 'slm-plus') . '

'; + echo '' . esc_html__('View License', 'slm-plus') . '

'; } } - } - else { + } else { // If editing, load existing data if ($id) { - $license = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE id = %d", $id)); + // Sanitize the $id to make sure it's an integer + $id = intval($id); + + // Define the table name as a constant + $table_name = SLM_TBL_LICENSE_KEYS; + + // Use $wpdb->prepare() for the actual query with a placeholder for the ID + $query = $wpdb->prepare( + "SELECT * FROM {$table_name} WHERE id = %d", // Use %d for the integer placeholder + $id + ); + + // Get the result using the prepared query + $license = $wpdb->get_row($query); + if ($license) { $data = (array) $license; + } else { + // If the license is not found, reset to create a new record + $data = [ + 'license_key' => '', + 'max_allowed_domains' => SLM_DEFAULT_MAX_DOMAINS, + 'max_allowed_devices' => SLM_DEFAULT_MAX_DEVICES, + 'lic_status' => 'pending', + 'first_name' => '', + 'last_name' => '', + 'email' => '', + 'company_name' => '', + 'txn_id' => '', + 'purchase_id_' => '', + 'date_created' => date_i18n($slm_wp_date_format, strtotime('now')), + 'date_renewed' => '', + 'date_activated' => '', + 'product_ref' => '', + 'until' => '', + 'current_ver' => '', + 'subscr_id' => '', + 'lic_type' => 'subscription', + 'date_expiry' => $date_expiry, // Set a default expiry + 'item_reference' => '', + 'slm_billing_length' => $slm_billing_length, + 'slm_billing_interval' => $slm_billing_interval, + 'reminder_sent' => '0', + 'manual_reset_count' => '', + 'reminder_sent_date' => '0000-00-00' + ]; + + // Add error message that license key wasn't found + echo '

' . esc_html__('License key not found. Please create a new license.', 'slm-plus') . '

'; } } else { - - // Prepare empty data for new record + // Prepare empty data for a new record $data = [ 'license_key' => '', 'max_allowed_domains' => SLM_DEFAULT_MAX_DOMAINS, 'max_allowed_devices' => SLM_DEFAULT_MAX_DEVICES, - 'lic_status' => 'pending', // Default value + 'lic_status' => 'pending', 'first_name' => '', 'last_name' => '', 'email' => '', 'company_name' => '', 'txn_id' => '', - 'manual_reset_count' => '', 'purchase_id_' => '', - 'date_created' => date_i18n($slm_wp_date_format, strtotime('now')), // Use WP date format + 'date_created' => date_i18n($slm_wp_date_format, strtotime('now')), 'date_renewed' => '', 'date_activated' => '', 'product_ref' => '', @@ -105,47 +147,48 @@ function slm_add_licenses_menu() 'current_ver' => '', 'subscr_id' => '', 'lic_type' => 'subscription', - 'date_expiry' => $date_expiry, // Calculated expiration date + 'date_expiry' => $date_expiry, 'item_reference' => '', 'slm_billing_length' => $slm_billing_length, 'slm_billing_interval' => $slm_billing_interval, 'reminder_sent' => '0', + 'manual_reset_count' => '', 'reminder_sent_date' => '0000-00-00' ]; - // Generate a license key if it's a new record - if (!isset($editing_record)) { - $editing_record = new stdClass(); - } - + // Generate a license key for new records $data['license_key'] = slm_get_license(KEY_API_PREFIX); } } ?>
-

+

+ +
- @@ -156,42 +199,41 @@ function slm_add_licenses_menu() // Fetch the log data using a utility function to handle the database query $log_entries = SLM_Helper_Class::get_license_logs($license_key); - // Display the log table if there are any log entries - if ($log_entries) { - ?> -
-

-
Michel Velis - + tipsandtricks
- +
- +
- - - - - - - - - - - - - - - - - - -
-
- ' . __('No activity log found for this license.', 'slmplus') . '

'; - } + // Display the log table if there are any log entries + if ($log_entries) { ?> - - +

+ + + + + + + + + + + + + + + + + + + +
+
+ ' . esc_html__('No activity log found for this license.', 'slm-plus') . '

'; + } + ?> + + get_row($wpdb->prepare( "SELECT max_allowed_domains, max_allowed_devices FROM " . SLM_TBL_LICENSE_KEYS . " WHERE license_key = %s", $license_key )); - + // Ensure the max values are retrieved and set them to default values if not found $max_domains = isset($license_info->max_allowed_domains) ? intval($license_info->max_allowed_domains) : 0; $max_devices = isset($license_info->max_allowed_devices) ? intval($license_info->max_allowed_devices) : 0; - + // Fetch the current number of registered domains for this license key $registered_domains = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM " . SLM_TBL_LIC_DOMAIN . " WHERE lic_key = %s", $license_key )); - + // Fetch the current number of registered devices for this license key $registered_devices = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM " . SLM_TBL_LIC_DEVICES . " WHERE lic_key = %s", $license_key )); - + // Ensure the count values are integers $registered_domains = isset($registered_domains) ? intval($registered_domains) : 0; $registered_devices = isset($registered_devices) ? intval($registered_devices) : 0; - + // Calculate how many domains and devices are left $domains_left = $max_domains - $registered_domains; $devices_left = $max_devices - $registered_devices; - + // Ensure the result is not negative (to handle edge cases) $domains_left = max(0, $domains_left); $devices_left = max(0, $devices_left); - + // Fetch all registered domains for this license key $registered_domains_data = $wpdb->get_results($wpdb->prepare( "SELECT id, registered_domain FROM " . SLM_TBL_LIC_DOMAIN . " WHERE lic_key = %s", $license_key )); - + // Fetch all registered devices for this license key $registered_devices_data = $wpdb->get_results($wpdb->prepare( "SELECT id, registered_devices FROM " . SLM_TBL_LIC_DEVICES . " WHERE lic_key = %s", $license_key )); - - $slm_ajax_uri =''; + + $slm_ajax_uri = ''; $slm_deactivate_nonce = wp_create_nonce('slmplus_delete_activation_nonce'); // Render the table - ?> + ?>
-

+

- :
- : -

+ :
+ : +

- - - - - + + + + + registered_domain); + $slm_ajax_uri = esc_url(home_url('/')) . '?slm_action=slm_deactivate&secret_key=' . VERIFY_KEY_API . '&license_key=' . esc_html($license_key) . '®istered_domain=' . esc_html($domain_entry->registered_domain); ?> - + @@ -294,27 +336,28 @@ function slm_add_licenses_menu() registered_devices); + $slm_ajax_uri = esc_url(home_url('/')) . '?slm_action=slm_deactivate&secret_key=' . VERIFY_KEY_API . '&license_key=' . esc_html($license_key) . '®istered_devices=' . esc_html($device_entry->registered_devices); ?> - + - + + +
id); ?> registered_domain); ?> - +
id); ?> registered_devices); ?> - - +
@@ -346,12 +389,12 @@ function slm_add_licenses_menu() _wpnonce: nonce // Include the nonce in the request }, function(response) { ////console.log(response); // Debugging to ensure we're getting the response - + // Handle success response if (response.result === 'success') { // Show WordPress-style success message $('.slm_ajax_msg').html('

' + response.message + '

'); - + // Remove the entire row or element containing the button $button.closest('tr').remove(); // Adjust the selector to the parent element of the row or item you want to remove } else { @@ -364,18 +407,17 @@ function slm_add_licenses_menu() }); }); }); - - 'error', - 'message' => __('Nonce verification failed.', 'slmplus'), + 'message' => __('Nonce verification failed.', 'slm-plus'), 'error_code' => 401 ]); } @@ -383,16 +425,15 @@ function slm_add_licenses_menu() global $wpdb; // Check if the activation ID and type are provided and valid - if (!isset($_POST['activation_id']) || !is_numeric($_POST['activation_id']) || !isset($_POST['activation_type'])) { + if (!isset($_POST['activation_id']) || !is_numeric(wp_unslash($_POST['activation_id'])) || !isset($_POST['activation_type']) || empty($_POST['activation_type'])) { wp_send_json_error([ 'result' => 'error', - 'message' => __('Invalid activation data.', 'slmplus'), + 'message' => __('Invalid activation data.', 'slm-plus'), 'error_code' => 400 ]); } - - $activation_id = intval($_POST['activation_id']); - $activation_type = sanitize_text_field($_POST['activation_type']); + $activation_id = isset($_POST['activation_id']) ? intval(wp_unslash($_POST['activation_id'])) : 0; + $activation_type = isset($_POST['activation_type']) ? sanitize_text_field(wp_unslash($_POST['activation_type'])) : ''; // Delete the activation from the correct table if ($activation_type === 'domain') { @@ -402,7 +443,7 @@ function slm_add_licenses_menu() } else { wp_send_json_error([ 'result' => 'error', - 'message' => __('Invalid activation type.', 'slmplus'), + 'message' => __('Invalid activation type.', 'slm-plus'), 'error_code' => 400 ]); } @@ -411,13 +452,13 @@ function slm_add_licenses_menu() if ($result !== false) { wp_send_json_success([ 'result' => 'success', - 'message' => __('The license key has been deactivated for this domain.', 'slmplus'), + 'message' => __('The license key has been deactivated for this domain.', 'slm-plus'), 'error_code' => 360 ]); } else { wp_send_json_error([ 'result' => 'error', - 'message' => __('Error deleting activation.', 'slmplus'), + 'message' => __('Error deleting activation.', 'slm-plus'), 'error_code' => 500 ]); } @@ -425,42 +466,42 @@ function slm_add_licenses_menu() ?> -
+ -

+

- + - + - + - + @@ -473,116 +514,136 @@ function slm_add_licenses_menu() -

+

- + - + - + - - + - + - + - + - + - + - + @@ -590,28 +651,28 @@ function slm_add_licenses_menu() -

+

- + - readonly />
get_results("SELECT status_key, status_label FROM $lic_status_table ", ARRAY_A); - + $lic_status_table = esc_sql($lic_status_table); + + // Now prepare the query with placeholders for values, not the table name. + $query = "SELECT status_key, status_label FROM $lic_status_table"; // No placeholders needed for table name + $statuses = $wpdb->get_results($query, ARRAY_A); + // Create the '; foreach ($statuses as $status) { // Set the selected attribute if the current status matches $selected = selected($data['lic_status'], $status['status_key'], false); - echo ''; + echo ''; } echo ''; ?>
readonly class="regular-text datepicker" required/> -

+
readonly class="regular-text datepicker" required /> +

+ +

-

Choose this date to set when the license should renew or expire.
Format: %s (input: YYYY-MM-DD).', 'slmplus'), $slm_wp_date_format); ?>

+

+ Choose this date to set when the license should renew or expire.
Format: %s (input: YYYY-MM-DD).', 'slm-plus'), esc_html($slm_wp_date_format)); + ?> +

- +

- +

- +

- +

-

- +

-

- +

- + - + - + - + @@ -619,36 +680,39 @@ function slm_add_licenses_menu() -

+

- + - + - + - + - +
-

- +

@@ -656,9 +720,9 @@ function slm_add_licenses_menu()
- + - + -
diff --git a/admin/slm-admin-functions.php b/admin/slm-admin-functions.php index 083e2e4..7faa4e9 100755 --- a/admin/slm-admin-functions.php +++ b/admin/slm-admin-functions.php @@ -7,77 +7,184 @@ if (!defined('WPINC')) { function slm_admin_tools_menu() { if (isset($_POST['slm_backup_db'])) { - slm_save_backup_to_uploads(); + // Verify the nonce + if (isset($_POST['slm_backup_nonce_field']) && wp_verify_nonce($_POST['slm_backup_nonce_field'], 'slm_backup_nonce_action')) { + // Nonce is valid, proceed with backup + SLM_Utility::slm_save_backup_to_uploads(); + } else { + // Nonce is invalid or missing + die('Security check failed.'); // You can display an error message or handle it as needed + } } echo '
'; - echo '

'. __('SLM Plus - Tools', 'slmplus') . '

'; + echo '

' . esc_html__('SLM Plus - Tools', 'slm-plus') . '

'; echo '
'; if (isset($_POST['send_deactivation_request'])) { - $postURL = esc_url_raw($_POST['slm_deactivation_req_url']); - $secretKeyForVerification = slm_get_option('lic_verification_secret'); - $data = array('secret_key' => $secretKeyForVerification); + // Verify the nonce + if (isset($_POST['slm_deactivation_nonce_field']) && wp_verify_nonce($_POST['slm_deactivation_nonce_field'], 'slm_deactivation_nonce_action')) { + // Nonce is valid, proceed with the deactivation request - $ch = curl_init($postURL); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - $returnValue = curl_exec($ch); + $postURL = esc_url_raw($_POST['slm_deactivation_req_url']); + $secretKeyForVerification = slm_get_option('lic_verification_secret'); + $data = array('secret_key' => $secretKeyForVerification); - $msg = ""; - if ($returnValue == "Success") { - $msg .= __('Success message returned from the remote host.', 'slmplus'); + // Make the POST request using wp_remote_post + $response = wp_remote_post($postURL, array( + 'method' => 'POST', + 'body' => $data, + 'timeout' => 15, // Optional timeout value + 'headers' => array('Content-Type' => 'application/x-www-form-urlencoded') + )); + + // Check for errors in the response + if (is_wp_error($response)) { + $error_message = $response->get_error_message(); + $msg = esc_html__('Request failed: ', 'slm-plus') . esc_html($error_message); + } else { + $body = wp_remote_retrieve_body($response); + + // Check for success message in response + if ($body == "Success") { + $msg = esc_html__('Success message returned from the remote host.', 'slm-plus'); + } else { + $msg = esc_html__('Unexpected response: ', 'slm-plus') . esc_html($body); + } + } + + // Display message + echo '

'; + echo esc_html__('Request sent to the specified URL!', 'slm-plus'); + echo '
' . esc_html($msg); + echo '

'; + } else { + // Nonce is invalid or missing + echo '

' . esc_html__('Security check failed. Invalid nonce.', 'slm-plus') . '

'; } - echo '

'; - echo __('Request sent to the specified URL!', 'slmplus'); - echo '
' . esc_html($msg); - echo '

'; } + if (isset($_POST['slm_clear_log'])) { - global $wpdb, $slm_debug_logger; - $table = SLM_TBL_LIC_LOG; - $wpdb->query("TRUNCATE TABLE $table"); - $slm_debug_logger->reset_log_file("log.txt"); - $slm_debug_logger->reset_log_file("log-cron-job.txt"); + // Verify the nonce + if (isset($_POST['slm_clear_log_nonce_field']) && wp_verify_nonce($_POST['slm_clear_log_nonce_field'], 'slm_clear_log_nonce_action')) { + // Nonce is valid, proceed with clearing the log - echo '

' . esc_html__('Log was cleared successfully!', 'slmplus') . '

'; + global $wpdb, $slm_debug_logger; + + // Define the table name using the constant (already assumed to be done securely) + $table = SLM_TBL_LIC_LOG; + + // Sanitize the table name if it's dynamically passed (for security) + $table = sanitize_key($table); // sanitize_key ensures a safe table name, although here it's already defined + + // Sanitize and validate other variables if used dynamically + + // Direct query execution for truncating the table + if ($wpdb->get_var("SHOW TABLES LIKE '$table'")) { // Check if table exists + $query = "TRUNCATE TABLE `$table`"; // Backticks are used to prevent issues with reserved SQL keywords + $wpdb->query($query); // Direct query execution + } else { + // Handle the case where the table doesn't exist + error_log('Table not found: ' . $table); + } + + // Reset log files + $slm_debug_logger->reset_log_file("log.txt"); + $slm_debug_logger->reset_log_file("log-cron-job.txt"); + + echo '

' . esc_html__('Log was cleared successfully!', 'slm-plus') . '

'; + } else { + // Nonce is invalid or missing + echo '

' . esc_html__('Security check failed. Invalid nonce.', 'slm-plus') . '

'; + } } - ?> +?>
-

+

+
- + +
+
+
+
+ + +
+

+
+

+ +

+
+ + + + + + + +
+ +

' . esc_html__('New Creation Secret Key:', 'slm-plus') . ' ' . esc_html($_GET['new_creation_secret']) . '

'; + } + if (isset($_GET['new_verification_secret'])) { + echo '

' . esc_html__('New Verification Secret Key:', 'slm-plus') . ' ' . esc_html($_GET['new_verification_secret']) . '

'; + } + ?> +
+
+ + $new_creation_secret])); + wp_redirect(add_query_arg(['slm_notice' => 'creation_key_reset', 'new_creation_secret' => $new_creation_secret], $_SERVER['REQUEST_URI'])); + exit; + } + + if (isset($_POST['reset_verification_secret']) && check_admin_referer('slm_reset_secret_keys_nonce_action', 'slm_reset_secret_keys_nonce_field')) { + $new_verification_secret = SLM_Utility::create_secret_keys(); // Generate new verification secret + update_option('slm_plugin_options', array_merge(get_option('slm_plugin_options', []), ['lic_verification_secret' => $new_verification_secret])); + wp_redirect(add_query_arg(['slm_notice' => 'verification_key_reset', 'new_verification_secret' => $new_verification_secret], $_SERVER['REQUEST_URI'])); + exit; + } + } + ?> + + +
+

+
+

+
+
+ +
-

+

-

+

+
- -
-
-
-
- -
-

-
-

-
-
- +
@@ -87,19 +194,19 @@ function slm_admin_tools_menu() if (!empty($backup_info)) { $backup_url = esc_url($backup_info['url']); $backup_date = esc_html($backup_info['date']); - echo '

' . __('Last backup created on: ', 'slmplus') . $backup_date . ' - ' . __('Download Backup', 'slmplus') . '

'; + echo '

' . esc_html__('Last backup created on: ', 'slm-plus') . esc_html($backup_date) . ' - ' . esc_html__('Download Backup', 'slm-plus') . '

'; } ?>
-

+

- - - + + +

@@ -109,32 +216,32 @@ function slm_admin_tools_menu() - + - + @@ -144,7 +251,7 @@ function slm_admin_tools_menu()
-

+

    @@ -162,13 +269,13 @@ function slm_admin_tools_menu() // Validation: Check if fields are empty if (!productID) { - $('#license-result-list').html('
  • Error:
  • '); - alert(''); + $('#license-result-list').html('
  • Error:
  • '); + alert(''); return; // Stop submission if Product ID is empty } if (!subscriptionType) { - $('#license-result-list').html('
  • Error:
  • '); - alert(''); + $('#license-result-list').html('
  • Error:
  • '); + alert(''); return; // Stop submission if Subscription Type is empty } @@ -189,24 +296,23 @@ function slm_admin_tools_menu() $.post(ajaxurl, data, function(response) { //console.log('AJAX response:', response); if (response.success) { - $('#license-result-list').html(response.data.html); - alert(''); + $('#license-result-list').html(response.data.html); + alert(''); } else { $('#license-result-list').html(response.data.html); - alert(''); + alert(''); } }).fail(function(xhr, status, error) { console.error('AJAX error:', status, error); - $('#license-result-list').html('
  • Error:
  • '); - alert(''); + $('#license-result-list').html('
  • Error:
  • '); + alert(''); }); }); }); - '; - echo ''; +'; } /** @@ -215,77 +321,13 @@ function slm_admin_tools_menu() function slm_get_unique_hash() { $hash = slm_get_option('slm_backup_dir_hash'); - if (!$hash) { $hash = wp_generate_password(8, false, false); // Generate random 8-character hash slm_update_option('slm_backup_dir_hash', $hash); } - return $hash; } -/** - * Saves a backup of the plugin's database tables in a secure folder. - */ -function slm_save_backup_to_uploads() -{ - global $wpdb; - - // Get the upload directory - $upload_dir = wp_upload_dir(); - $unique_hash = slm_get_unique_hash(); // Generate or retrieve the unique hash - $slm_backup_dir = $upload_dir['basedir'] . $unique_hash; - - // Create the slm-plus folder with hash if it doesn't exist - if (!file_exists($slm_backup_dir)) { - wp_mkdir_p($slm_backup_dir); - } - - // Set backup file name and path - $backup_file = $slm_backup_dir . '/slm_plugin_backup_' . date('Y-m-d_H-i-s') . '.sql'; - - // Get plugin tables - $backup_tables = [ - SLM_TBL_LICENSE_KEYS, - SLM_TBL_LIC_DOMAIN, - SLM_TBL_LIC_DEVICES, - SLM_TBL_LIC_LOG, - SLM_TBL_EMAILS, - SLM_TBL_LICENSE_STATUS - ]; - - $sql = ""; - foreach ($backup_tables as $table) { - // Get table structure - $create_table_query = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N); - $sql .= "\n\n" . $create_table_query[0][1] . ";\n\n"; - - // Get table data - $rows = $wpdb->get_results("SELECT * FROM $table", ARRAY_A); - foreach ($rows as $row) { - $values = array_map('esc_sql', array_values($row)); // Use esc_sql to escape the values - $values = "'" . implode("','", $values) . "'"; - $sql .= "INSERT INTO $table VALUES ($values);\n"; - } - } - - // Save the SQL to a file in the slm-plus folder - if (file_put_contents($backup_file, $sql)) { - $backup_url = $upload_dir['baseurl'] . $unique_hash . '/' . basename($backup_file); - - // Save backup info in plugin options - $backup_info = [ - 'url' => $backup_url, - 'date' => date('Y-m-d H:i:s') - ]; - slm_update_option('slm_last_backup_info', $backup_info); - - echo '

    ' . __('Backup created successfully! Download from: ', 'slmplus') . '' . esc_html(basename($backup_file)) . '

    '; - } else { - echo '

    ' . __('Error: Failed to create the backup file.', 'slmplus') . '

    '; - } -} - /** * Retrieves an option from the slm_plugin_options. diff --git a/admin/slm-dashboard-widgets.php b/admin/slm-dashboard-widgets.php index a351a47..1a229da 100644 --- a/admin/slm-dashboard-widgets.php +++ b/admin/slm-dashboard-widgets.php @@ -27,39 +27,39 @@ function slm_add_dashboard_widgets() function add_toolbar_items($admin_bar){ $admin_bar->add_menu(array( 'id' => 'slm-menu', - 'title' => '' . __('SLM Plus', 'slmplus'), + 'title' => '' . __('SLM Plus', 'slm-plus'), // Added text domain 'href' => admin_url('admin.php?page=slm_overview'), 'meta' => array( - 'title' => __('SLM'), + 'title' => __('slm-plus', 'slm-plus'), // Added text domain ), )); $admin_bar->add_menu(array( 'id' => 'slm-manage-licenses-overview', 'parent' => 'slm-menu', - 'title' => 'Overview', + 'title' => __('Overview', 'slm-plus'), // Added text domain 'href' => admin_url('admin.php?page=slm_overview'), 'meta' => array( - 'title' => __('Overview'), + 'title' => __('Overview', 'slm-plus'), // Added text domain 'class' => 'slm_overview_menu' ), )); $admin_bar->add_menu(array( 'id' => 'slm-manage-licenses-addnew', 'parent' => 'slm-menu', - 'title' => 'Add new license', + 'title' => __('Add new license', 'slm-plus'), // Added text domain 'href' => admin_url('admin.php?page=slm_manage_license'), 'meta' => array( - 'title' => __( 'Add new license'), + 'title' => __('Add new license', 'slm-plus'), // Added text domain 'class' => 'slm_addlicense_menu' ), )); $admin_bar->add_menu(array( 'id' => 'slm-manage-licenses-settings', 'parent' => 'slm-menu', - 'title' => 'Settings', + 'title' => __('Settings', 'slm-plus'), // Added text domain 'href' => admin_url( 'admin.php?page=slm_settings'), 'meta' => array( - 'title' => __('Settings'), + 'title' => __('Settings', 'slm-plus'), // Added text domain 'class' => 'slm_settings_menu' ), )); @@ -72,61 +72,62 @@ function add_toolbar_items($admin_bar){ function slm_dashboard_widget_function() { ?> - + + +
    +
    +
    - -

    + +

    -

    +

    - /> + />

    - +

    + + + + + + + + +
    + +  –  +
    +
    -
    -
    - - - - - - - - - -
    - -  –  -
    -
    -

    - +

    + -
    -
    -
    +
    +
    +
    -

    +

    -

    - +

    + -

    - +

    + -

    - +

    +
    +
    -

    +

    -

    +

    - +

    -

    +

    - - - + + +

    ' . __('Options updated!', 'slmplus') . '

    '; + echo '

    ' . esc_html__('Options updated!', 'slm-plus') . '

    '; } $secret_key = !empty($options['lic_creation_secret']) ? $options['lic_creation_secret'] : SLM_Utility::create_secret_keys(); @@ -82,26 +82,27 @@ function slm_general_settings()
    -

    +

    @@ -112,49 +113,48 @@ function slm_general_settings()
    - - + - - + - - + - - + - - + - - + - - + @@ -164,37 +164,37 @@ function slm_general_settings() ?> - + +

    - + - + - + @@ -202,25 +202,25 @@ function slm_general_settings() - + - + @@ -229,14 +229,14 @@ function slm_general_settings()
    -

    +

    -

    +
    +

    -

    +
    +

    -

    +
    +

    -

    +
    +

    -

    +
    +

    -

    +
    +

    -

    +
    +

    -

    -

    -

    +

    +

    value="1" /> - -

    + +

    value="1" /> - +
    value="1" /> - +
    value="1" /> - -

    + +

    value="1" /> - -

    + +

    - + @@ -244,11 +244,11 @@ function slm_general_settings() @@ -257,28 +257,28 @@ function slm_general_settings()
    value="1" /> - +
    value="1" /> - +

    - - - + + +

    value="1" /> - +
    value="1" /> - +
    -

    +
    @@ -286,31 +286,31 @@ function slm_general_settings()
    - + - + - + - + @@ -323,7 +323,7 @@ function slm_general_settings()

    value="1" /> -

    +

    -

    +

    -

    +

    -

    +

    - + @@ -333,7 +333,7 @@ function slm_general_settings()
    - +
    diff --git a/admin/slm-list-licenses-class.php b/admin/slm-list-licenses-class.php index 3eb3750..88c2477 100755 --- a/admin/slm-list-licenses-class.php +++ b/admin/slm-list-licenses-class.php @@ -24,7 +24,7 @@ class SLM_List_Licenses extends WP_List_Table public function no_items() { - _e('No licenses avaliable.', 'slmplus'); + esc_html_e('No licenses avaliable.', 'slm-plus'); } function get_views() @@ -40,35 +40,35 @@ class SLM_List_Licenses extends WP_List_Table $link_html, esc_url(remove_query_arg('view', $base)), $current === 'all' || $current == '' ? ' class="current"' : '', - esc_html__('All', 'slmplus'), + esc_html__('All', 'slm-plus'), SLM_Utility::get_total_licenses() ), 'active' => sprintf( $link_html, esc_url(add_query_arg('view', 'active', $base . '&s=active')), $current === 'active' ? ' class="current"' : '', - esc_html__('active', 'slmplus'), + esc_html__('active', 'slm-plus'), SLM_Utility::count_licenses('active') ), 'pending' => sprintf( $link_html, esc_url(add_query_arg('view', 'pending', $base . '&s=pending')), $current === 'pending' ? ' class="current"' : '', - esc_html__('pending', 'slmplus'), + esc_html__('pending', 'slm-plus'), SLM_Utility::count_licenses('pending') ), 'expired' => sprintf( $link_html, esc_url(add_query_arg('view', 'expired', $base . '&s=expired')), $current === 'expired' ? ' class="current"' : '', - esc_html__('expired', 'slmplus'), + esc_html__('expired', 'slm-plus'), SLM_Utility::count_licenses('expired') ), 'blocked' => sprintf( $link_html, esc_url(add_query_arg('view', 'blocked', $base . '&s=blocked')), $current === 'blocked' ? ' class="current"' : '', - esc_html__('blocked', 'slmplus'), + esc_html__('blocked', 'slm-plus'), SLM_Utility::count_licenses('blocked') ) ); @@ -81,21 +81,21 @@ class SLM_List_Licenses extends WP_List_Table { $columns = array( 'cb' => '', //Render a checkbox - 'id' => __('ID', 'slmplus'), - 'lic_status' => __('Status', 'slmplus'), - 'license_key' => __('Key', 'slmplus'), - 'item_reference' => __('Item reference', 'slmplus'), - 'lic_type' => __('License type', 'slmplus'), - 'email' => __('Email', 'slmplus'), - 'max_allowed_domains' => __('Domains', 'slmplus'), - 'max_allowed_devices' => __('Devices', 'slmplus'), - 'purchase_id_' => __('Order #', 'slmplus'), - 'date_created' => __('Created on', 'slmplus'), - 'date_renewed' => __('Renewed on', 'slmplus'), - 'date_activated' => __('Activated on', 'slmplus'), - 'date_expiry' => __('Expiration', 'slmplus'), - 'until' => __('Until Ver.', 'slmplus'), - 'current_ver' => __('Current Ver.', 'slmplus') + 'id' => __('ID', 'slm-plus'), + 'lic_status' => __('Status', 'slm-plus'), + 'license_key' => __('Key', 'slm-plus'), + 'item_reference' => __('Item reference', 'slm-plus'), + 'lic_type' => __('License type', 'slm-plus'), + 'email' => __('Email', 'slm-plus'), + 'max_allowed_domains' => __('Domains', 'slm-plus'), + 'max_allowed_devices' => __('Devices', 'slm-plus'), + 'purchase_id_' => __('Order #', 'slm-plus'), + 'date_created' => __('Created on', 'slm-plus'), + 'date_renewed' => __('Renewed on', 'slm-plus'), + 'date_activated' => __('Activated on', 'slm-plus'), + 'date_expiry' => __('Expiration', 'slm-plus'), + 'until' => __('Until Ver.', 'slm-plus'), + 'current_ver' => __('Current Ver.', 'slm-plus') ); return $columns; } @@ -117,19 +117,17 @@ class SLM_List_Licenses extends WP_List_Table $date_today = time(); if ($expiration == '0000-00-00') { - return ''. __(' Lifetime ','slmplus'). '' . ' '; + return '' . __(' Lifetime ', 'slm-plus') . '' . ' '; } if ($expiration != '0000-00-00') { if (strtotime($expiration) < time()) { return ' ' . $expiration . ' ' . ' ' . SLM_Utility::get_days_remaining($expiration) . ' day(s) due'; - } - else { + } else { return '' . $item[$column_name] . '' . ' ' . SLM_Utility::get_days_remaining($expiration) . ' day(s) left'; } - } - else { + } else { //return $item[$column_name]; return 'not set'; } @@ -204,94 +202,94 @@ class SLM_List_Licenses extends WP_List_Table ); return $actions; } - + function process_bulk_action() { if ('delete' === $this->current_action()) { //Process delete bulk actions if (!isset($_REQUEST['item'])) { - $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slmplus') . '

    '; - echo '
    ' . $error_msg . '
    '; + $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slm-plus') . '

    '; + echo '
    ' . esc_html($error_msg) . '
    '; return; } else { $nvp_key = $this->_args['singular']; $records_to_delete = $_GET[$nvp_key]; - + foreach ($records_to_delete as $row) { SLM_Utility::delete_license_key_by_row_id($row); } - + echo '

    Selected records deleted successfully!

    '; } } - + if ('blocked' === $this->current_action()) { //Process blocked bulk actions if (!isset($_REQUEST['item'])) { - $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slmplus') . '

    '; - echo '
    ' . $error_msg . '
    '; + $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slm-plus') . '

    '; + echo '
    ' . esc_html($error_msg) . '
    '; return; } else { $nvp_key = $this->_args['singular']; $licenses_to_block = $_GET[$nvp_key]; - + foreach ($licenses_to_block as $row) { SLM_Utility::block_license_key_by_row_id($row); } - - echo '

    ' . $row . ' Selected records blocked successfully!

    '; + + echo '

    ' . esc_html($row) . ' ' . esc_html__('Selected records blocked successfully!', 'slm-plus') . '

    '; } } - + if ('expired' === $this->current_action()) { //Process expired bulk actions if (!isset($_REQUEST['item'])) { - $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slmplus') . '

    '; - echo '
    ' . $error_msg . '
    '; + $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slm-plus') . '

    '; + echo '
    ' . esc_html($error_msg) . '
    '; return; } else { $nvp_key = $this->_args['singular']; $licenses_to_expire = $_GET[$nvp_key]; - + foreach ($licenses_to_expire as $row) { SLM_Utility::expire_license_key_by_row_id($row); } - - echo '

    ' . $row . ' Selected records expired successfully!

    '; + + echo '

    ' . esc_html($row) . ' ' . esc_html__('Selected records expired successfully!', 'slm-plus') . '

    '; } } - + if ('active' === $this->current_action()) { //Process activate bulk actions if (!isset($_REQUEST['item'])) { - $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slmplus') . '

    '; - echo '
    ' . $error_msg . '
    '; + $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slm-plus') . '

    '; + echo '
    ' . esc_html($error_msg) . '
    '; return; } else { $nvp_key = $this->_args['singular']; $liceses_to_activate = $_GET[$nvp_key]; - + foreach ($liceses_to_activate as $row) { SLM_Utility::active_license_key_by_row_id($row); } - - echo '

    ' . $row . ' Selected records activated successfully!

    '; + + echo '

    ' . esc_html($row) . ' ' . esc_html__('Selected records activated successfully!', 'slm-plus') . '

    '; } } - + // Export license data if ('export' === $this->current_action()) { if (!isset($_REQUEST['item'])) { - $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slmplus') . '

    '; - echo '
    ' . $error_msg . '
    '; + $error_msg = '

    ' . __('Error - Please select some records using the checkboxes', 'slm-plus') . '

    '; + echo '
    ' . esc_html($error_msg) . '
    '; return; } else { $nvp_key = $this->_args['singular']; $licenses_to_export = $_GET[$nvp_key]; - + // Call the export function $file_urls = self::export_license_data($licenses_to_export); - + // Display success message with download links for each license echo '
    '; echo '

    Export successful! Download the CSV files:

    '; @@ -302,58 +300,73 @@ class SLM_List_Licenses extends WP_List_Table } } } - -// Export function -public static function export_license_data($license_ids) -{ - global $wpdb; - // Fetch the custom directory path from options (saved with hash) - $slm_options = get_option('slm_plugin_options'); - $custom_dir_hash = isset($slm_options['slm_backup_dir_hash']) ? $slm_options['slm_backup_dir_hash'] : ''; + public static function export_license_data($license_ids) + { + global $wpdb; - // Prepare file URLs array - $file_urls = []; + // Fetch the custom directory path from options (saved with hash) + $slm_options = get_option('slm_plugin_options'); + $custom_dir_hash = isset($slm_options['slm_backup_dir_hash']) ? $slm_options['slm_backup_dir_hash'] : ''; - // Get the WordPress upload directory - $upload_dir = wp_upload_dir(); - $custom_dir = $upload_dir['basedir'] . $custom_dir_hash; + // Prepare file URLs array + $file_urls = []; - // Ensure the directory exists - if (!file_exists($custom_dir)) { - mkdir($custom_dir, 0755, true); // Create the directory if it doesn't exist - } + // Get the WordPress upload directory + $upload_dir = wp_upload_dir(); + $custom_dir = $upload_dir['basedir'] . '/' . $custom_dir_hash; - // Fetch license data for each selected ID - foreach ($license_ids as $license_id) { - $data = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE id = %d", $license_id), ARRAY_A); - if ($data) { - $license_key = $data['license_key']; - - // Prepare file name as "license_key.csv" - $file_name = sanitize_file_name($license_key) . '.csv'; - $file_path = $custom_dir . '/' . $file_name; - - // Open file handle - $output = fopen($file_path, 'w'); - - // Write CSV headers - fputcsv($output, array_keys($data)); - - // Write license data to CSV file - fputcsv($output, $data); - - // Close the file handle - fclose($output); - - // Store the file URL for download - $file_urls[] = $upload_dir['baseurl'] . $custom_dir_hash . '/' . $file_name; + // Initialize WP_Filesystem for safe file handling + if (empty($GLOBALS['wp_filesystem'])) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + WP_Filesystem(); } + + // Ensure the directory exists using WP_Filesystem methods + if (!is_dir($custom_dir)) { + $created = $GLOBALS['wp_filesystem']->mkdir($custom_dir, 0755); // Create the directory if it doesn't exist + if (!$created) { + return new WP_Error('directory_creation_failed', 'Unable to create the directory.'); + } + } + + // Fetch license data for each selected ID + foreach ($license_ids as $license_id) { + $data = $wpdb->get_row($wpdb->prepare( + "SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE id = %d", + $license_id + ), ARRAY_A); + + if ($data) { + $license_key = $data['license_key']; + + // Prepare file name as "license_key.csv" + $file_name = sanitize_file_name($license_key) . '.csv'; + $file_path = $custom_dir . '/' . $file_name; + + // Open file handle using WP_Filesystem methods + $file_handle = $GLOBALS['wp_filesystem']->open($file_path, 'w'); + + if (!$file_handle) { + return new WP_Error('file_creation_failed', 'Unable to open the file for writing.'); + } + + // Write CSV headers and license data to the file + fputcsv($file_handle, array_keys($data)); + fputcsv($file_handle, $data); + + // Close the file handle + $GLOBALS['wp_filesystem']->close($file_handle); + + // Store the file URL for download + $file_urls[] = $upload_dir['baseurl'] . '/' . $custom_dir_hash . '/' . $file_name; + } + } + + // Return the array of file URLs + return $file_urls; } - // Return the array of file URLs - return $file_urls; -} /* @@ -365,7 +378,7 @@ public static function export_license_data($license_ids) $success_msg = '

    '; $success_msg .= 'The selected entry was deleted successfully!'; $success_msg .= '

    '; - echo $success_msg; + echo esc_html($success_msg); } function block_license_key($key_row_id) @@ -374,7 +387,7 @@ public static function export_license_data($license_ids) $success_msg = '

    '; $success_msg .= 'The selected entry was blocked successfully!'; $success_msg .= '

    '; - echo $success_msg; + echo esc_html($success_msg); } private function sort_data($a, $b) @@ -382,26 +395,34 @@ public static function export_license_data($license_ids) // Set defaults $orderby = 'id'; $order = 'desc'; - // If orderby is set, use this as the sort column + + // Sanitize and unslash input for 'orderby' and 'order' if (!empty($_GET['orderby'])) { - $orderby = $_GET['orderby']; + $orderby = wp_unslash($_GET['orderby']); // wp_unslash before sanitization + $orderby = sanitize_key($orderby); // sanitize for key-based data } - // If order is set use this as the order + if (!empty($_GET['order'])) { - $order = $_GET['order']; + $order = wp_unslash($_GET['order']); // wp_unslash before sanitization + $order = in_array(strtolower($order), ['asc', 'desc']) ? strtolower($order) : 'desc'; // Ensure 'asc' or 'desc' only } - if ($orderby == 'id'){ - if ($a[$orderby]==$b[$orderby]){ - $result = 0; - }else{ - $result = ($a[$orderby]<$b[$orderby])?-1:1; - } - }else{ - $result = strcmp($a[$orderby], $b[$orderby]); + + // Sorting logic + if ($orderby == 'id') { + if ($a[$orderby] == $b[$orderby]) { + $result = 0; + } else { + $result = ($a[$orderby] < $b[$orderby]) ? -1 : 1; + } + } else { + $result = strcmp($a[$orderby], $b[$orderby]); } + + // Return based on the order (asc or desc) if ($order === 'asc') { return $result; } + return -$result; } @@ -416,26 +437,51 @@ public static function export_license_data($license_ids) if (empty($per_page) || $per_page < 1) { $per_page = $screen->get_option('per_page', 'default'); } - $columns = $this->get_columns(); - // $hidden = array(); - $hidden = get_hidden_columns( $screen ); - $sortable = $this->get_sortable_columns(); + + $columns = $this->get_columns(); + $hidden = get_hidden_columns($screen); + $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); + $this->process_bulk_action(); - $license_table = SLM_TBL_LICENSE_KEYS; - $search = (isset($_REQUEST['s'])) ? $_REQUEST['s'] : false; - $search_term = trim(strip_tags($search)); - $do_search = $wpdb->prepare("SELECT * FROM " . $license_table . " WHERE `license_key` LIKE '%%%s%%' OR `email` LIKE '%%%s%%' OR `lic_status` LIKE '%%%s%%' OR `first_name` LIKE '%%%s%%' OR `last_name` LIKE '%%%s%%'", $search_term, $search_term, $search_term, $search_term, $search_term); + + // Ensure the license table constant is used safely + $license_table = esc_sql(SLM_TBL_LICENSE_KEYS); // Sanitize the table name + + // Search handling with esc_like for wildcard search + $search = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : ''; // Use wp_unslash to handle slashes + $search_term = wp_strip_all_tags($search); // Using wp_strip_all_tags instead of strip_tags + $search_term_esc = addcslashes($search_term, '_%'); // Escapes underscore and percent characters + + // Prepared query with placeholders and escaped search term + $do_search = $wpdb->prepare( + "SELECT * FROM $license_table + WHERE license_key LIKE %s OR email LIKE %s OR lic_status LIKE %s OR first_name LIKE %s OR last_name LIKE %s", + '%' . $search_term_esc . '%', // Apply wildcard to the escaped search term + '%' . $search_term_esc . '%', + '%' . $search_term_esc . '%', + '%' . $search_term_esc . '%', + '%' . $search_term_esc . '%' + ); + + // Execute the query and get the results $data = $wpdb->get_results($do_search, ARRAY_A); + + // Sort data usort($data, array(&$this, 'sort_data')); - $current_page = $this->get_pagenum(); - $total_items = count($data); - $data = array_slice($data, (($current_page - 1) * $per_page), $per_page); - $this->items = $data; + + // Pagination + $current_page = $this->get_pagenum(); + $total_items = count($data); + $data = array_slice($data, (($current_page - 1) * $per_page), $per_page); + + $this->items = $data; + + // Set pagination arguments $this->set_pagination_args(array( - 'total_items' => $total_items, //WE have to calculate the total number of items - 'per_page' => $per_page, //WE have to determine how many items to show on a page - 'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages + 'total_items' => $total_items, + 'per_page' => $per_page, + 'total_pages' => ceil($total_items / $per_page) )); } } @@ -463,21 +509,22 @@ class SLM_Plugin public function slm_add_admin_menu() { $icon_svg = SLM_ASSETS_URL . 'images/slm_logo_small.svg'; - add_menu_page(__( 'SLM Plus', 'slmplus'), __( 'SLM Plus', 'slmplus'), SLM_MANAGEMENT_PERMISSION, SLM_MAIN_MENU_SLUG, "slm_manage_licenses_menu", $icon_svg); - $hook = add_submenu_page(SLM_MAIN_MENU_SLUG, __('Manage Licenses', 'slmplus'), __('Manage Licenses', 'slmplus'), SLM_MANAGEMENT_PERMISSION, SLM_MAIN_MENU_SLUG, "slm_manage_licenses_menu"); - add_submenu_page(SLM_MAIN_MENU_SLUG, __( 'Create license', 'slmplus'), __( 'Create license', 'slmplus') , SLM_MANAGEMENT_PERMISSION, 'slm_manage_license', "slm_add_licenses_menu"); - add_submenu_page(SLM_MAIN_MENU_SLUG, __( 'Subscribers', 'slmplus'), __( 'Subscribers', 'slmplus'), SLM_MANAGEMENT_PERMISSION, 'slm_subscribers', "slm_subscribers_menu"); - add_submenu_page(SLM_MAIN_MENU_SLUG, __( 'Tools', 'slmplus'), __( 'Tools', 'slmplus'), SLM_MANAGEMENT_PERMISSION, 'slm_admin_tools', "slm_admin_tools_menu"); - add_submenu_page(SLM_MAIN_MENU_SLUG, __( 'Settings', 'slmplus'), __( 'Settings', 'slmplus'), SLM_MANAGEMENT_PERMISSION, 'slm_settings', "slm_settings_menu"); - add_submenu_page(SLM_MAIN_MENU_SLUG, __( 'Help', 'slmplus'), __( 'Help', 'slmplus'), SLM_MANAGEMENT_PERMISSION, 'slm_help', "slm_integration_help_menu"); - add_submenu_page(SLM_MAIN_MENU_SLUG, __( 'About', 'slmplus'),__( 'About', 'slmplus'), SLM_MANAGEMENT_PERMISSION, 'slm_about', "slm_about_menu"); + add_menu_page(__('SLM Plus', 'slm-plus'), __('SLM Plus', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, SLM_MAIN_MENU_SLUG, "slm_manage_licenses_menu", $icon_svg); + $hook = add_submenu_page(SLM_MAIN_MENU_SLUG, __('Manage Licenses', 'slm-plus'), __('Manage Licenses', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, SLM_MAIN_MENU_SLUG, "slm_manage_licenses_menu"); + add_submenu_page(SLM_MAIN_MENU_SLUG, __('Create license', 'slm-plus'), __('Create license', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, 'slm_manage_license', "slm_add_licenses_menu"); + add_submenu_page(SLM_MAIN_MENU_SLUG, __('Subscribers', 'slm-plus'), __('Subscribers', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, 'slm_subscribers', "slm_subscribers_menu"); + add_submenu_page(SLM_MAIN_MENU_SLUG, __('Tools', 'slm-plus'), __('Tools', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, 'slm_admin_tools', "slm_admin_tools_menu"); + add_submenu_page(SLM_MAIN_MENU_SLUG, __('Settings', 'slm-plus'), __('Settings', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, 'slm_settings', "slm_settings_menu"); + add_submenu_page(SLM_MAIN_MENU_SLUG, __('Help', 'slm-plus'), __('Help', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, 'slm_help', "slm_integration_help_menu"); + add_submenu_page(SLM_MAIN_MENU_SLUG, __('About', 'slm-plus'), __('About', 'slm-plus'), SLM_MANAGEMENT_PERMISSION, 'slm_about', "slm_about_menu"); add_action("load-" . $hook, [$this, 'screen_option']); } /** * Screen options */ - public function screen_option(){ + public function screen_option() + { $option = 'per_page'; $args = [ 'label' => 'Pagination', diff --git a/admin/slm-manage-licenses.php b/admin/slm-manage-licenses.php index ea87b78..83b8a6e 100755 --- a/admin/slm-manage-licenses.php +++ b/admin/slm-manage-licenses.php @@ -12,7 +12,7 @@ function get_user_info() if (!current_user_can('manage_licenses')) { $response = array( 'success' => false, - 'message' => _e('You do not have permission to manage this license.', 'slmplus'), + 'message' => esc_html__('You do not have permission to manage this license.', 'slm-plus'), ); echo json_encode($response); die(); @@ -33,9 +33,9 @@ function slm_manage_licenses_menu()
    -

    +


    - +
    @@ -56,10 +56,10 @@ function slm_manage_licenses_menu()
    - + prepare_items(); - $license_list->search_box(__('Search'), 'search-box-id'); + $license_list->search_box(__('Search', 'slm-plus'), 'search-box-id'); $license_list->views(); $license_list->display(); ?> @@ -73,4 +73,4 @@ function slm_manage_licenses_menu()
    '', //Render a checkbox - 'id' => __('ID', 'slmplus'), - 'first_name' => __('First Name', 'slmplus'), - 'last_name' => __('Last Name', 'slmplus'), - 'email' => __('Email Address', 'slmplus') + 'id' => __('ID', 'slm-plus'), + 'first_name' => __('First Name', 'slm-plus'), + 'last_name' => __('Last Name', 'slm-plus'), + 'email' => __('Email Address', 'slm-plus') ); return $columns; } @@ -116,14 +116,14 @@ class Subscribers_List_Table extends WP_List_Table if (!empty($_GET['order'])) { $order = $_GET['order']; } - if ($orderby == 'id'){ - if ($a[$orderby]==$b[$orderby]){ - $result = 0; - }else{ - $result = ($a[$orderby]<$b[$orderby])?-1:1; - } - }else{ - $result = strcmp($a[$orderby], $b[$orderby]); + if ($orderby == 'id') { + if ($a[$orderby] == $b[$orderby]) { + $result = 0; + } else { + $result = ($a[$orderby] < $b[$orderby]) ? -1 : 1; + } + } else { + $result = strcmp($a[$orderby], $b[$orderby]); } if ($order === 'asc') { return $result; @@ -133,11 +133,10 @@ class Subscribers_List_Table extends WP_List_Table function prepare_items() { - - $per_page = 24; - $columns = $this->get_columns(); - $hidden = array(); - $sortable = $this->get_sortable_columns(); + $per_page = 24; + $columns = $this->get_columns(); + $hidden = array(); + $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); $this->process_bulk_action(); @@ -145,24 +144,41 @@ class Subscribers_List_Table extends WP_List_Table global $wpdb; $license_table = SLM_TBL_LICENSE_KEYS; - $search = (isset($_REQUEST['s'])) ? $_REQUEST['s'] : false; - $search_term = trim(strip_tags($search)); + // Sanitize the search term and strip all tags + $search = isset($_REQUEST['s']) ? sanitize_text_field(wp_unslash($_REQUEST['s'])) : false; + $search_term = trim(wp_strip_all_tags($search)); // Using wp_strip_all_tags for better sanitization - $do_search = $wpdb->prepare("SELECT * FROM " . $license_table . " WHERE `email` LIKE '%%%s%%' OR `first_name` LIKE '%%%s%%' OR `last_name` LIKE '%%%s%%' GROUP BY email", $search_term, $search_term, $search_term); + // Escape the search term for SQL and add wildcards manually + $escaped_search_term = '%' . $wpdb->esc_like($search_term) . '%'; // esc_like handles escaping the term + // Prepare the query with placeholders to prevent SQL injection + $do_search = $wpdb->prepare( + "SELECT * FROM {$license_table} + WHERE `email` LIKE %s + OR `first_name` LIKE %s + OR `last_name` LIKE %s + GROUP BY `email`", + $escaped_search_term, // Use the escaped search term with wildcards + $escaped_search_term, + $escaped_search_term + ); + + // Execute the query safely $data = $wpdb->get_results($do_search, ARRAY_A); usort($data, array(&$this, 'sort_data')); - $current_page = $this->get_pagenum(); - $total_items = count($data); - $data = array_slice($data, (($current_page - 1) * $per_page), $per_page); - $this->items = $data; + // Pagination logic + $current_page = $this->get_pagenum(); + $total_items = count($data); + $data = array_slice($data, (($current_page - 1) * $per_page), $per_page); + $this->items = $data; + // Set pagination arguments $this->set_pagination_args(array( - 'total_items' => $total_items, //WE have to calculate the total number of items - 'per_page' => $per_page, //WE have to determine how many items to show on a page - 'total_pages' => ceil($total_items / $per_page) //WE have to calculate the total number of pages + 'total_items' => $total_items, + 'per_page' => $per_page, + 'total_pages' => ceil($total_items / $per_page) )); } } @@ -170,12 +186,13 @@ class Subscribers_List_Table extends WP_List_Table function slm_subscribers_menu() { $subscribers_list = new Subscribers_List_Table(); - if (isset($_REQUEST['slm_subscriber_edit']) && $_REQUEST['slm_subscriber_edit'] == 'true') : ?> + $slm_subscriber_edit = isset($_REQUEST['slm_subscriber_edit']) ? sanitize_text_field($_REQUEST['slm_subscriber_edit']) : ''; + if ($slm_subscriber_edit === 'true') : ?>
    -

    +


    - +
    @@ -184,12 +201,11 @@ function slm_subscribers_menu()
    - - - + + + - @@ -203,7 +219,7 @@ function slm_subscribers_menu()
    -

    +



    @@ -211,10 +227,10 @@ function slm_subscribers_menu()
    - + prepare_items(); - $subscribers_list->search_box(__('Search', 'slmplus'), 'search-box-id'); + $subscribers_list->search_box(__('Search', 'slm-plus'), 'search-box-id'); $subscribers_list->views(); $subscribers_list->display(); ?> diff --git a/i18n/languages/slm-plus.pot b/i18n/languages/slm-plus.pot new file mode 100644 index 0000000..b64f95a --- /dev/null +++ b/i18n/languages/slm-plus.pot @@ -0,0 +1,1553 @@ +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: SLM Plus\n" +"POT-Creation-Date: 2024-11-12 15:24-0500\n" +"PO-Revision-Date: 2024-11-12 15:00-0500\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"X-Generator: Poedit 3.5\n" +"X-Poedit-Basepath: ../..\n" +"X-Poedit-Flags-xgettext: --add-comments=translators:\n" +"X-Poedit-WPHeader: slm-plus.php\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" +"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" +"_nx_noop:3c,1,2;__ngettext_noop:1,2\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPathExcluded-0: *.min.js\n" + +#: admin/includes/cronjobs/slm-tasks.php:9 +msgid "Every 24 Hours" +msgstr "" + +#: admin/includes/cronjobs/slm-tasks.php:89 +#: admin/includes/cronjobs/slm-tasks.php:90 +#: admin/includes/cronjobs/slm-tasks.php:124 +msgid "Run License Check" +msgstr "" + +#: admin/includes/cronjobs/slm-tasks.php:113 +msgid "License check completed. The following licenses have expired:" +msgstr "" + +#: admin/includes/cronjobs/slm-tasks.php:115 +msgid "License check completed. No expired licenses found." +msgstr "" + +#: admin/includes/cronjobs/slm-tasks.php:121 +msgid "Run License Check Manually" +msgstr "" + +#: admin/includes/cronjobs/slm-tasks.php:129 +msgid "Expired Licenses:" +msgstr "" + +#: admin/includes/partials/stats.php:8 +msgid "Total licenses" +msgstr "" + +#: admin/includes/partials/stats.php:18 +msgid "Licenses this week" +msgstr "" + +#: admin/includes/partials/stats.php:28 +msgid "Licenses this month" +msgstr "" + +#: admin/includes/partials/stats.php:38 admin/slm-dashboard-widgets.php:88 +msgid "Active licenses" +msgstr "" + +#: admin/includes/partials/stats.php:48 admin/slm-dashboard-widgets.php:95 +msgid "Pending licenses" +msgstr "" + +#: admin/includes/partials/stats.php:58 admin/slm-dashboard-widgets.php:102 +msgid "Blocked licenses" +msgstr "" + +#: admin/includes/partials/stats.php:68 +msgid "Logs saved" +msgstr "" + +#: admin/includes/partials/stats.php:78 +msgid "Reminders sent" +msgstr "" + +#: admin/includes/partials/stats.php:88 admin/slm-dashboard-widgets.php:109 +msgid "Expired licenses" +msgstr "" + +#: admin/includes/partials/stats.php:98 +msgid "Licenses about to expire" +msgstr "" + +#: admin/includes/wpestores/slm-wpestores.php:73 +msgid "Item Name: " +msgstr "" + +#: admin/includes/wpestores/slm-wpestores.php:73 +msgid "License Key: " +msgstr "" + +#: admin/slm-about-menu.php:16 +msgid "SLM - About" +msgstr "" + +#: admin/slm-about-menu.php:23 +msgid "Credits and Authors" +msgstr "" + +#: admin/slm-about-menu.php:25 +msgid "" +"SLM is a comprehensive software license management solution for your web " +"applications, supporting WordPress plugins, themes, applications, and " +"WooCommerce." +msgstr "" + +#: admin/slm-about-menu.php:29 +msgid "Information" +msgstr "" + +#: admin/slm-about-menu.php:30 +msgid "Details" +msgstr "" + +#: admin/slm-about-menu.php:35 +msgid "Authors" +msgstr "" + +#: admin/slm-about-menu.php:40 +msgid "and" +msgstr "" + +#: admin/slm-about-menu.php:47 +msgid "Help and Support" +msgstr "" + +#: admin/slm-about-menu.php:50 +msgid "Submit a request" +msgstr "" + +#: admin/slm-about-menu.php:55 +msgid "API Demos" +msgstr "" + +#: admin/slm-about-menu.php:58 +msgid "Postman Demos" +msgstr "" + +#: admin/slm-add-licenses.php:31 +msgid "Security check failed" +msgstr "" + +#: admin/slm-add-licenses.php:65 +msgid "Required fields are missing." +msgstr "" + +#: admin/slm-add-licenses.php:70 +msgid "License updated successfully." +msgstr "" + +#: admin/slm-add-licenses.php:73 +msgid "License created successfully." +msgstr "" + +#: admin/slm-add-licenses.php:74 woocommerce/includes/slm-meta-boxes.php:386 +msgid "View License" +msgstr "" + +#: admin/slm-add-licenses.php:127 +msgid "SLM Plus - License Management" +msgstr "" + +#: admin/slm-add-licenses.php:133 admin/slm-add-licenses.php:476 +msgid "License Information" +msgstr "" + +#: admin/slm-add-licenses.php:137 +#: woocommerce/includes/wc_licenses_class.php:285 +msgid "Activations" +msgstr "" + +#: admin/slm-add-licenses.php:142 +msgid "Activity" +msgstr "" + +#: admin/slm-add-licenses.php:163 +msgid "Activity Log" +msgstr "" + +#: admin/slm-add-licenses.php:167 admin/slm-add-licenses.php:267 +#: admin/slm-list-licenses-class.php:84 admin/slm-subscribers.php:85 +#: admin/slm-subscribers.php:187 includes/slm-utility.php:894 +#: woocommerce/includes/wc_licenses_class.php:293 +msgid "ID" +msgstr "" + +#: admin/slm-add-licenses.php:168 admin/slm-add-licenses.php:271 +#: woocommerce/includes/wc_licenses_class.php:115 +#: woocommerce/includes/wc_licenses_class.php:293 +msgid "Action" +msgstr "" + +#: admin/slm-add-licenses.php:169 +msgid "Time" +msgstr "" + +#: admin/slm-add-licenses.php:170 +msgid "Source" +msgstr "" + +#: admin/slm-add-licenses.php:189 +msgid "No activity log found for this license." +msgstr "" + +#: admin/slm-add-licenses.php:258 +msgid "Activation" +msgstr "" + +#: admin/slm-add-licenses.php:260 +msgid "Domains Left" +msgstr "" + +#: admin/slm-add-licenses.php:261 +msgid "Devices Left" +msgstr "" + +#: admin/slm-add-licenses.php:268 admin/slm-add-licenses.php:482 +#: woocommerce/includes/purchase.php:679 woocommerce/includes/purchase.php:756 +#: woocommerce/includes/wc_licenses_class.php:113 +#: woocommerce/includes/wc_licenses_class.php:199 +msgid "License Key" +msgstr "" + +#: admin/slm-add-licenses.php:269 woocommerce/includes/purchase.php:680 +#: woocommerce/includes/wc_licenses_class.php:293 +msgid "Type" +msgstr "" + +#: admin/slm-add-licenses.php:270 +#: woocommerce/includes/wc_licenses_class.php:293 +msgid "Origin" +msgstr "" + +#: admin/slm-add-licenses.php:283 +msgid "Domain" +msgstr "" + +#: admin/slm-add-licenses.php:287 admin/slm-add-licenses.php:309 +msgid "Remove" +msgstr "" + +#: admin/slm-add-licenses.php:303 +msgid "Device" +msgstr "" + +#: admin/slm-add-licenses.php:317 +msgid "No activations found" +msgstr "" + +#: admin/slm-add-licenses.php:378 +msgid "Nonce verification failed." +msgstr "" + +#: admin/slm-add-licenses.php:389 +msgid "Invalid activation data." +msgstr "" + +#: admin/slm-add-licenses.php:405 +msgid "Invalid activation type." +msgstr "" + +#: admin/slm-add-licenses.php:414 +msgid "The license key has been deactivated for this domain." +msgstr "" + +#: admin/slm-add-licenses.php:420 +msgid "Error deleting activation." +msgstr "" + +#: admin/slm-add-licenses.php:437 +msgid "Subscriber Information" +msgstr "" + +#: admin/slm-add-licenses.php:442 admin/slm-subscribers.php:86 +msgid "First Name" +msgstr "" + +#: admin/slm-add-licenses.php:449 admin/slm-subscribers.php:87 +msgid "Last Name" +msgstr "" + +#: admin/slm-add-licenses.php:456 admin/slm-list-licenses-class.php:89 +msgid "Email" +msgstr "" + +#: admin/slm-add-licenses.php:463 +#: woocommerce/includes/wc_licenses_class.php:211 +msgid "Company Name" +msgstr "" + +#: admin/slm-add-licenses.php:491 +#: woocommerce/includes/wc_licenses_class.php:209 +msgid "Max Allowed Domains" +msgstr "" + +#: admin/slm-add-licenses.php:495 +#: woocommerce/includes/wc_licenses_class.php:210 +msgid "Max Allowed Devices" +msgstr "" + +#: admin/slm-add-licenses.php:499 +msgid "License Status" +msgstr "" + +#: admin/slm-add-licenses.php:517 +#: woocommerce/includes/wc_licenses_class.php:203 +msgid "Date Created" +msgstr "" + +#: admin/slm-add-licenses.php:519 admin/slm-add-licenses.php:574 +#: admin/slm-add-licenses.php:585 admin/slm-add-licenses.php:646 +#, php-format +msgid "Display Format: %s (input: YYYY-MM-DD)" +msgstr "" + +#: admin/slm-add-licenses.php:523 woocommerce/includes/slm-meta-boxes.php:184 +#: woocommerce/includes/wc_licenses_class.php:201 +msgid "License Type" +msgstr "" + +#: admin/slm-add-licenses.php:526 admin/slm-admin-functions.php:123 +#: woocommerce/includes/slm-meta-boxes.php:189 +#: woocommerce/includes/slm-meta-boxes.php:391 +msgid "Subscription" +msgstr "" + +#: admin/slm-add-licenses.php:527 admin/slm-admin-functions.php:124 +#: woocommerce/includes/slm-meta-boxes.php:190 +#: woocommerce/includes/slm-meta-boxes.php:392 +msgid "Lifetime" +msgstr "" + +#: admin/slm-add-licenses.php:532 +msgid "Expiration Date" +msgstr "" + +#: admin/slm-add-licenses.php:534 +#, php-format +msgid "" +"Selecting a future date will automatically adjust the renewal term." +"
    Choose this date to set when the license should renew or expire. " +"
    Format: %s (input: YYYY-MM-DD)." +msgstr "" + +#: admin/slm-add-licenses.php:538 +msgid "Renewal" +msgstr "" + +#: admin/slm-add-licenses.php:542 admin/slm-lic-settings.php:167 +msgid "Billing Length" +msgstr "" + +#: admin/slm-add-licenses.php:545 +msgid "" +"Sets how often the license renews. E.g., a length of 2 with a term of years " +"means the license renews every 2 years." +msgstr "" + +#: admin/slm-add-licenses.php:550 admin/slm-lic-settings.php:173 +#: woocommerce/includes/slm-meta-boxes.php:207 +msgid "Expiration Term" +msgstr "" + +#: admin/slm-add-licenses.php:552 admin/slm-lic-settings.php:176 +#: woocommerce/includes/slm-meta-boxes.php:211 +msgid "Day(s)" +msgstr "" + +#: admin/slm-add-licenses.php:553 admin/slm-lic-settings.php:177 +#: woocommerce/includes/slm-meta-boxes.php:212 +msgid "Month(s)" +msgstr "" + +#: admin/slm-add-licenses.php:554 admin/slm-lic-settings.php:178 +#: woocommerce/includes/slm-meta-boxes.php:213 +msgid "Year(s)" +msgstr "" + +#: admin/slm-add-licenses.php:557 +msgid "Choose the renewal period: days, months, or years." +msgstr "" + +#: admin/slm-add-licenses.php:564 +msgid "Subscriber ID" +msgstr "" + +#: admin/slm-add-licenses.php:568 +#: woocommerce/includes/wc_licenses_class.php:205 +msgid "Date Renewed" +msgstr "" + +#: admin/slm-add-licenses.php:579 +#: woocommerce/includes/wc_licenses_class.php:204 +msgid "Date Activated" +msgstr "" + +#: admin/slm-add-licenses.php:593 +msgid "Transaction Information" +msgstr "" + +#: admin/slm-add-licenses.php:599 woocommerce/includes/slm-meta-boxes.php:174 +msgid "Item Reference" +msgstr "" + +#: admin/slm-add-licenses.php:604 +msgid "Transaction ID" +msgstr "" + +#: admin/slm-add-licenses.php:609 +msgid "Purchase ID" +msgstr "" + +#: admin/slm-add-licenses.php:614 +#: woocommerce/includes/wc_licenses_class.php:207 +msgid "Product Reference" +msgstr "" + +#: admin/slm-add-licenses.php:622 +msgid "Other" +msgstr "" + +#: admin/slm-add-licenses.php:627 +msgid "Until" +msgstr "" + +#: admin/slm-add-licenses.php:631 admin/slm-lic-settings.php:155 +#: woocommerce/includes/slm-meta-boxes.php:224 +msgid "Current Version" +msgstr "" + +#: admin/slm-add-licenses.php:635 +msgid "Reminder Sent" +msgstr "" + +#: admin/slm-add-licenses.php:639 +msgid "Reminder Sent Date" +msgstr "" + +#: admin/slm-add-licenses.php:651 +msgid "Manual Reset Count" +msgstr "" + +#: admin/slm-add-licenses.php:659 +msgid "Update License" +msgstr "" + +#: admin/slm-add-licenses.php:661 woocommerce/includes/slm-meta-boxes.php:395 +#: woocommerce/includes/slm-meta-boxes.php:399 +msgid "Create License" +msgstr "" + +#: admin/slm-admin-functions.php:14 +msgid "SLM Plus - Tools" +msgstr "" + +#: admin/slm-admin-functions.php:30 +msgid "Success message returned from the remote host." +msgstr "" + +#: admin/slm-admin-functions.php:33 +msgid "Request sent to the specified URL!" +msgstr "" + +#: admin/slm-admin-functions.php:45 +msgid "Log was cleared successfully!" +msgstr "" + +#: admin/slm-admin-functions.php:51 +msgid "Send Deactivation Message for a License" +msgstr "" + +#: admin/slm-admin-functions.php:56 +msgid "Send Request" +msgstr "" + +#: admin/slm-admin-functions.php:63 +msgid "Clean Activity Log" +msgstr "" + +#: admin/slm-admin-functions.php:65 +msgid "This will clear/reset license keys activities" +msgstr "" + +#: admin/slm-admin-functions.php:68 +msgid "Clear Log" +msgstr "" + +#: admin/slm-admin-functions.php:75 +msgid "Backup Database" +msgstr "" + +#: admin/slm-admin-functions.php:77 +msgid "" +"This will create a backup of the database tables related to this plugin and " +"save it to the uploads directory." +msgstr "" + +#: admin/slm-admin-functions.php:80 +msgid "Create Backup" +msgstr "" + +#: admin/slm-admin-functions.php:90 +msgid "Last backup created on: " +msgstr "" + +#: admin/slm-admin-functions.php:90 +msgid "Download Backup" +msgstr "" + +#: admin/slm-admin-functions.php:97 +msgid "Generate License for WooCommerce Orders" +msgstr "" + +#: admin/slm-admin-functions.php:100 admin/slm-lic-settings.php:249 +msgid "" +"This tool generates bulk licenses for WooCommerce orders placed before the " +"plugin was activated or for orders that lack existing licenses." +msgstr "" + +#: admin/slm-admin-functions.php:101 admin/slm-lic-settings.php:250 +msgid "Warning:" +msgstr "" + +#: admin/slm-admin-functions.php:102 admin/slm-lic-settings.php:251 +msgid "" +"This action cannot be undone. Please back up your database before proceeding." +msgstr "" + +#: admin/slm-admin-functions.php:112 +msgid "Product ID" +msgstr "" + +#: admin/slm-admin-functions.php:114 +msgid "Enter Product ID" +msgstr "" + +#: admin/slm-admin-functions.php:115 +msgid "Specify the default product ID for license generation." +msgstr "" + +#: admin/slm-admin-functions.php:120 +msgid "Subscription Type" +msgstr "" + +#: admin/slm-admin-functions.php:126 +msgid "Select the type of license for the order." +msgstr "" + +#: admin/slm-admin-functions.php:133 +msgid "Generate Licenses" +msgstr "" + +#: admin/slm-admin-functions.php:137 +msgid "" +"Please enable the WooCommerce License Generator option to activate the " +"Generate Licenses tool." +msgstr "" + +#: admin/slm-admin-functions.php:147 +msgid "License Generation Results:" +msgstr "" + +#: admin/slm-admin-functions.php:165 +msgid "Product ID cannot be empty." +msgstr "" + +#: admin/slm-admin-functions.php:166 +msgid "Product ID is required." +msgstr "" + +#: admin/slm-admin-functions.php:170 +msgid "Subscription Type cannot be empty." +msgstr "" + +#: admin/slm-admin-functions.php:171 +msgid "Subscription Type is required." +msgstr "" + +#: admin/slm-admin-functions.php:193 +msgid "Licenses generated successfully!" +msgstr "" + +#: admin/slm-admin-functions.php:196 +msgid "Some licenses failed to generate. Check the response for details." +msgstr "" + +#: admin/slm-admin-functions.php:200 +msgid "There was an error processing the request. Please try again." +msgstr "" + +#: admin/slm-admin-functions.php:201 +msgid "There was an error processing the request." +msgstr "" + +#: admin/slm-admin-functions.php:283 +msgid "Backup created successfully! Download from: " +msgstr "" + +#: admin/slm-admin-functions.php:285 +msgid "Error: Failed to create the backup file." +msgstr "" + +#. Plugin Name of the plugin/theme +#: admin/slm-dashboard-widgets.php:30 admin/slm-list-licenses-class.php:466 +msgid "SLM Plus" +msgstr "" + +#: admin/slm-dashboard-widgets.php:33 +msgid "slm-plus" +msgstr "" + +#: admin/slm-dashboard-widgets.php:42 +msgid "Overview" +msgstr "" + +#: admin/slm-dashboard-widgets.php:52 +msgid "Add new license" +msgstr "" + +#: admin/slm-dashboard-widgets.php:62 admin/slm-list-licenses-class.php:471 +#: slm-plus.php:69 +msgid "Settings" +msgstr "" + +#: admin/slm-dashboard-widgets.php:79 +msgid "Manage licenses" +msgstr "" + +#: admin/slm-dashboard-widgets.php:80 +msgid "Total active licenses" +msgstr "" + +#: admin/slm-dashboard-widgets.php:120 +msgid "Recent Licenses" +msgstr "" + +#: admin/slm-dashboard-widgets.php:121 +msgid "View All" +msgstr "" + +#: admin/slm-integration-help-page.php:14 +msgid "SLM Plus - Integration Help" +msgstr "" + +#: admin/slm-integration-help-page.php:15 +msgid "Version:" +msgstr "" + +#: admin/slm-integration-help-page.php:21 +msgid "API Settings" +msgstr "" + +#: admin/slm-integration-help-page.php:29 +msgid "License API Query POST URL for Your Installation" +msgstr "" + +#: admin/slm-integration-help-page.php:32 +msgid "License Activation/Deactivation API Secret Key" +msgstr "" + +#: admin/slm-integration-help-page.php:35 +msgid "License Creation API Secret Key" +msgstr "" + +#: admin/slm-integration-help-page.php:41 +msgid "Documentation and Guides" +msgstr "" + +#: admin/slm-integration-help-page.php:43 +msgid "Need more help? Check out the documentation:" +msgstr "" + +#: admin/slm-integration-help-page.php:45 +msgid "Postman API Demos" +msgstr "" + +#: admin/slm-integration-help-page.php:52 +msgid "Error Codes and Descriptions" +msgstr "" + +#: admin/slm-integration-help-page.php:57 +msgid "Constant" +msgstr "" + +#: admin/slm-integration-help-page.php:58 +msgid "Error Code" +msgstr "" + +#: admin/slm-integration-help-page.php:59 +msgid "Description" +msgstr "" + +#: admin/slm-integration-help-page.php:65 +msgid "The license creation failed due to an unknown error." +msgstr "" + +#: admin/slm-integration-help-page.php:66 +msgid "The license key provided during creation is invalid." +msgstr "" + +#: admin/slm-integration-help-page.php:67 +msgid "The domain associated with this license is already inactive." +msgstr "" + +#: admin/slm-integration-help-page.php:68 +msgid "The domain information is missing in the request." +msgstr "" + +#: admin/slm-integration-help-page.php:69 +msgid "The license key has been canceled." +msgstr "" + +#: admin/slm-integration-help-page.php:70 +msgid "Failed to cancel the license key." +msgstr "" + +#: admin/slm-integration-help-page.php:71 +msgid "Successfully deactivated the license key for the specified domain." +msgstr "" + +#: admin/slm-integration-help-page.php:72 +msgid "The license key was successfully deactivated." +msgstr "" + +#: admin/slm-integration-help-page.php:73 +msgid "Failed to delete the license key." +msgstr "" + +#: admin/slm-integration-help-page.php:74 +msgid "The license key was successfully deleted." +msgstr "" + +#: admin/slm-integration-help-page.php:75 +msgid "The license key has been deleted." +msgstr "" + +#: admin/slm-integration-help-page.php:76 +msgid "Failed to update the license key details." +msgstr "" + +#: admin/slm-integration-help-page.php:77 +msgid "The license key was successfully updated." +msgstr "" + +#: admin/slm-integration-help-page.php:78 +msgid "The license key was successfully activated." +msgstr "" + +#: admin/slm-integration-help-page.php:79 +msgid "The license key has been blocked from further use." +msgstr "" + +#: admin/slm-integration-help-page.php:80 +msgid "The license key was successfully created." +msgstr "" + +#: admin/slm-integration-help-page.php:81 +msgid "The license key already exists in the system." +msgstr "" + +#: admin/slm-integration-help-page.php:82 +msgid "The license key has expired." +msgstr "" + +#: admin/slm-integration-help-page.php:83 +msgid "The license key is already in use on another domain or device." +msgstr "" + +#: admin/slm-integration-help-page.php:84 +msgid "The license key is invalid." +msgstr "" + +#: admin/slm-integration-help-page.php:85 +msgid "Failed to delete the license key because it was not found." +msgstr "" + +#: admin/slm-integration-help-page.php:86 +msgid "Failed to update the license key because it was not found." +msgstr "" + +#: admin/slm-integration-help-page.php:87 +msgid "The license key has reached its maximum allowable devices." +msgstr "" + +#: admin/slm-integration-help-page.php:88 +msgid "The license key has reached its maximum allowable domains." +msgstr "" + +#: admin/slm-integration-help-page.php:89 +msgid "The key verification failed due to an invalid key." +msgstr "" + +#: admin/slm-lic-settings.php:72 +msgid "Options updated!" +msgstr "" + +#: admin/slm-lic-settings.php:85 +msgid "SLM Plus - Settings" +msgstr "" + +#: admin/slm-lic-settings.php:91 +msgid "General" +msgstr "" + +#: admin/slm-lic-settings.php:95 +msgid "Integrations" +msgstr "" + +#: admin/slm-lic-settings.php:99 +msgid "Debugging" +msgstr "" + +#: admin/slm-lic-settings.php:103 +msgid "Emails" +msgstr "" + +#: admin/slm-lic-settings.php:115 +msgid "Secret Key for License Creation" +msgstr "" + +#: admin/slm-lic-settings.php:118 +msgid "" +"This secret key will be used to authenticate any license creation request. " +"You can change it with something random." +msgstr "" + +#: admin/slm-lic-settings.php:122 +msgid "Secret Key for License Verification Requests" +msgstr "" + +#: admin/slm-lic-settings.php:124 +msgid "" +"This secret key will be used to authenticate any license verification " +"request from customer's site. Important! Do not change this value once your " +"customers start to use your product(s)!" +msgstr "" + +#: admin/slm-lic-settings.php:128 +msgid "License Key Prefix" +msgstr "" + +#: admin/slm-lic-settings.php:130 +msgid "" +"You can optionaly specify a prefix for the license keys. This prefix will be " +"added to the uniquely generated license keys." +msgstr "" + +#: admin/slm-lic-settings.php:134 +msgid "Maximum Allowed Devices" +msgstr "" + +#: admin/slm-lic-settings.php:136 +msgid "" +"Maximum number of devices which each license is valid for (default value)." +msgstr "" + +#: admin/slm-lic-settings.php:141 +msgid "Maximum Allowed Domains" +msgstr "" + +#: admin/slm-lic-settings.php:143 +msgid "" +"Maximum number of domains which each license is valid for (default value)." +msgstr "" + +#: admin/slm-lic-settings.php:148 +msgid "Support Until Ver." +msgstr "" + +#: admin/slm-lic-settings.php:150 +msgid "" +"This is used to enable bulk license generation for WooCommerce orders placed " +"before the plugin was active or for orders that do not already contain " +"licenses (default setting)." +msgstr "" + +#: admin/slm-lic-settings.php:157 admin/slm-lic-settings.php:169 +#: admin/slm-lic-settings.php:181 +msgid "" +"This is used to enable bulk license generation for WooCommerce orders placed " +"before the plugin was active or for orders that do not already contain " +"licenses (default setting:)." +msgstr "" + +#: admin/slm-lic-settings.php:180 +msgid "Frequency period: in days, months, or years" +msgstr "" + +#: admin/slm-lic-settings.php:187 +msgid "Auto Expire License Keys" +msgstr "" + +#: admin/slm-lic-settings.php:189 +msgid "Enable auto expiration " +msgstr "" + +#: admin/slm-lic-settings.php:190 +msgid "" +" When enabled, it will automatically set the status of a license key to " +"\"Expired\" when the expiry date value of the key is reached. It doesn't " +"remotely deactivate a key. It simply changes the status of the key in your " +"database to expired." +msgstr "" + +#: admin/slm-lic-settings.php:194 +msgid "General settings" +msgstr "" + +#: admin/slm-lic-settings.php:197 +msgid "Enable stats in licenses overview page." +msgstr "" + +#: admin/slm-lic-settings.php:205 +msgid "Enable admin bar shortcut link" +msgstr "" + +#: admin/slm-lic-settings.php:210 +msgid "Multiple items validation" +msgstr "" + +#: admin/slm-lic-settings.php:213 +msgid "Enable verification of Item reference." +msgstr "" + +#: admin/slm-lic-settings.php:214 +msgid "" +"When enabled, there will be another field in Licenced product - Item " +"reference. This field should correspond to the API parameter item_reference " +"of your software." +msgstr "" + +#: admin/slm-lic-settings.php:219 +msgid "User permissions" +msgstr "" + +#: admin/slm-lic-settings.php:222 +msgid "Allow users to remove domains/devices in My account." +msgstr "" + +#: admin/slm-lic-settings.php:223 +msgid "" +"When enabled, users will be able to remove registered domains or devices in " +"their account." +msgstr "" + +#: admin/slm-lic-settings.php:232 +msgid "WooCommerce Settings" +msgstr "" + +#: admin/slm-lic-settings.php:236 +msgid "WooCommerce" +msgstr "" + +#: admin/slm-lic-settings.php:239 +msgid "" +"Enable WooCommerce Support (A fully customizable, open source eCommerce " +"platform built for WordPress.)" +msgstr "" + +#: admin/slm-lic-settings.php:247 +msgid "Enable WooCommerce Order License Generator" +msgstr "" + +#: admin/slm-lic-settings.php:260 +msgid "" +"Disable WooCommerce download page. Process downloads though license order " +"info page." +msgstr "" + +#: admin/slm-lic-settings.php:267 +msgid "" +"Enable WooCommerce downloads expiration. Downloads will expire together with " +"corresponding license." +msgstr "" + +#: admin/slm-lic-settings.php:272 admin/slm-lic-settings.php:275 +msgid "WP eStores" +msgstr "" + +#: admin/slm-lic-settings.php:278 +msgid "Enable WordPress eStore Plugin Support." +msgstr "" + +#: admin/slm-lic-settings.php:289 +msgid "Enable Debug Logging" +msgstr "" + +#: admin/slm-lic-settings.php:292 +msgid "If checked, debug output will be written to log files." +msgstr "" + +#: admin/slm-lic-settings.php:297 +msgid "SLM Plus Version" +msgstr "" + +#: admin/slm-lic-settings.php:304 +msgid "SLM Databse Version" +msgstr "" + +#: admin/slm-lic-settings.php:311 +msgid "SLM Rewrite Version" +msgstr "" + +#: admin/slm-lic-settings.php:326 +msgid "Expiration reminder" +msgstr "" + +#: admin/slm-lic-settings.php:336 +msgid "Update Options" +msgstr "" + +#: admin/slm-list-licenses-class.php:27 +msgid "No licenses avaliable." +msgstr "" + +#: admin/slm-list-licenses-class.php:43 +msgid "All" +msgstr "" + +#: admin/slm-list-licenses-class.php:50 +msgid "active" +msgstr "" + +#: admin/slm-list-licenses-class.php:57 +msgid "pending" +msgstr "" + +#: admin/slm-list-licenses-class.php:64 +msgid "expired" +msgstr "" + +#: admin/slm-list-licenses-class.php:71 +msgid "blocked" +msgstr "" + +#: admin/slm-list-licenses-class.php:85 admin/slm-subscribers.php:189 +#: woocommerce/includes/wc_licenses_class.php:114 +#: woocommerce/includes/wc_licenses_class.php:200 +msgid "Status" +msgstr "" + +#: admin/slm-list-licenses-class.php:86 +msgid "Key" +msgstr "" + +#: admin/slm-list-licenses-class.php:87 +msgid "Item reference" +msgstr "" + +#: admin/slm-list-licenses-class.php:88 +msgid "License type" +msgstr "" + +#: admin/slm-list-licenses-class.php:90 +msgid "Domains" +msgstr "" + +#: admin/slm-list-licenses-class.php:91 +msgid "Devices" +msgstr "" + +#: admin/slm-list-licenses-class.php:92 +msgid "Order #" +msgstr "" + +#: admin/slm-list-licenses-class.php:93 +msgid "Created on" +msgstr "" + +#: admin/slm-list-licenses-class.php:94 +msgid "Renewed on" +msgstr "" + +#: admin/slm-list-licenses-class.php:95 +msgid "Activated on" +msgstr "" + +#: admin/slm-list-licenses-class.php:96 +msgid "Expiration" +msgstr "" + +#: admin/slm-list-licenses-class.php:97 +msgid "Until Ver." +msgstr "" + +#: admin/slm-list-licenses-class.php:98 +msgid "Current Ver." +msgstr "" + +#: admin/slm-list-licenses-class.php:120 +msgid " Lifetime " +msgstr "" + +#: admin/slm-list-licenses-class.php:213 admin/slm-list-licenses-class.php:231 +#: admin/slm-list-licenses-class.php:249 admin/slm-list-licenses-class.php:267 +#: admin/slm-list-licenses-class.php:285 +msgid "Error - Please select some records using the checkboxes" +msgstr "" + +#: admin/slm-list-licenses-class.php:467 +msgid "Manage Licenses" +msgstr "" + +#: admin/slm-list-licenses-class.php:468 +msgid "Create license" +msgstr "" + +#: admin/slm-list-licenses-class.php:469 +msgid "Subscribers" +msgstr "" + +#: admin/slm-list-licenses-class.php:470 +msgid "Tools" +msgstr "" + +#: admin/slm-list-licenses-class.php:472 +msgid "Help" +msgstr "" + +#: admin/slm-list-licenses-class.php:473 +msgid "About" +msgstr "" + +#: admin/slm-manage-licenses.php:15 +msgid "You do not have permission to manage this license." +msgstr "" + +#: admin/slm-manage-licenses.php:36 +msgid "SLM Plus - Manage Licenses" +msgstr "" + +#: admin/slm-manage-licenses.php:38 +msgid "Add New" +msgstr "" + +#: admin/slm-manage-licenses.php:62 admin/slm-subscribers.php:217 +msgid "Search" +msgstr "" + +#: admin/slm-subscribers.php:88 +msgid "Email Address" +msgstr "" + +#: admin/slm-subscribers.php:176 +msgid "Overview - Manage Subscribers" +msgstr "" + +#: admin/slm-subscribers.php:178 +msgid "View all" +msgstr "" + +#: admin/slm-subscribers.php:188 +msgid "License key" +msgstr "" + +#: admin/slm-subscribers.php:206 +msgid "Overview - All Subscribers" +msgstr "" + +#: includes/class-slm-installer.php:41 +msgid "Pending" +msgstr "" + +#: includes/class-slm-installer.php:42 +msgid "Active" +msgstr "" + +#: includes/class-slm-installer.php:43 +msgid "Blocked" +msgstr "" + +#: includes/class-slm-installer.php:44 +msgid "Expired" +msgstr "" + +#: includes/slm-utility.php:421 includes/slm-utility.php:437 +msgid "0 days remaining" +msgstr "" + +#: includes/slm-utility.php:430 +#, php-format +msgid "%s days remaining until %s" +msgstr "" + +#: includes/slm-utility.php:482 +msgid "License key not found or invalid email." +msgstr "" + +#: includes/slm-utility.php:882 +msgid " view" +msgstr "" + +#: includes/slm-utility.php:894 +msgid "Request" +msgstr "" + +#: includes/slm-utility.php:902 +msgid "Source:" +msgstr "" + +#: includes/slm-utility.php:903 +msgid "Time:" +msgstr "" + +#: includes/slm-utility.php:949 +msgid "Not registered yet" +msgstr "" + +#: includes/slm-utility.php:967 includes/slm-utility.php:979 +msgid "License information" +msgstr "" + +#: includes/slm-utility.php:980 +msgid "License type: " +msgstr "" + +#: includes/slm-utility.php:981 +msgid "Domains allowed: " +msgstr "" + +#: includes/slm-utility.php:982 +msgid "Devices allowed: " +msgstr "" + +#: includes/slm-utility.php:983 +msgid "Renews every " +msgstr "" + +#: woocommerce/includes/create-license-orders.php:42 +msgid "Product ID is missing in the request." +msgstr "" + +#: woocommerce/includes/create-license-orders.php:58 +msgid "" +"The provided Product ID does not correspond to a valid WooCommerce product. " +"Please check the ID and try again." +msgstr "" + +#: woocommerce/includes/create-license-orders.php:190 +#: woocommerce/includes/create-license-orders.php:239 +#: woocommerce/includes/slm-meta-boxes.php:530 +#, php-format +msgid "License Key generated: %s" +msgstr "" + +#: woocommerce/includes/create-license-orders.php:260 +#, php-format +msgid "%d orders were skipped:" +msgstr "" + +#: woocommerce/includes/create-license-orders.php:264 +#, php-format +msgid "" +"Order ID %d was skipped due to: %s. View " +"Order" +msgstr "" + +#: woocommerce/includes/create-license-orders.php:273 +#, php-format +msgid "%d licenses generated successfully:" +msgstr "" + +#: woocommerce/includes/create-license-orders.php:276 +#, php-format +msgid "" +"License Key: %s for Order ID %d - View " +"Order" +msgstr "" + +#: woocommerce/includes/create-license-orders.php:282 +#, php-format +msgid "%d licenses failed to generate." +msgstr "" + +#: woocommerce/includes/purchase.php:90 +msgid "License no longer exists" +msgstr "" + +#: woocommerce/includes/purchase.php:95 +#: woocommerce/includes/slm-meta-boxes.php:381 +msgid "License Key:" +msgstr "" + +#: woocommerce/includes/purchase.php:193 +msgid "License could not be created: Invalid sites allowed number." +msgstr "" + +#: woocommerce/includes/purchase.php:344 +msgid "License Key(s) generated:" +msgstr "" + +#: woocommerce/includes/purchase.php:373 +msgid "License Key(s) could not be created." +msgstr "" + +#: woocommerce/includes/purchase.php:627 +#, php-format +msgid "Order confirmation email sent to: %s" +msgstr "" + +#: woocommerce/includes/purchase.php:675 +#: woocommerce/includes/wc_licenses_class.php:215 +msgid "License Details" +msgstr "" + +#: woocommerce/includes/purchase.php:690 +msgid "View My Licenses" +msgstr "" + +#: woocommerce/includes/purchase.php:748 +msgid "License Keys" +msgstr "" + +#: woocommerce/includes/purchase.php:753 +msgid "Product" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:51 +msgid "License product" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:68 +msgid "License Manager" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:70 +msgid "Enables the license creation API." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:120 +msgid "License Info" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:146 +msgid "Domain Licenses" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:152 +msgid "Enter the allowed number of domains this license can have (websites)." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:161 +msgid "Devices Licenses" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:167 +msgid "" +"Enter the allowed number of devices this license can have (computers, " +"mobile, etc)." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:175 +msgid "Software's item reference" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:177 +msgid "" +"Enter the item reference of your application, theme, or plug-in. The license " +"will be then bound to this exact software." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:186 +msgid "Type of license: subscription base or lifetime" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:188 +msgid "Select one" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:197 +msgid "Renewal Period Length" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:198 +msgid "XX Amount of days, months, or years." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:209 +msgid "Choose between days, months, or years" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:214 +msgid "One Time" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:227 +msgid "Enter the current version of your application, theme, or plug-in" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:233 +msgid "Until Version" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:236 +msgid "Enter the version until support expires." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:361 +msgid "SLM Properties" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:382 +#: woocommerce/includes/slm-meta-boxes.php:389 +msgid "License Type:" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:383 +msgid "A license key is already assigned to this order." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:398 +msgid "Order must be completed or processing to create a license." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:421 +msgid "" +"Warning: The order lacks user information like last name or email. Do you " +"still wish to create the license?" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:425 +msgid "Are you sure you want to create a license for this order?" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:435 +msgid "License creation failed. Please check the logs." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:441 +msgid "Unable to verify order details. Please try again." +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:460 +#: woocommerce/includes/slm-meta-boxes.php:545 +msgid "Invalid order ID" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:465 +msgid "Order must be completed or processing to create a license" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:518 +msgid "API request failed" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:533 +msgid "License created successfully" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:535 +msgid "License creation failed" +msgstr "" + +#: woocommerce/includes/slm-meta-boxes.php:554 +msgid "Order not found" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:59 +msgid "My Licenses" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:84 +#: woocommerce/includes/wc_licenses_class.php:188 +msgid "Invalid license or access denied." +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:112 +#: woocommerce/includes/wc_licenses_class.php:202 +msgid "Order ID" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:132 +msgid "Manual" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:140 +msgid "View" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:195 +msgid "Back to My Licenses" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:206 +msgid "Date Expiry" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:208 +msgid "Subscription ID" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:231 +msgid "No Order Information Available" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:247 +msgid "Product Not Found" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:250 +msgid "No Product Information Available" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:256 +msgid "Not activated yet" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:256 +msgid "Not renewed yet" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:289 +msgid "No activations found." +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:305 +msgid "Delete" +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:327 +msgid "Activation successfully deleted. Reload Page." +msgstr "" + +#: woocommerce/includes/wc_licenses_class.php:329 +msgid "Failed to delete activation. Please try again." +msgstr "" + +#. Plugin URI of the plugin/theme +msgid "https://github.com/michelve/software-license-manager/" +msgstr "" + +#. Description of the plugin/theme +msgid "" +"A comprehensive software license management solution for web applications " +"including WordPress plugins, themes, and PHP-based software. Seamlessly " +"integrates with WooCommerce to offer license key generation, management, and " +"validation. Ideal for developers managing software licenses across multiple " +"platforms with built-in multilingual support and performance optimization." +msgstr "" + +#. Author of the plugin/theme +msgid "Michel Velis" +msgstr "" + +#. Author URI of the plugin/theme +msgid "https://github.com/michelve/" +msgstr "" diff --git a/i18n/languages/slmplus-es_ES.mo b/i18n/languages/slmplus-es_ES.mo deleted file mode 100644 index b27d7a2d8e194676f3b76ddacb6365dc9bf620d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2756 zcmaKsU1(fI6vs!~`mwFnwtm&msamTwce~l9P;V?HO_L^=G)p&$g2i=m?{qWq?w#w* z+%&;H>8sKQ>q|ux3I(+vg5U>=R4O9);Dex`AR;Kz7ax66{GWSgvnhzfp8d_4IWyRsLH`8F{w*vfyR#tW z@d8M8pMiAlFTh*DZ@m5sxEcBtkmCFs#E(^Ayan6>()W&a(leI5vT_ zZX5n+pFR+#Y!68G`$5X{sMlve@_!VhxRlp5NPbU%wEsyze+s01PlI&MGa#M z9%}UcKMc7YLNQRgvjpo0cR=V3-w&a?p}gD;={C9-`c~+^so@C4nW#@WqWnDqq5N=2 z4e|iwF-R5CZFC=X$acuR-NB(bojW!ZIkhO+P#p8a@;Dnx5_TZb(epB9!@84+beSI( z9m$4`6i&umr|cj)-0SS1w2@JnQ#2u+P>E$D9iaT@*w{$x$ACp?mU%3e*~n6+j40L> zT{s+7#=6qoA(=`e65f=~skCj`A?3#MIW{JfjEx^;y#tt>E%qanbaXUvv9)&l1;P7zer;yDI-Wj=DnAp z7`-4P7mUZjtTYxog}ga2$s0*-D~+k(h+I@O8qlqTyk4sh1pT$3zL(eQVXZ%?4b*BC zN>We+lL)6x$T5<(b0i>`mZGyt54p6hf&RxUljD;kJ&*m>T4h+LPNvugrwF-|OKw+| z2$c@q!A+J_^?^hiv!xQx9F+Hm=w6-K@T`HB`rJq(S_1RdlS#`4F zYi%HtK@GY5uZfYRD9K|PlflkvN2S#T`@eSmAx8?^Dh={1#upbv^Ag3v99_gmt4#&< zM4CvHWkp*y)Hbp$3{P{psPQUdP2~lzNuYOFcjk=bvE+&1vXh}uh@#NMn#+`pN_|@>hcFvVTy;=RUBTBv?x@@NGwV4Pz=meq^};+tA^}Vc6g(R$?^meUp_A^o0Vy# zItpKuF8eEivZ00CI%#>kEKcz3tJ2VN9*b^SG94f6a3ZL(W->_>Hu>Yi$G@GtSd^z? zrZ_j%sYr>C6+?(Y@}gW}3^f@Sg73~CS7!B$MS+TG%PD6NB;G#`-Hoa&UI-uI`TC_< zQzt4?E|1xP+(yD6J?Syk&W#Us#5%f=CMHqL%k++EgSf_|F``HZax)%N7{xmiQE4@; iGR?+NUj(vcxT6~`Y8ozonMDHilXfmDDh0(*W7)syHicRM diff --git a/i18n/languages/slmplus-es_ES.po b/i18n/languages/slmplus-es_ES.po deleted file mode 100644 index a3758ab..0000000 --- a/i18n/languages/slmplus-es_ES.po +++ /dev/null @@ -1,1511 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: SLM Plus\n" -"POT-Creation-Date: 2024-10-28 22:01-0400\n" -"PO-Revision-Date: 2024-10-28 22:20-0400\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: es_419\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.5\n" -"X-Poedit-Basepath: ../..\n" -"X-Poedit-Flags-xgettext: --add-comments=translators:\n" -"X-Poedit-WPHeader: slm-plus.php\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;" -"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;" -"_nx_noop:3c,1,2;__ngettext_noop:1,2\n" -"X-Poedit-SearchPath-0: .\n" -"X-Poedit-SearchPathExcluded-0: *.min.js\n" -"X-Poedit-SearchPathExcluded-1: plugin-update-checker\\vendor\n" - -#: admin/includes/cronjobs/slm-tasks.php:10 -msgid "Every day" -msgstr "Todos los días" - -#: admin/includes/partials/stats.php:8 -#, fuzzy -msgid "Total licenses" -msgstr "Total de licencias" - -#: admin/includes/partials/stats.php:18 -#, fuzzy -msgid "Licenses this week" -msgstr "Licencias esta semana" - -#: admin/includes/partials/stats.php:28 -#, fuzzy -msgid "Licenses this month" -msgstr "Licencias este mes" - -#: admin/includes/partials/stats.php:38 -#, fuzzy -msgid "Active licenses" -msgstr "Licencias activas" - -#: admin/includes/partials/stats.php:48 -#, fuzzy -msgid "Pending licenses" -msgstr "Licencias pendientes" - -#: admin/includes/partials/stats.php:58 -#, fuzzy -msgid "Blocked licenses" -msgstr "Licencias bloqueadas" - -#: admin/includes/partials/stats.php:68 -#, fuzzy -msgid "Logs saved" -msgstr "Registros guardados" - -#: admin/includes/partials/stats.php:78 -#, fuzzy -msgid "Reminders sent" -msgstr "Recordatorios enviados" - -#: admin/includes/partials/stats.php:88 -#, fuzzy -msgid "Expired licenses" -msgstr "Licencias caducadas" - -#: admin/includes/partials/stats.php:98 -#, fuzzy -msgid "Licenses about to expire" -msgstr "Licencias a punto de caducar" - -#: admin/includes/wpestores/slm-wpestores.php:73 -#, fuzzy -msgid "Item Name: " -msgstr "Nombre del artículo: " - -#: admin/includes/wpestores/slm-wpestores.php:73 -#, fuzzy -msgid "License Key: " -msgstr "Clave de licencia: " - -#: admin/slm-add-licenses.php:18 -#, fuzzy -msgid "Security check failed" -msgstr "Error en la comprobación de seguridad" - -#: admin/slm-add-licenses.php:64 -#, fuzzy -msgid "Required fields are missing." -msgstr "Faltan los campos obligatorios." - -#: admin/slm-add-licenses.php:69 -#, fuzzy -msgid "License updated successfully." -msgstr "Licencia actualizada con éxito." - -#: admin/slm-add-licenses.php:72 -#, fuzzy -msgid "License created successfully." -msgstr "Licencia creada con éxito." - -#: admin/slm-add-licenses.php:127 -#, fuzzy -msgid "License Management" -msgstr "Gestión de licencias" - -#: admin/slm-add-licenses.php:138 woocommerce/includes/slm-meta-boxes.php:120 -#, fuzzy -msgid "License Info" -msgstr "Información de la licencia" - -#: admin/slm-add-licenses.php:143 woocommerce/includes/purchase.php:689 -#: woocommerce/includes/purchase.php:748 woocommerce/includes/purchase.php:825 -#: woocommerce/includes/wc_licenses_class.php:166 -msgid "License Key" -msgstr "许可 Key" - -#: admin/slm-add-licenses.php:147 -#, fuzzy -msgid "Max Allowed Domains" -msgstr "Dominio máximo permitido" - -#: admin/slm-add-licenses.php:151 -#, fuzzy -msgid "Max Allowed Devices" -msgstr "Máximo de dispositivos permitidos" - -#: admin/slm-add-licenses.php:155 woocommerce/includes/purchase.php:693 -#, fuzzy -msgid "License Status" -msgstr "Estado de la licencia" - -#: admin/slm-add-licenses.php:173 -msgid "Date Created" -msgstr "Fecha de creación" - -#: admin/slm-add-licenses.php:175 admin/slm-add-licenses.php:190 -#: admin/slm-add-licenses.php:200 admin/slm-add-licenses.php:206 -#: admin/slm-add-licenses.php:288 -#, fuzzy, php-format -msgid "Display Format: %s (input: YYYY-MM-DD)" -msgstr "Formato de visualización: %s (entrada: AAAA-MM-DD)" - -#: admin/slm-add-licenses.php:179 woocommerce/includes/purchase.php:691 -#: woocommerce/includes/slm-meta-boxes.php:184 -#, fuzzy -msgid "License Type" -msgstr "Tipo de licencia" - -#: admin/slm-add-licenses.php:182 woocommerce/includes/slm-meta-boxes.php:189 -msgid "Subscription" -msgstr "Suscripción" - -#: admin/slm-add-licenses.php:183 woocommerce/includes/slm-meta-boxes.php:190 -#: woocommerce/includes/wc_licenses_class.php:180 -#, fuzzy -msgid "Lifetime" -msgstr "Vida" - -#: admin/slm-add-licenses.php:188 -#, fuzzy -msgid "Date Expiry" -msgstr "Fecha de caducidad" - -#: admin/slm-add-licenses.php:194 -#, fuzzy -msgid "Subscription ID" -msgstr "ID de suscripción" - -#: admin/slm-add-licenses.php:198 -#, fuzzy -msgid "Date Renewed" -msgstr "Fecha de renovación" - -#: admin/slm-add-licenses.php:204 -#, fuzzy -msgid "Date Activated" -msgstr "Fecha de activación" - -#: admin/slm-add-licenses.php:212 -#, fuzzy -msgid "Subscriber Info" -msgstr "Información del suscriptor" - -#: admin/slm-add-licenses.php:217 admin/slm-subscribers.php:86 -msgid "First Name" -msgstr "Nombre" - -#: admin/slm-add-licenses.php:221 admin/slm-subscribers.php:87 -msgid "Last Name" -msgstr "Apellido" - -#: admin/slm-add-licenses.php:225 admin/slm-list-licenses-class.php:89 -msgid "Email" -msgstr "Correo electrónico" - -#: admin/slm-add-licenses.php:229 -msgid "Company Name" -msgstr "Nombre de la empresa" - -#: admin/slm-add-licenses.php:235 -#, fuzzy -msgid "Transaction" -msgstr "Transacción" - -#: admin/slm-add-licenses.php:239 woocommerce/includes/slm-meta-boxes.php:174 -#, fuzzy -msgid "Item Reference" -msgstr "Referencia del artículo" - -#: admin/slm-add-licenses.php:244 -msgid "Transaction ID" -msgstr "Id de transacción" - -#: admin/slm-add-licenses.php:249 -#, fuzzy -msgid "Purchase ID" -msgstr "ID de compra" - -#: admin/slm-add-licenses.php:254 -#, fuzzy -msgid "Product Reference" -msgstr "Referencia del producto" - -#: admin/slm-add-licenses.php:260 -msgid "Other" -msgstr "Otro" - -#: admin/slm-add-licenses.php:264 -msgid "Until" -msgstr "Hasta" - -#: admin/slm-add-licenses.php:268 woocommerce/includes/slm-meta-boxes.php:225 -#, fuzzy -msgid "Current Version" -msgstr "Versión actual" - -#: admin/slm-add-licenses.php:274 -#, fuzzy -msgid "Billing Length" -msgstr "Duración de la facturación" - -#: admin/slm-add-licenses.php:278 -#, fuzzy -msgid "Billing Interval" -msgstr "Intervalo de facturación" - -#: admin/slm-add-licenses.php:282 -#, fuzzy -msgid "Reminder Sent" -msgstr "Recordatorio enviado" - -#: admin/slm-add-licenses.php:286 -#, fuzzy -msgid "Reminder Sent Date" -msgstr "Fecha de envío del recordatorio" - -#: admin/slm-add-licenses.php:292 -#, fuzzy -msgid "Manual Reset Count" -msgstr "Recuento de restablecimiento manual" - -#: admin/slm-add-licenses.php:296 -#, fuzzy -msgid "Save License" -msgstr "Guardar licencia" - -#: admin/slm-admin-functions.php:14 -#, fuzzy -msgid "Admin Tools" -msgstr "Herramientas de administración" - -#: admin/slm-admin-functions.php:30 -#, fuzzy -msgid "Success message returned from the remote host." -msgstr "Mensaje de éxito devuelto por el host remoto." - -#: admin/slm-admin-functions.php:33 -#, fuzzy -msgid "Request sent to the specified URL!" -msgstr "¡Solicitud enviada a la URL especificada!" - -#: admin/slm-admin-functions.php:45 -#, fuzzy -msgid "Log was cleared successfully!" -msgstr "¡El registro se borró con éxito!" - -#: admin/slm-admin-functions.php:51 -#, fuzzy -msgid "Send Deactivation Message for a License" -msgstr "Enviar mensaje de desactivación de una licencia" - -#: admin/slm-admin-functions.php:56 -#, fuzzy -msgid "Send Request" -msgstr "Enviar solicitud" - -#: admin/slm-admin-functions.php:63 -#, fuzzy -msgid "Clean Activity Log" -msgstr "Limpiar registro de actividad" - -#: admin/slm-admin-functions.php:65 -#, fuzzy -msgid "This will clear/reset license keys activities" -msgstr "Esto borrará/restablecerá las actividades de las claves de licencia" - -#: admin/slm-admin-functions.php:68 -#, fuzzy -msgid "Clear Log" -msgstr "Borrar registro" - -#: admin/slm-admin-functions.php:75 -#, fuzzy -msgid "Backup Database" -msgstr "Base de datos de copia de seguridad" - -#: admin/slm-admin-functions.php:77 -#, fuzzy -msgid "" -"This will create a backup of the database tables related to this plugin and " -"save it to the uploads directory." -msgstr "" -"Esto creará una copia de seguridad de las tablas de la base de datos " -"relacionadas con este complemento y la guardará en el directorio de cargas." - -#: admin/slm-admin-functions.php:80 -#, fuzzy -msgid "Create Backup" -msgstr "Crear copia de seguridad" - -#: admin/slm-admin-functions.php:90 -#, fuzzy -msgid "Last backup created on: " -msgstr "Última copia de seguridad creada el: " - -#: admin/slm-admin-functions.php:90 -#, fuzzy -msgid "Download Backup" -msgstr "Descargar copia de seguridad" - -#: admin/slm-admin-functions.php:172 -#, fuzzy -msgid "Backup created successfully! Download from: " -msgstr "¡Copia de seguridad creada con éxito! Descargar desde: " - -#: admin/slm-admin-functions.php:174 -#, fuzzy -msgid "Error: Failed to create the backup file." -msgstr "Error: No se pudo crear el archivo de copia de seguridad." - -#: admin/slm-dashboard-widgets.php:30 admin/slm-dashboard-widgets.php:33 -#: admin/slm-list-licenses-class.php:479 -#, fuzzy -msgid "SLM" -msgstr "SLM" - -#: admin/slm-dashboard-widgets.php:42 -msgid "Overview" -msgstr "Visión general" - -#: admin/slm-dashboard-widgets.php:52 -#, fuzzy -msgid "Add new license" -msgstr "Agregar nueva licencia" - -#: admin/slm-dashboard-widgets.php:62 admin/slm-list-licenses-class.php:485 -#: includes/slm-plugin-core.php:39 -msgid "Settings" -msgstr "Configuración" - -#: admin/slm-integration-help-page.php:11 -#, fuzzy -msgid "License Manager Integration Help" -msgstr "Ayuda de integración de License Manager" - -#: admin/slm-integration-help-page.php:34 -#, fuzzy -msgid "API Settings" -msgstr "Configuración de la API" - -#: admin/slm-integration-help-page.php:42 -#, fuzzy -msgid "The License API Query POST URL For Your Installation" -msgstr "La URL POST de la consulta de la API de licencia para su instalación" - -#: admin/slm-integration-help-page.php:45 -#, fuzzy -msgid "The License Activation or Deactivation API Secret Key" -msgstr "La clave secreta de la API de activación o desactivación de licencias" - -#: admin/slm-integration-help-page.php:48 -#, fuzzy -msgid "The License Creation API Secret Key" -msgstr "La clave secreta de la API de creación de licencias" - -#: admin/slm-integration-help-page.php:54 -#, fuzzy -msgid "Documentation and guides:" -msgstr "Documentación y guías:" - -#: admin/slm-integration-help-page.php:55 -#, fuzzy -msgid "Check out Postman demos" -msgstr "Echa un vistazo a las demostraciones de Postman" - -#: admin/slm-integration-help-page.php:60 -#, fuzzy -msgid "Error Codes and Descriptions" -msgstr "Códigos de error y descripciones" - -#: admin/slm-integration-help-page.php:65 -#, fuzzy -msgid "Constant" -msgstr "Constante" - -#: admin/slm-integration-help-page.php:66 -#, fuzzy -msgid "Error Code" -msgstr "Código de error" - -#: admin/slm-integration-help-page.php:67 -msgid "Description" -msgstr "Descripción" - -#: admin/slm-integration-help-page.php:73 -#, fuzzy -msgid "The license creation failed due to an unknown error." -msgstr "La creación de la licencia falló debido a un error desconocido." - -#: admin/slm-integration-help-page.php:77 -#, fuzzy -msgid "The license key provided during creation is invalid." -msgstr "La clave de licencia proporcionada durante la creación no es válida." - -#: admin/slm-integration-help-page.php:81 -#, fuzzy -msgid "The domain associated with this license is already inactive." -msgstr "El dominio asociado a esta licencia ya está inactivo." - -#: admin/slm-integration-help-page.php:85 -#, fuzzy -msgid "The domain information is missing in the request." -msgstr "Falta la información del dominio en la solicitud." - -#: admin/slm-integration-help-page.php:89 -#, fuzzy -msgid "The license key has been canceled." -msgstr "La clave de licencia ha sido cancelada." - -#: admin/slm-integration-help-page.php:93 -#, fuzzy -msgid "Failed to cancel the license key." -msgstr "No se pudo cancelar la clave de licencia." - -#: admin/slm-integration-help-page.php:97 -#, fuzzy -msgid "Successfully deactivated the license key for the specified domain." -msgstr "" -"Se ha desactivado correctamente la clave de licencia para el dominio " -"especificado." - -#: admin/slm-integration-help-page.php:101 -#, fuzzy -msgid "The license key was successfully deactivated." -msgstr "La clave de licencia se ha desactivado correctamente." - -#: admin/slm-integration-help-page.php:105 -#, fuzzy -msgid "Failed to delete the license key." -msgstr "No se pudo eliminar la clave de licencia." - -#: admin/slm-integration-help-page.php:109 -#, fuzzy -msgid "The license key was successfully deleted." -msgstr "La clave de licencia se ha eliminado correctamente." - -#: admin/slm-integration-help-page.php:113 -#, fuzzy -msgid "The license key has been deleted." -msgstr "Se ha eliminado la clave de licencia." - -#: admin/slm-integration-help-page.php:117 -#, fuzzy -msgid "Failed to update the license key details." -msgstr "No se pudieron actualizar los detalles de la clave de licencia." - -#: admin/slm-integration-help-page.php:121 -#, fuzzy -msgid "The license key was successfully updated." -msgstr "La clave de licencia se actualizó correctamente." - -#: admin/slm-integration-help-page.php:125 -#, fuzzy -msgid "The license key was successfully activated." -msgstr "La clave de licencia se ha activado correctamente." - -#: admin/slm-integration-help-page.php:129 -#, fuzzy -msgid "The license key has been blocked from further use." -msgstr "Se ha bloqueado el uso posterior de la clave de licencia." - -#: admin/slm-integration-help-page.php:133 -#, fuzzy -msgid "The license key was successfully created." -msgstr "La clave de licencia se ha creado correctamente." - -#: admin/slm-integration-help-page.php:137 -#, fuzzy -msgid "The license key already exists in the system." -msgstr "La clave de licencia ya existe en el sistema." - -#: admin/slm-integration-help-page.php:141 -#, fuzzy -msgid "The license key has expired." -msgstr "La clave de licencia ha caducado." - -#: admin/slm-integration-help-page.php:145 -#, fuzzy -msgid "The license key is already in use on another domain or device." -msgstr "La clave de licencia ya está en uso en otro dominio o dispositivo." - -#: admin/slm-integration-help-page.php:149 -#, fuzzy -msgid "The license key is invalid." -msgstr "La clave de licencia no es válida." - -#: admin/slm-integration-help-page.php:153 -#, fuzzy -msgid "Failed to delete the license key because it was not found." -msgstr "No se pudo eliminar la clave de licencia porque no se encontró." - -#: admin/slm-integration-help-page.php:157 -#, fuzzy -msgid "Failed to update the license key because it was not found." -msgstr "No se pudo actualizar la clave de licencia porque no se encontró." - -#: admin/slm-integration-help-page.php:161 -#, fuzzy -msgid "The license key has reached its maximum allowable devices." -msgstr "" -"La clave de licencia ha alcanzado el máximo de dispositivos permitidos." - -#: admin/slm-integration-help-page.php:165 -#, fuzzy -msgid "The license key has reached its maximum allowable domains." -msgstr "La clave de licencia ha alcanzado sus dominios máximos permitidos." - -#: admin/slm-integration-help-page.php:169 -#, fuzzy -msgid "The key verification failed due to an invalid key." -msgstr "Error en la verificación de la clave debido a una clave no válida." - -#: admin/slm-lic-settings.php:22 -#, fuzzy -msgid "Debug log files have been reset!" -msgstr "¡Se han restablecido los archivos de registro de depuración!" - -#: admin/slm-lic-settings.php:53 -#, fuzzy -msgid "Options updated!" -msgstr "¡Opciones actualizadas!" - -#: admin/slm-lic-settings.php:63 -#, fuzzy -msgid "Settings - SLM Plus" -msgstr "Ajustes - SLM Plus" - -#: admin/slm-lic-settings.php:69 -msgid "General Settings" -msgstr "Ajustes generales" - -#: admin/slm-lic-settings.php:73 -#, fuzzy -msgid "Integrations" -msgstr "Integraciones" - -#: admin/slm-lic-settings.php:77 -#, fuzzy -msgid "Debugging settings" -msgstr "Configuración de depuración" - -#: admin/slm-lic-settings.php:81 -msgid "Emails" -msgstr "Correos electrónicos" - -#: admin/slm-lic-settings.php:107 -#, fuzzy -msgid "Secret Key for License Creation" -msgstr "Clave secreta para la creación de licencias" - -#: admin/slm-lic-settings.php:110 -#, fuzzy -msgid "" -"This secret key will be used to authenticate any license creation request. " -"You can change it with something random." -msgstr "" -"Esta clave secreta se utilizará para autenticar cualquier solicitud de " -"creación de licencia. Puedes cambiarlo con algo aleatorio." - -#: admin/slm-lic-settings.php:114 -#, fuzzy -msgid "Secret Key for License Verification Requests" -msgstr "Clave secreta para solicitudes de verificación de licencias" - -#: admin/slm-lic-settings.php:116 -#, fuzzy -msgid "" -"This secret key will be used to authenticate any license verification " -"request from customer's site. Important! Do not change this value once your " -"customers start to use your product(s)!" -msgstr "" -"Esta clave secreta se utilizará para autenticar cualquier solicitud de " -"verificación de licencia desde el sitio del cliente. ¡Importante! ¡No " -"cambies este valor una vez que tus clientes comiencen a usar tu(s) " -"producto(s)!" - -#: admin/slm-lic-settings.php:120 -#, fuzzy -msgid "License Key Prefix" -msgstr "Prefijo de clave de licencia" - -#: admin/slm-lic-settings.php:122 -#, fuzzy -msgid "" -"You can optionaly specify a prefix for the license keys. This prefix will be " -"added to the uniquely generated license keys." -msgstr "" -"Opcionalmente, puede especificar un prefijo para las claves de licencia. " -"Este prefijo se agregará a las claves de licencia generadas de forma única." - -#: admin/slm-lic-settings.php:126 -#, fuzzy -msgid "Maximum Allowed Domains" -msgstr "Dominios máximos permitidos" - -#: admin/slm-lic-settings.php:128 -#, fuzzy -msgid "" -"Maximum number of domains/installs which each license is valid for (default " -"value)." -msgstr "" -"Número máximo de dominios/instalaciones para los que es válida cada licencia " -"(valor predeterminado)." - -#: admin/slm-lic-settings.php:132 -#, fuzzy -msgid "Maximum Allowed Devices" -msgstr "Dispositivo máximo permitido" - -#: admin/slm-lic-settings.php:134 -#, fuzzy -msgid "" -"Maximum number of devices which each license is valid for (default value)." -msgstr "" -"Número máximo de dispositivos para los que es válida cada licencia (valor " -"predeterminado)." - -#: admin/slm-lic-settings.php:138 -#, fuzzy -msgid "Auto Expire License Keys" -msgstr "Caducidad automática de las claves de licencia" - -#: admin/slm-lic-settings.php:140 -#, fuzzy -msgid "Enable auto expiration " -msgstr "Habilitar la caducidad automática " - -#: admin/slm-lic-settings.php:141 -#, fuzzy -msgid "" -" When enabled, it will automatically set the status of a license key to " -"\"Expired\" when the expiry date value of the key is reached. It doesn't " -"remotely deactivate a key. It simply changes the status of the key in your " -"database to expired." -msgstr "" -" Cuando está habilitado, establecerá automáticamente el estado de una clave " -"de licencia en \"Caducado\" cuando se alcance el valor de la fecha de " -"caducidad de la clave. No desactiva una tecla de forma remota. Simplemente " -"cambia el estado de la clave en su base de datos a caducada." - -#: admin/slm-lic-settings.php:145 -#, fuzzy -msgid "General settings" -msgstr "Ajustes generales" - -#: admin/slm-lic-settings.php:148 -#, fuzzy -msgid "Enable stats in licenses overview page." -msgstr "" -"Habilite las estadísticas en la página de información general de licencias." - -#: admin/slm-lic-settings.php:156 -#, fuzzy -msgid "Enable admin bar shortcut link" -msgstr "Habilitar el enlace de acceso directo de la barra de administración" - -#: admin/slm-lic-settings.php:161 -#, fuzzy -msgid "Multiple items validation" -msgstr "Validación de varios elementos" - -#: admin/slm-lic-settings.php:164 -#, fuzzy -msgid "Enable verification of Item reference." -msgstr "Habilite la verificación de la referencia del artículo." - -#: admin/slm-lic-settings.php:165 -#, fuzzy -msgid "" -"When enabled, there will be another field in Licenced product - Item " -"reference. This field should correspond to the API parameter item_reference " -"of your software." -msgstr "" -"Cuando esté habilitado, habrá otro campo en Producto con licencia - " -"Referencia del artículo. Este campo debe corresponder al item_reference de " -"parámetros de API de su software." - -#: admin/slm-lic-settings.php:170 -#, fuzzy -msgid "User permissions" -msgstr "Permisos de usuario" - -#: admin/slm-lic-settings.php:173 -#, fuzzy -msgid "Allow users to remove domains/devices in My account." -msgstr "Permitir que los usuarios eliminen dominios/dispositivos en Mi cuenta." - -#: admin/slm-lic-settings.php:174 -#, fuzzy -msgid "" -"When enabled, users will be able to remove registered domains or devices in " -"their account." -msgstr "" -"Cuando esté habilitado, los usuarios podrán eliminar dominios o dispositivos " -"registrados en su cuenta." - -#: admin/slm-lic-settings.php:179 -#, fuzzy -msgid "Bootstrap library" -msgstr "Biblioteca de Bootstrap" - -#: admin/slm-lic-settings.php:182 -#, fuzzy -msgid "Enable Bootstrap javascript libray." -msgstr "Habilite la biblioteca javascript de Bootstrap." - -#: admin/slm-lic-settings.php:189 -#, fuzzy -msgid "" -"Enable Bootstrap javascript libray in front-end (woocommerce pages, etc)." -msgstr "" -"Habilite la biblioteca javascript de Bootstrap en el front-end (páginas de " -"woocommerce, etc.)." - -#: admin/slm-lic-settings.php:202 -#, fuzzy -msgid "Woocommerce Support" -msgstr "Soporte de Woocommerce" - -#: admin/slm-lic-settings.php:205 -#, fuzzy -msgid "" -"A fully customizable, open source eCommerce platform built for WordPress." -msgstr "" -"Una plataforma de comercio electrónico de código abierto totalmente " -"personalizable creada para WordPress." - -#: admin/slm-lic-settings.php:212 -#, fuzzy -msgid "" -"Disable woocommerce download page. Process downloads though license order " -"info page." -msgstr "" -"Desactiva la página de descarga de woocommerce. Procese las descargas a " -"través de la página de información del pedido de licencia." - -#: admin/slm-lic-settings.php:219 -#, fuzzy -msgid "" -"Expire WooCommerce downloads. Downloads will expire together with " -"corresponding license." -msgstr "" -"Caducar las descargas de WooCommerce. Las descargas caducarán junto con la " -"licencia correspondiente." - -#: admin/slm-lic-settings.php:223 -#, fuzzy -msgid "Download Manager Support" -msgstr "Soporte técnico de Download Manager" - -#: admin/slm-lic-settings.php:226 -#, fuzzy -msgid "" -"Download Manager Plugin – Adds a simple download manager to your WordPress " -"blog." -msgstr "" -"Plugin de administrador de descargas: agrega un administrador de descargas " -"simple a su blog de WordPress." - -#: admin/slm-lic-settings.php:230 -#, fuzzy -msgid "WP eStores Support" -msgstr "Soporte de WP eStores" - -#: admin/slm-lic-settings.php:233 -#, fuzzy -msgid "" -"WordPress eStore Plugin – Complete Solution to Sell Digital Products from " -"Your WordPress Blog Securely" -msgstr "" -"Plugin de WordPress eStore: solución completa para vender productos " -"digitales desde su blog de WordPress de forma segura" - -#: admin/slm-lic-settings.php:245 -#, fuzzy -msgid "Enable Debug Logging" -msgstr "Habilitar el registro de depuración" - -#: admin/slm-lic-settings.php:248 -#, fuzzy -msgid "If checked, debug output will be written to log files." -msgstr "" -"Si se selecciona, la salida de depuración se escribirá en los archivos de " -"registro." - -#: admin/slm-lic-settings.php:259 -#, fuzzy -msgid "Expiration reminder" -msgstr "Recordatorio de caducidad" - -#: admin/slm-lic-settings.php:269 -#, fuzzy -msgid "Update Options" -msgstr "Opciones de actualización" - -#: admin/slm-list-licenses-class.php:27 -#, fuzzy -msgid "No licenses avaliable." -msgstr "No hay licencias disponibles." - -#: admin/slm-list-licenses-class.php:43 -msgid "All" -msgstr "Todo" - -#: admin/slm-list-licenses-class.php:50 -msgid "active" -msgstr "activos" - -#: admin/slm-list-licenses-class.php:57 -msgid "pending" -msgstr "Pendiente" - -#: admin/slm-list-licenses-class.php:64 -msgid "expired" -msgstr "caducado" - -#: admin/slm-list-licenses-class.php:71 -#, fuzzy -msgid "blocked" -msgstr "bloqueado" - -#: admin/slm-list-licenses-class.php:84 admin/slm-subscribers.php:85 -#: admin/slm-subscribers.php:187 includes/slm-utility.php:789 -msgid "ID" -msgstr "ID" - -#: admin/slm-list-licenses-class.php:85 admin/slm-subscribers.php:189 -#: woocommerce/includes/wc_licenses_class.php:136 -#: woocommerce/includes/wc_licenses_class.php:149 -msgid "Status" -msgstr "Estado" - -#: admin/slm-list-licenses-class.php:86 -msgid "Key" -msgstr "Clave" - -#: admin/slm-list-licenses-class.php:87 -#, fuzzy -msgid "Item reference" -msgstr "Referencia del artículo" - -#: admin/slm-list-licenses-class.php:88 -#: woocommerce/includes/wc_licenses_class.php:241 -#, fuzzy -msgid "License type" -msgstr "Tipo de licencia" - -#: admin/slm-list-licenses-class.php:90 -#, fuzzy -msgid "Domains" -msgstr "Dominios" - -#: admin/slm-list-licenses-class.php:91 -#, fuzzy -msgid "Devices" -msgstr "Dispositivos" - -#: admin/slm-list-licenses-class.php:92 -#, fuzzy -msgid "Order #" -msgstr "Orden #" - -#: admin/slm-list-licenses-class.php:93 -msgid "Created on" -msgstr "Creado en" - -#: admin/slm-list-licenses-class.php:94 -#, fuzzy -msgid "Renewed on" -msgstr "Renovado el" - -#: admin/slm-list-licenses-class.php:95 -#, fuzzy -msgid "Activated on" -msgstr "Activado el" - -#: admin/slm-list-licenses-class.php:96 -#: woocommerce/includes/wc_licenses_class.php:238 -msgid "Expiration" -msgstr "Vencimiento" - -#: admin/slm-list-licenses-class.php:97 -#, fuzzy -msgid "Until Ver." -msgstr "Hasta la Ver." - -#: admin/slm-list-licenses-class.php:98 -#, fuzzy -msgid "Current Ver." -msgstr "La versión actual." - -#: admin/slm-list-licenses-class.php:120 -#, fuzzy -msgid " Lifetime " -msgstr " Vida " - -#: admin/slm-list-licenses-class.php:213 admin/slm-list-licenses-class.php:231 -#: admin/slm-list-licenses-class.php:249 admin/slm-list-licenses-class.php:267 -#: admin/slm-list-licenses-class.php:285 -#, fuzzy -msgid "Error - Please select some records using the checkboxes" -msgstr "" -"Error: seleccione algunos registros usando las casillas de verificación" - -#: admin/slm-list-licenses-class.php:480 -#, fuzzy -msgid "Manage Licenses" -msgstr "Administrar licencias" - -#: admin/slm-list-licenses-class.php:482 -#, fuzzy -msgid "Create license" -msgstr "Crear licencia" - -#: admin/slm-list-licenses-class.php:483 -#, fuzzy -msgid "Subscribers" -msgstr "Suscriptores" - -#: admin/slm-list-licenses-class.php:484 -msgid "Tools" -msgstr "Herramientas" - -#: admin/slm-list-licenses-class.php:486 -msgid "Help" -msgstr "Ayuda" - -#: admin/slm-list-licenses-class.php:488 -msgid "About" -msgstr "Acerca" - -#: admin/slm-manage-licenses.php:15 -#, fuzzy -msgid "You do not have permission to manage this license." -msgstr "No tiene permiso para administrar esta licencia." - -#: admin/slm-manage-licenses.php:36 -#, fuzzy -msgid "Overview - Manage licenses" -msgstr "Información general - Administrar licencias" - -#: admin/slm-manage-licenses.php:38 -msgid "Add New" -msgstr "Agregar nuevo" - -#: admin/slm-manage-licenses.php:62 admin/slm-subscribers.php:217 -msgid "Search" -msgstr "Buscar" - -#: admin/slm-subscribers.php:88 -msgid "Email Address" -msgstr "Correo electronico" - -#: admin/slm-subscribers.php:176 -#, fuzzy -msgid "Overview - Manage Subscribers" -msgstr "Descripción general - Administrar suscriptores" - -#: admin/slm-subscribers.php:178 -msgid "View all" -msgstr "Ver todo" - -#: admin/slm-subscribers.php:188 woocommerce/includes/wc_licenses_class.php:138 -#, fuzzy -msgid "License key" -msgstr "Clave de licencia" - -#: admin/slm-subscribers.php:206 -#, fuzzy -msgid "Overview - All Subscribers" -msgstr "Resumen - Todos los suscriptores" - -#: admin/slm_about_menu.php:15 -#, fuzzy -msgid "SLM Logo" -msgstr "Logotipo de SLM" - -#: admin/slm_about_menu.php:15 -#, fuzzy -msgid "SLM - About" -msgstr "SLM - Acerca de" - -#: admin/slm_about_menu.php:26 -#, fuzzy -msgid "Credits and authors" -msgstr "Créditos y autores" - -#: admin/slm_about_menu.php:28 -#, fuzzy -msgid "" -"Software license management solution for your web applications (WordPress " -"plugins, Themes, Applications, PHP based membership script, etc.). Supports " -"WooCommerce." -msgstr "" -"Solución de gestión de licencias de software para sus aplicaciones web " -"(plugins de WordPress, Temas, Aplicaciones, scripts de membresía basados en " -"PHP, etc.). Compatible con WooCommerce." - -#: admin/slm_about_menu.php:33 -#, fuzzy -msgid "Information" -msgstr "Información" - -#: admin/slm_about_menu.php:34 -msgid "Details" -msgstr "Detalles" - -#: admin/slm_about_menu.php:39 -#, fuzzy -msgid "Authors" -msgstr "Autores" - -#: admin/slm_about_menu.php:42 -msgid "and" -msgstr "y" - -#: admin/slm_about_menu.php:47 -#, fuzzy -msgid "Help and Support" -msgstr "Ayuda y soporte" - -#: admin/slm_about_menu.php:50 -#, fuzzy -msgid "Submit a request" -msgstr "Enviar una solicitud" - -#: admin/slm_about_menu.php:55 -#, fuzzy -msgid "API Demos" -msgstr "Demostraciones de API" - -#: admin/slm_about_menu.php:58 -#, fuzzy -msgid "Postman Demos" -msgstr "Demostraciones de cartero" - -#: includes/class-slm-installer.php:41 -msgid "Pending" -msgstr "Pendientes" - -#: includes/class-slm-installer.php:42 -msgid "Active" -msgstr "Activos" - -#: includes/class-slm-installer.php:43 -msgid "Blocked" -msgstr "Bloqueado" - -#: includes/class-slm-installer.php:44 -#: woocommerce/includes/wc_licenses_class.php:175 -msgid "Expired" -msgstr "Vencido" - -#: includes/slm-plugin-core.php:40 -msgid "GitHub" -msgstr "GitHub" - -#: includes/slm-utility.php:365 -#, fuzzy, php-format -msgid "%s days remaining until %s" -msgstr "%s días que faltan para %s" - -#: includes/slm-utility.php:777 -#, fuzzy -msgid " view" -msgstr " vista" - -#: includes/slm-utility.php:789 -msgid "Request" -msgstr "Solicitud" - -#: includes/slm-utility.php:797 -#, fuzzy -msgid "Source:" -msgstr "Fuente:" - -#: includes/slm-utility.php:798 -msgid "Time:" -msgstr "Hora:" - -#: includes/slm-utility.php:844 -#, fuzzy -msgid "Not registered yet" -msgstr "Aún no se ha registrado" - -#: includes/slm-utility.php:862 includes/slm-utility.php:874 -#: woocommerce/includes/wc_licenses_class.php:235 -#, fuzzy -msgid "License information" -msgstr "Información de la licencia" - -#: includes/slm-utility.php:875 -#, fuzzy -msgid "License type: " -msgstr "Tipo de licencia: " - -#: includes/slm-utility.php:876 -#, fuzzy -msgid "Domains allowed: " -msgstr "Dominios permitidos: " - -#: includes/slm-utility.php:877 -#, fuzzy -msgid "Devices allowed: " -msgstr "Dispositivos permitidos: " - -#: includes/slm-utility.php:878 -#, fuzzy -msgid "Renews every " -msgstr "Renueva cada " - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:54 -#, fuzzy -msgid "View details" -msgstr "Ver detalles" - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:77 -#, fuzzy, php-format -msgid "More information about %s" -msgstr "Más información sobre %s" - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:128 -#, fuzzy -msgid "Check for updates" -msgstr "Buscar actualizaciones" - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:213 -#, fuzzy, php-format -msgctxt "the plugin title" -msgid "The %s plugin is up to date." -msgstr "El plugin %s está actualizado." - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:215 -#, fuzzy, php-format -msgctxt "the plugin title" -msgid "A new version of the %s plugin is available." -msgstr "Está disponible una nueva versión del plugin %s." - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:217 -#, fuzzy, php-format -msgctxt "the plugin title" -msgid "Could not determine if updates are available for %s." -msgstr "No se pudo determinar si hay actualizaciones disponibles para %s." - -#: plugin-update-checker/Puc/v4p9/Plugin/Ui.php:223 -#, fuzzy, php-format -msgid "Unknown update checker status \"%s\"" -msgstr "Estado desconocido del comprobador de actualizaciones \"%s\"" - -#: plugin-update-checker/Puc/v4p9/Vcs/PluginUpdateChecker.php:98 -#, fuzzy -msgid "There is no changelog available." -msgstr "No hay registro de cambios disponible." - -#: woocommerce/includes/purchase.php:94 -#, fuzzy -msgid "License no longer exists" -msgstr "La licencia ya no existe" - -#: woocommerce/includes/purchase.php:99 -#: woocommerce/includes/wc_licenses_class.php:209 -msgid "License Key:" -msgstr "Clave de licencia:" - -#: woocommerce/includes/purchase.php:197 -#, fuzzy -msgid "License could not be created: Invalid sites allowed number." -msgstr "No se pudo crear la licencia: número de sitios permitidos no válidos." - -#: woocommerce/includes/purchase.php:343 -#, fuzzy -msgid "License Key(s) generated:" -msgstr "Clave(s) de licencia generada(s):" - -#: woocommerce/includes/purchase.php:372 -#, fuzzy -msgid "License Key(s) could not be created." -msgstr "No se han podido crear las claves de licencia." - -#: woocommerce/includes/purchase.php:626 -#, fuzzy, php-format -msgid "Order confirmation email sent to: %s" -msgstr "" -"Correo electrónico de confirmación del pedido enviado a: %s" - -#: woocommerce/includes/purchase.php:690 -#, fuzzy -msgid "License Expiration" -msgstr "Caducidad de la licencia" - -#: woocommerce/includes/purchase.php:692 -#, fuzzy -msgid "License Item Reference" -msgstr "Referencia de elementos de licencia" - -#: woocommerce/includes/purchase.php:694 -#, fuzzy -msgid "License Current Version" -msgstr "Licencia Versión actual" - -#: woocommerce/includes/purchase.php:695 -#, fuzzy -msgid "Supported Until Version" -msgstr "Compatible hasta la versión" - -#: woocommerce/includes/purchase.php:744 -#, fuzzy -msgid "License Details" -msgstr "Detalles de la licencia" - -#: woocommerce/includes/purchase.php:749 -msgid "Type" -msgstr "Tipo" - -#: woocommerce/includes/purchase.php:759 -#, fuzzy -msgid "View My Licenses" -msgstr "Ver mis licencias" - -#: woocommerce/includes/purchase.php:817 -msgid "License Keys" -msgstr "Claves de Licencia" - -#: woocommerce/includes/purchase.php:822 -#: woocommerce/includes/wc_licenses_class.php:137 -#: woocommerce/includes/wc_licenses_class.php:155 -msgid "Product" -msgstr "Producto" - -#: woocommerce/includes/slm-meta-boxes.php:51 -#, fuzzy -msgid "License product" -msgstr "Producto de licencia" - -#: woocommerce/includes/slm-meta-boxes.php:68 -msgid "License Manager" -msgstr "Administrador de Licencias" - -#: woocommerce/includes/slm-meta-boxes.php:70 -#, fuzzy -msgid "Enables the license creation API." -msgstr "Habilita la API de creación de licencias." - -#: woocommerce/includes/slm-meta-boxes.php:146 -#, fuzzy -msgid "Domain Licenses" -msgstr "Licencias de dominio" - -#: woocommerce/includes/slm-meta-boxes.php:152 -#, fuzzy -msgid "Enter the allowed number of domains this license can have (websites)." -msgstr "" -"Introduzca el número permitido de dominios que puede tener esta licencia " -"(sitios web)." - -#: woocommerce/includes/slm-meta-boxes.php:161 -#, fuzzy -msgid "Devices Licenses" -msgstr "Licencias de dispositivos" - -#: woocommerce/includes/slm-meta-boxes.php:167 -#, fuzzy -msgid "" -"Enter the allowed number of devices this license can have (computers, " -"mobile, etc)." -msgstr "" -"Introduzca el número permitido de dispositivos que puede tener esta licencia " -"(ordenadores, móviles, etc.)." - -#: woocommerce/includes/slm-meta-boxes.php:175 -#, fuzzy -msgid "Software's item reference" -msgstr "Referencia del artículo del software" - -#: woocommerce/includes/slm-meta-boxes.php:177 -#, fuzzy -msgid "" -"Enter the item reference of your application, theme, or plug-in. The license " -"will be then bound to this exact software." -msgstr "" -"Introduzca la referencia del elemento de la aplicación, el tema o el " -"complemento. A continuación, la licencia se vinculará a este software exacto." - -#: woocommerce/includes/slm-meta-boxes.php:186 -#, fuzzy -msgid "Type of license: subscription base or lifetime" -msgstr "Tipo de licencia: base de suscripción o de por vida" - -#: woocommerce/includes/slm-meta-boxes.php:188 -#, fuzzy -msgid "Select one" -msgstr "Seleccione uno" - -#: woocommerce/includes/slm-meta-boxes.php:197 -#, fuzzy -msgid "Renewal Period Length" -msgstr "Duración del período de renovación" - -#: woocommerce/includes/slm-meta-boxes.php:198 -#, fuzzy -msgid "Amount of days, months, or years." -msgstr "Cantidad de días, meses o años." - -#: woocommerce/includes/slm-meta-boxes.php:208 -#, fuzzy -msgid "Expiration Term" -msgstr "Plazo de caducidad" - -#: woocommerce/includes/slm-meta-boxes.php:210 -#, fuzzy -msgid "Choose between days, months, or years" -msgstr "Elige entre días, meses o años" - -#: woocommerce/includes/slm-meta-boxes.php:212 -#, fuzzy -msgid "Day(s)" -msgstr "Día(s)" - -#: woocommerce/includes/slm-meta-boxes.php:213 -#, fuzzy -msgid "Month(s)" -msgstr "Mes(es)" - -#: woocommerce/includes/slm-meta-boxes.php:214 -#, fuzzy -msgid "Year(s)" -msgstr "Año(s)" - -#: woocommerce/includes/slm-meta-boxes.php:215 -#, fuzzy -msgid "One Time" -msgstr "Una vez" - -#: woocommerce/includes/slm-meta-boxes.php:228 -#, fuzzy -msgid "Enter the current version of your application, theme, or plug-in" -msgstr "Introduce la versión actual de tu aplicación, tema o plug-in" - -#: woocommerce/includes/slm-meta-boxes.php:234 -#, fuzzy -msgid "Until Version" -msgstr "Hasta la versión" - -#: woocommerce/includes/slm-meta-boxes.php:237 -#, fuzzy -msgid "Enter the version until support expires." -msgstr "Introduzca la versión hasta que caduque el soporte." - -#: woocommerce/includes/wc_licenses_class.php:83 -#: woocommerce/includes/wc_licenses_class.php:95 -#, fuzzy -msgid "My Licenses" -msgstr "Mis Licencias" - -#: woocommerce/includes/wc_licenses_class.php:122 -#, fuzzy -msgid "Browse products" -msgstr "Ver productos" - -#: woocommerce/includes/wc_licenses_class.php:124 -#, fuzzy -msgid "No licenses available yet." -msgstr "Todavía no hay licencias disponibles." - -#: woocommerce/includes/wc_licenses_class.php:135 -#: woocommerce/includes/wc_licenses_class.php:147 -msgid "Order" -msgstr "Pedido" - -#: woocommerce/includes/wc_licenses_class.php:139 -#: woocommerce/includes/wc_licenses_class.php:168 -#, fuzzy -msgid "Renews on" -msgstr "Se renueva el" - -#: woocommerce/includes/wc_licenses_class.php:140 -msgid "Info" -msgstr "Información" - -#: woocommerce/includes/wc_licenses_class.php:184 -msgid "view" -msgstr "ver" - -#: woocommerce/includes/wc_licenses_class.php:218 -#, fuzzy -msgid "License Information" -msgstr "Información de la licencia" - -#: woocommerce/includes/wc_licenses_class.php:222 -#, fuzzy -msgid "Activations" -msgstr "Activaciones" - -#: woocommerce/includes/wc_licenses_class.php:226 -#, fuzzy -msgid "Copy License" -msgstr "Licencia de copia" - -#: woocommerce/includes/wc_licenses_class.php:239 -#, fuzzy -msgid "Allowed devices" -msgstr "Dispositivos permitidos" - -#: woocommerce/includes/wc_licenses_class.php:240 -#, fuzzy -msgid "Allowed Domains" -msgstr "Dominios permitidos" - -#: woocommerce/includes/wc_licenses_class.php:242 -#, fuzzy -msgid "Date renewed" -msgstr "Fecha de renovación" - -#: woocommerce/includes/wc_licenses_class.php:243 -#, fuzzy -msgid "Activation Date" -msgstr "Fecha de activación" - -#: woocommerce/includes/wc_licenses_class.php:315 -#, fuzzy -msgid "License key was deactivated!" -msgstr "¡La clave de licencia fue desactivada!" - -#: woocommerce/includes/wc_licenses_class.php:317 -#, fuzzy -msgid "License key was not deactivated!" -msgstr "¡La clave de licencia no se ha desactivado!" - -#. Plugin Name of the plugin/theme -#, fuzzy -msgid "SLM Plus" -msgstr "SLM Plus" - -#. Plugin URI of the plugin/theme -#, fuzzy -msgid "https://github.com/michelve/software-license-manager/" -msgstr "https://github.com/michelve/software-license-manager/" - -#. Description of the plugin/theme -#, fuzzy -msgid "" -"A comprehensive software license management solution for web applications " -"including WordPress plugins, themes, and PHP-based software. Seamlessly " -"integrates with WooCommerce to offer license key generation, management, and " -"validation. Ideal for developers managing software licenses across multiple " -"platforms with built-in multilingual support and performance optimization." -msgstr "" -"Una solución integral de gestión de licencias de software para aplicaciones " -"web, incluidos complementos de WordPress, temas y software basado en PHP. Se " -"integra a la perfección con WooCommerce para ofrecer generación, gestión y " -"validación de claves de licencia. Ideal para desarrolladores que administran " -"licencias de software en múltiples plataformas con soporte multilingüe " -"integrado y optimización del rendimiento." - -#. Author of the plugin/theme -#, fuzzy -msgid "Michel Velis" -msgstr "Michel Velis" - -#. Author URI of the plugin/theme -#, fuzzy -msgid "https://github.com/michelve/" -msgstr "https://github.com/michelve/" diff --git a/i18n/languages/slmplus.mo b/i18n/languages/slmplus.mo deleted file mode 100644 index 63d5c2a76b3dd2c8f278134934e287720b4cc6d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2756 zcmaKsU1(fI6vs!~`mwFnwtm&msamTwce~l9P;V?HO_L^=G)p&$g2i=m?{qWq?w#w* z+%&;H>8sKQ>q|ux3I(+vg5U>=R4O9);Dex`AR;Kz7ax66{GWSgvnhzfp8d_4IWyRsLH`8F{w*vfyR#tW z@d8M8pMiAlFTh*DZ@m5sxEcBtkmCFs#E(^Ayan6>()W&a(leI5vT_ zZX5n+pFR+#Y!68G`$5X{sMlve@_!VhxRlp5NPbU%wEsyze+s01PlI&MGa#M z9%}UcKMc7YLNQRgvjpo0cR=V3-w&a?p}gD;={C9-`c~+^so@C4nW#@WqWnDqq5N=2 z4e|iwF-R5CZFC=X$acuR-NB(bojW!ZIkhO+P#p8a@;Dnx5_TZb(epB9!@84+beSI( z9m$4`6i&umr|cj)-0SS1w2@JnQ#2u+P>E$D9iaT@*w{$x$ACp?mU%3e*~n6+j40L> zT{s+7#=6qoA(=`e65f=~skCj`A?3#MIW{JfjEx^;y#tt>E%qanbaXUvv9)&l1;P7zer;yDI-Wj=DnAp z7`-4P7mUZjtTYxog}ga2$s0*-D~+k(h+I@O8qlqTyk4sh1pT$3zL(eQVZ9dA25Pkm zB`GL^NrclT|OVL@Shg{m$K>y>F$??gNp2z-btum}rCsXW$Q-s{fCATX} zgh~f_G%t*mZr{xGXt1|uM~6QqO)!#1n$j8ay>rS{o({^(Edpt187s$kSNCANRDuJ- z%1pTVkXNg_s@2}aXd>D+SZX8v@E-CY5OEwty3;{icAq1M#Q|;DTl7?8ObXm_$ZgUI zGNi4V&1b#&rp`?yhsz^`ygb87Eclp?YZKcEW#O>Z8f?kIRvPyA)dyQkga{+uPP!Bh zM13@eN6`|_87x@o%3jwmps9J+NxW6jEv<^~%C@ak>#X#dE|tpe(od_E`fRM&tU6io zwKkB+poU!j*Tl$Dl;p9D$zW%-qtfbv{a?HOkRyd{l?Hhhg zjZk|cb@>CTFvUabDh@A5S`;c{B$gz2CFNBZqeErg_ zsS_0`m&fctZX;okp7fY%=f;ORVjW#b6O$%s" -msgstr "" - -#: woocommerce/includes/purchase.php:690 -msgid "License Expiration" -msgstr "" - -#: woocommerce/includes/purchase.php:692 -msgid "License Item Reference" -msgstr "" - -#: woocommerce/includes/purchase.php:694 -msgid "License Current Version" -msgstr "" - -#: woocommerce/includes/purchase.php:695 -msgid "Supported Until Version" -msgstr "" - -#: woocommerce/includes/purchase.php:744 -msgid "License Details" -msgstr "" - -#: woocommerce/includes/purchase.php:749 -msgid "Type" -msgstr "" - -#: woocommerce/includes/purchase.php:759 -msgid "View My Licenses" -msgstr "" - -#: woocommerce/includes/purchase.php:817 -msgid "License Keys" -msgstr "" - -#: woocommerce/includes/purchase.php:822 -#: woocommerce/includes/wc_licenses_class.php:137 -#: woocommerce/includes/wc_licenses_class.php:155 -msgid "Product" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:51 -msgid "License product" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:68 -msgid "License Manager" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:70 -msgid "Enables the license creation API." -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:146 -msgid "Domain Licenses" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:152 -msgid "Enter the allowed number of domains this license can have (websites)." -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:161 -msgid "Devices Licenses" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:167 -msgid "" -"Enter the allowed number of devices this license can have (computers, " -"mobile, etc)." -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:175 -msgid "Software's item reference" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:177 -msgid "" -"Enter the item reference of your application, theme, or plug-in. The license " -"will be then bound to this exact software." -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:186 -msgid "Type of license: subscription base or lifetime" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:188 -msgid "Select one" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:197 -msgid "Renewal Period Length" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:198 -msgid "Amount of days, months, or years." -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:208 -msgid "Expiration Term" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:210 -msgid "Choose between days, months, or years" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:212 -msgid "Day(s)" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:213 -msgid "Month(s)" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:214 -msgid "Year(s)" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:215 -msgid "One Time" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:228 -msgid "Enter the current version of your application, theme, or plug-in" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:234 -msgid "Until Version" -msgstr "" - -#: woocommerce/includes/slm-meta-boxes.php:237 -msgid "Enter the version until support expires." -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:83 -#: woocommerce/includes/wc_licenses_class.php:95 -msgid "My Licenses" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:122 -msgid "Browse products" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:124 -msgid "No licenses available yet." -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:135 -#: woocommerce/includes/wc_licenses_class.php:147 -msgid "Order" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:139 -#: woocommerce/includes/wc_licenses_class.php:168 -msgid "Renews on" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:140 -msgid "Info" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:184 -msgid "view" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:218 -msgid "License Information" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:222 -msgid "Activations" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:226 -msgid "Copy License" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:239 -msgid "Allowed devices" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:240 -msgid "Allowed Domains" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:242 -msgid "Date renewed" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:243 -msgid "Activation Date" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:315 -msgid "License key was deactivated!" -msgstr "" - -#: woocommerce/includes/wc_licenses_class.php:317 -msgid "License key was not deactivated!" -msgstr "" - -#. Plugin Name of the plugin/theme -msgid "SLM Plus" -msgstr "" - -#. Plugin URI of the plugin/theme -msgid "https://github.com/michelve/software-license-manager/" -msgstr "" - -#. Description of the plugin/theme -msgid "" -"A comprehensive software license management solution for web applications " -"including WordPress plugins, themes, and PHP-based software. Seamlessly " -"integrates with WooCommerce to offer license key generation, management, and " -"validation. Ideal for developers managing software licenses across multiple " -"platforms with built-in multilingual support and performance optimization." -msgstr "" - -#. Author of the plugin/theme -msgid "Michel Velis" -msgstr "" - -#. Author URI of the plugin/theme -msgid "https://github.com/michelve/" -msgstr "" diff --git a/includes/class-slm-installer.php b/includes/class-slm-installer.php index 3402d26..1c149da 100755 --- a/includes/class-slm-installer.php +++ b/includes/class-slm-installer.php @@ -38,10 +38,10 @@ dbDelta($status_table_sql); $status_count = $wpdb->get_var("SELECT COUNT(*) FROM $lic_status_table"); if ($status_count == 0) { $default_statuses = array( - array('status_key' => 'pending', 'status_label' => __('Pending', 'slmplus')), - array('status_key' => 'active', 'status_label' => __('Active', 'slmplus')), - array('status_key' => 'blocked', 'status_label' => __('Blocked', 'slmplus')), - array('status_key' => 'expired', 'status_label' => __('Expired', 'slmplus')) + array('status_key' => 'pending', 'status_label' => __('Pending', 'slm-plus')), + array('status_key' => 'active', 'status_label' => __('Active', 'slm-plus')), + array('status_key' => 'blocked', 'status_label' => __('Blocked', 'slm-plus')), + array('status_key' => 'expired', 'status_label' => __('Expired', 'slm-plus')) ); foreach ($default_statuses as $status) { diff --git a/includes/slm-api-listener.php b/includes/slm-api-listener.php index c99680e..f765940 100755 --- a/includes/slm-api-listener.php +++ b/includes/slm-api-listener.php @@ -33,8 +33,10 @@ */ -class SLM_API_Listener{ - function __construct(){ +class SLM_API_Listener +{ + function __construct() + { if (isset($_REQUEST['slm_action']) && isset($_REQUEST['secret_key'])) { do_action('slm_api_listener_init'); $this->creation_api_listener(); @@ -46,32 +48,33 @@ class SLM_API_Listener{ } } - function creation_api_listener() { + function creation_api_listener() + { if (isset($_REQUEST['slm_action']) && trim($_REQUEST['slm_action']) === 'slm_create_new') { global $slm_debug_logger, $wpdb; $slm_lic_table = SLM_TBL_LICENSE_KEYS; $options = get_option('slm_plugin_options'); $lic_key_prefix = $options['lic_prefix'] ?? 'SLM-'; // Use default prefix if missing - + // Security check: Verify secret key SLM_API_Utility::verify_secret_key_for_creation(); - + // Logging for debugging $slm_debug_logger->log_debug("API - license creation (slm_create_new) request received."); - + // Trigger action hook for external integrations do_action('slm_api_listener_slm_create_new'); - + // Initialize fields array $fields = []; - + // License key handling if (!empty($_REQUEST['license_key'])) { $fields['license_key'] = sanitize_text_field($_REQUEST['license_key']); } else { $fields['license_key'] = slm_get_license($lic_key_prefix); // Generate if not provided } - + // Sanitize and prepare other fields $fields['lic_status'] = !empty($_REQUEST['lic_status']) ? sanitize_text_field($_REQUEST['lic_status']) : 'pending'; $fields['first_name'] = sanitize_text_field($_REQUEST['first_name']); @@ -92,7 +95,7 @@ class SLM_API_Listener{ $fields['lic_type'] = !empty($_REQUEST['lic_type']) ? sanitize_text_field($_REQUEST['lic_type']) : ''; $fields['slm_billing_length'] = !empty($_REQUEST['slm_billing_length']) ? sanitize_text_field($_REQUEST['slm_billing_length']) : ''; $fields['slm_billing_interval'] = !empty($_REQUEST['slm_billing_interval']) ? sanitize_text_field($_REQUEST['slm_billing_interval']) : ''; - + // Validation for subscription-type licenses if ($fields['lic_type'] === 'subscription') { if (empty($fields['slm_billing_length'])) { @@ -110,10 +113,10 @@ class SLM_API_Listener{ ]); } } - + // Insert the license into the database $result = $wpdb->insert($slm_lic_table, $fields); - + // Error handling for database insertion if ($result === false) { SLM_API_Utility::output_api_response([ @@ -129,28 +132,29 @@ class SLM_API_Listener{ 'key' => $fields['license_key'], 'code' => SLM_Error_Codes::LICENSE_CREATED ]; - + // Log license creation SLM_Utility::create_log($fields['license_key'], 'slm_create_new'); - + // Output API response SLM_API_Utility::output_api_response($response_args); } } } - - function activation_api_listener() { + + function activation_api_listener() + { if (isset($_REQUEST['slm_action']) && trim($_REQUEST['slm_action']) === 'slm_activate') { global $slm_debug_logger, $wpdb; $sql_prep1 = ""; $options = get_option('slm_plugin_options'); - + // Verify secret key first for security SLM_API_Utility::verify_secret_key(); - + // Trigger action hook for external integrations do_action('slm_api_listener_slm_activate'); - + // Initialize fields $fields = []; $fields['lic_key'] = sanitize_text_field($_REQUEST['license_key']); @@ -158,12 +162,12 @@ class SLM_API_Listener{ $registered_devices = isset($_REQUEST['registered_devices']) ? sanitize_text_field($_REQUEST['registered_devices']) : ''; $item_reference = isset($_REQUEST['item_reference']) ? sanitize_text_field($_REQUEST['item_reference']) : ''; - + // Table names $slm_lic_table = SLM_TBL_LICENSE_KEYS; $reg_domain_table = SLM_TBL_LIC_DOMAIN; $reg_table_devices = SLM_TBL_LIC_DEVICES; - + // Check if multiple items need verification if (!empty($item_reference) && $options['slm_multiple_items'] == 1) { $sql_prep1 = $wpdb->prepare("SELECT * FROM $slm_lic_table WHERE license_key = %s AND item_reference = %s", $fields['lic_key'], $item_reference); @@ -176,30 +180,30 @@ class SLM_API_Listener{ SLM_Helper_Class::write_log('User ID (subscr_id): ' . $sql_prep1); - + if (!$retLic) { $args = ['result' => 'error', 'message' => 'Invalid license key, key was not found.', 'error_code' => SLM_Error_Codes::LICENSE_INVALID]; SLM_API_Utility::output_api_response($args); } - + // Check if the license is blocked or expired if ($retLic->lic_status === 'blocked') { do_action('slm_api_listener_slm_activate_key_blocked', $fields['lic_key']); $args = ['result' => 'error', 'message' => 'Your license key is blocked', 'error_code' => SLM_Error_Codes::LICENSE_BLOCKED]; SLM_API_Utility::output_api_response($args); } - + if ($retLic->lic_status === 'expired') { do_action('slm_api_listener_slm_activate_key_expired', $fields['lic_key']); $args = ['result' => 'error', 'message' => 'Your license key has expired', 'error_code' => SLM_Error_Codes::LICENSE_EXPIRED]; SLM_API_Utility::output_api_response($args); } - + // Handling registered domains if (!empty($registered_domain)) { $sql_prep2 = $wpdb->prepare("SELECT * FROM $reg_domain_table WHERE lic_key = %s", $fields['lic_key']); $reg_domains = $wpdb->get_results($sql_prep2, OBJECT); - + if (count($reg_domains) < intval($retLic->max_allowed_domains)) { foreach ($reg_domains as $reg_domain) { @@ -233,19 +237,19 @@ class SLM_API_Listener{ // Insert into the registered domain table $wpdb->insert($reg_domain_table, $fields); - + // Update license status to active $current_date = wp_date('Y-m-d'); $wpdb->update($slm_lic_table, ['lic_status' => 'active', 'date_activated' => $current_date], ['id' => $retLic->id]); //SLM_Helper_Class::write_log('LOG: ' . $url); - + // Send activation email $lic_email = SLM_Utility::slm_get_lic_email($fields['lic_key']); $subject = 'Your license key was activated'; $message = 'Your license key: ' . $fields['lic_key'] . ' was activated successfully on ' . wp_date("F j, Y, g:i a") . '.'; SLM_Utility::slm_send_mail($lic_email, $subject, $message, 'success'); - + // Return success response $args = [ 'result' => 'success', @@ -257,25 +261,22 @@ class SLM_API_Listener{ ]; SLM_Utility::create_log($fields['lic_key'], 'License key activated for domain ' . $registered_domain); SLM_API_Utility::output_api_response($args); - - } - - else { + } else { $args = [ - 'result' => 'error', - 'message' => 'Reached maximum allowable domains', + 'result' => 'error', + 'message' => 'Reached maximum allowable domains', 'error_code' => SLM_Error_Codes::REACHED_MAX_DOMAINS ]; SLM_Utility::create_log($fields['lic_key'], 'Reached maximum allowable domains'); SLM_API_Utility::output_api_response($args); } } - + // Handling registered devices if (!empty($registered_devices)) { $sql_prep3 = $wpdb->prepare("SELECT * FROM $reg_table_devices WHERE lic_key = %s", $fields['lic_key']); $reg_devices = $wpdb->get_results($sql_prep3, OBJECT); - + if (count($reg_devices) < intval($retLic->max_allowed_devices)) { foreach ($reg_devices as $reg_device) { if (!empty($_REQUEST['migrate_from']) && $reg_device->registered_devices === sanitize_text_field($_REQUEST['migrate_from'])) { @@ -294,7 +295,7 @@ class SLM_API_Listener{ SLM_API_Utility::output_api_response($args); } } - + // Register new device // If the registered device is provided, add it to the fields $fields['registered_devices'] = $registered_devices; @@ -304,17 +305,17 @@ class SLM_API_Listener{ // Insert into the registered device table $wpdb->insert($reg_table_devices, $fields); - + // Update license status $current_date = wp_date('Y-m-d'); $wpdb->update($slm_lic_table, ['lic_status' => 'active', 'date_activated' => $current_date], ['id' => $retLic->id]); - + // Send activation email $lic_email = SLM_Utility::slm_get_lic_email($fields['lic_key']); $subject = 'Your license key was activated'; $message = 'Your license key: ' . $fields['lic_key'] . ' was activated successfully on ' . wp_date("F j, Y, g:i a") . '.'; SLM_Utility::slm_send_mail($lic_email, $subject, $message, 'success'); - + // Return success response $args = [ 'result' => 'success', @@ -325,9 +326,7 @@ class SLM_API_Listener{ ]; SLM_Utility::create_log($fields['lic_key'], 'License key activated for device ' . $registered_devices); SLM_API_Utility::output_api_response($args); - } - - else { + } else { $args = [ 'result' => 'error', 'icon_url' => SLM_Utility::slm_get_icon_url('1x', 'f-remove.png'), @@ -340,32 +339,33 @@ class SLM_API_Listener{ } } } - - function deactivation_api_listener() { + + function deactivation_api_listener() + { if (isset($_REQUEST['slm_action']) && trim($_REQUEST['slm_action']) === 'slm_deactivate') { global $slm_debug_logger, $wpdb; - + // Verify the secret key for security SLM_API_Utility::verify_secret_key(); $slm_debug_logger->log_debug("API - license deactivation (slm_deactivate) request received."); - + // Trigger deactivation hook for other integrations do_action('slm_api_listener_slm_deactivate'); - + // Sanitize inputs $license_key = sanitize_text_field($_REQUEST['license_key']); $registered_domain = isset($_REQUEST['registered_domain']) ? sanitize_text_field($_REQUEST['registered_domain']) : ''; $registered_devices = isset($_REQUEST['registered_devices']) ? sanitize_text_field($_REQUEST['registered_devices']) : ''; - + // Handle domain deactivation if domain info is provided if (!empty($registered_domain)) { $registered_dom_table = SLM_TBL_LIC_DOMAIN; - + // Prepare SQL query for domain deactivation $sql_prep = $wpdb->prepare("DELETE FROM $registered_dom_table WHERE lic_key = %s AND registered_domain = %s", $license_key, $registered_domain); $delete = $wpdb->query($sql_prep); - + // Check result of the deletion query if ($delete === false) { $slm_debug_logger->log_debug("Error - failed to delete the registered domain from the database."); @@ -390,15 +390,15 @@ class SLM_API_Listener{ SLM_API_Utility::output_api_response($args); } } - + // Handle device deactivation if device info is provided if (!empty($registered_devices)) { $registered_device_table = SLM_TBL_LIC_DEVICES; - + // Prepare SQL query for device deactivation $sql_prep2 = $wpdb->prepare("DELETE FROM $registered_device_table WHERE lic_key = %s AND registered_devices = %s", $license_key, $registered_devices); $delete2 = $wpdb->query($sql_prep2); - + // Check result of the deletion query if ($delete2 === false) { $slm_debug_logger->log_debug("Error - failed to delete the registered device from the database."); @@ -423,7 +423,7 @@ class SLM_API_Listener{ SLM_API_Utility::output_api_response($args); } } - + // If neither domain nor device info is provided, return an error response if (empty($registered_domain) && empty($registered_devices)) { $args = ['result' => 'error', 'message' => 'No deactivation target specified. Either a domain or device must be provided.', 'error_code' => SLM_Error_Codes::DOMAIN_MISSING]; @@ -431,19 +431,19 @@ class SLM_API_Listener{ } } } - - - function update_api_listener() { + + function update_api_listener() + { if (isset($_REQUEST['slm_action']) && trim($_REQUEST['slm_action']) === 'slm_update') { global $slm_debug_logger, $wpdb; - + // Verify secret key for security SLM_API_Utility::verify_secret_key_for_creation(); $slm_debug_logger->log_debug("API - license update (slm_update) request received."); - + // Trigger update hook for integrations do_action('slm_api_listener_slm_update'); - + // Sanitize inputs and build the update fields array $fields = array( 'license_key' => sanitize_text_field($_REQUEST['license_key']), @@ -456,7 +456,7 @@ class SLM_API_Listener{ 'lic_status' => isset($_REQUEST['lic_status']) ? sanitize_text_field($_REQUEST['lic_status']) : 'active', 'item_reference' => isset($_REQUEST['item_reference']) ? sanitize_text_field($_REQUEST['item_reference']) : '', ); - + // Validate that the license key is provided if (empty($fields['license_key'])) { $args = array( @@ -468,12 +468,12 @@ class SLM_API_Listener{ SLM_API_Utility::output_api_response($args); return; } - + // Update the license in the database $slm_lic_table = SLM_TBL_LICENSE_KEYS; $where_clause = array('license_key' => $fields['license_key']); $update_result = $wpdb->update($slm_lic_table, $fields, $where_clause); - + // Handle update result if ($update_result === false) { $args = array( @@ -504,41 +504,41 @@ class SLM_API_Listener{ SLM_API_Utility::output_api_response($args); } } - + function check_api_listener() { if (isset($_REQUEST['slm_action']) && trim($_REQUEST['slm_action']) === 'slm_check') { global $slm_debug_logger, $wpdb; - + // Verify secret key for security SLM_API_Utility::verify_secret_key(); - + $slm_debug_logger->log_debug("API - license check (slm_check) request received."); - + // Sanitize input $license_key = sanitize_text_field($_REQUEST['license_key']); $slm_debug_logger->log_debug("Checking license key: " . $license_key); - + // Action hook for additional integrations do_action('slm_api_listener_slm_check'); - + // Query license key details $slm_lic_table = SLM_TBL_LICENSE_KEYS; $reg_domain_table = SLM_TBL_LIC_DOMAIN; $reg_table_devices = SLM_TBL_LIC_DEVICES; - + // Retrieve the license key details from the database $license_query = $wpdb->prepare("SELECT * FROM $slm_lic_table WHERE license_key = %s", $license_key); $retLic = $wpdb->get_row($license_query, OBJECT); - + if ($retLic) { // If the license exists, retrieve domain and device information $domain_query = $wpdb->prepare("SELECT * FROM $reg_domain_table WHERE lic_key = %s", $license_key); $device_query = $wpdb->prepare("SELECT * FROM $reg_table_devices WHERE lic_key = %s", $license_key); - + $registered_domains = $wpdb->get_results($domain_query, OBJECT); $registered_devices = $wpdb->get_results($device_query, OBJECT); - + // Prepare response with license and registration data $response_args = apply_filters('slm_check_response_args', array( 'result' => 'success', @@ -565,11 +565,10 @@ class SLM_API_Listener{ 'until' => $retLic->until, 'current_ver' => $retLic->current_ver, )); - + // Log and send the response SLM_Utility::create_log($license_key, 'License check successful'); SLM_API_Utility::output_api_response($response_args); - } else { // Invalid license key case $error_args = array( @@ -577,7 +576,7 @@ class SLM_API_Listener{ 'message' => 'Invalid license key', 'error_code' => SLM_Error_Codes::LICENSE_INVALID ); - + // Log the error and respond SLM_Utility::create_log($license_key, 'License check failed: Invalid license key'); SLM_API_Utility::output_api_response($error_args); @@ -589,36 +588,36 @@ class SLM_API_Listener{ { if (isset($_REQUEST['slm_action']) && trim($_REQUEST['slm_action']) === 'slm_info') { global $slm_debug_logger, $wpdb; - + // Verify secret key for security - SLM_API_Utility::verify_secret_key(); - + SLM_API_Utility::verify_secret_key(); + // Log the API request $slm_debug_logger->log_debug("API - license info (slm_info) request received."); - + // Sanitize input data $license_key = sanitize_text_field($_REQUEST['license_key']); $slm_debug_logger->log_debug("License key: " . $license_key); - + // Action hook for additional integrations do_action('slm_api_listener_slm_info'); - + // Fetch license details from the database $slm_lic_table = SLM_TBL_LICENSE_KEYS; $reg_domain_table = SLM_TBL_LIC_DOMAIN; $reg_table_devices = SLM_TBL_LIC_DEVICES; - + $license_query = $wpdb->prepare("SELECT * FROM $slm_lic_table WHERE license_key = %s", $license_key); $retLic = $wpdb->get_row($license_query, OBJECT); - + if ($retLic) { // If the license exists, fetch associated domains and devices $domain_query = $wpdb->prepare("SELECT * FROM $reg_domain_table WHERE lic_key = %s", $license_key); $device_query = $wpdb->prepare("SELECT * FROM $reg_table_devices WHERE lic_key = %s", $license_key); - + $registered_domains = $wpdb->get_results($domain_query, OBJECT); $registered_devices = $wpdb->get_results($device_query, OBJECT); - + // Prepare the response with the license and registration data $response_args = apply_filters('slm_info_response_args', array( 'result' => 'success', @@ -643,7 +642,7 @@ class SLM_API_Listener{ 'until' => $retLic->until, 'current_ver' => $retLic->current_ver, )); - + // Log the successful check SLM_Utility::create_log($license_key, 'info: valid license key'); SLM_API_Utility::output_api_response($response_args); @@ -654,7 +653,7 @@ class SLM_API_Listener{ 'message' => 'Invalid license key', 'error_code' => SLM_Error_Codes::LICENSE_INVALID ); - + // Log the error SLM_Utility::create_log($license_key, 'info: invalid license key'); SLM_API_Utility::output_api_response($error_args); diff --git a/includes/slm-init-time-tasks.php b/includes/slm-init-time-tasks.php index 53ef443..6f64c1f 100755 --- a/includes/slm-init-time-tasks.php +++ b/includes/slm-init-time-tasks.php @@ -2,36 +2,37 @@ class SLM_Init_Time_Tasks { - public function __construct() { - $this->load_scripts(); - // Add other init time operations here - add_action('slm_daily_cron_event', array($this, 'slm_daily_cron_event_handler')); - } +public function __construct() { + $this->load_scripts(); + // Add other init time operations here + add_action('slm_daily_cron_event', array($this, 'slm_daily_cron_event_handler')); +} - // Load common and admin-specific scripts and styles - public function load_scripts() { - wp_enqueue_script('jquery'); // Common scripts +// Load common and admin-specific scripts and styles +public function load_scripts() { + $plugin_version = '1.0.0'; // Replace with your plugin version if available - if (is_admin()) { - wp_enqueue_script('jquery-ui-datepicker'); - wp_enqueue_script('wplm-custom-admin-js', SLM_ASSETS_URL . 'js/wplm-custom-admin.js', array('jquery-ui-dialog')); // Admin-only JS - if (isset($_GET['page']) && $_GET['page'] == 'slm_manage_license') { // Only include if in license management interface - wp_enqueue_style('jquery-ui-style', SLM_ASSETS_URL . 'css/jquery-ui.css'); - } + wp_enqueue_script('jquery'); // Common scripts + + if (is_admin()) { + wp_enqueue_script('jquery-ui-datepicker'); + // Enqueue admin-specific JS and add version and load in footer + wp_enqueue_script('wplm-custom-admin-js', SLM_ASSETS_URL . 'js/wplm-custom-admin.js', array('jquery-ui-dialog'), $plugin_version, true); // true loads in footer + if (isset($_GET['page']) && $_GET['page'] == 'slm_manage_license') { // Only include if in license management interface + wp_enqueue_style('jquery-ui-style', SLM_ASSETS_URL . 'css/jquery-ui.css', array(), $plugin_version); // Add version for caching } } - - // Daily cron event handler - public function slm_daily_cron_event_handler() { - $options = get_option('slm_plugin_options'); - do_action('slm_daily_cron_event_triggered'); - - if (isset($options['enable_auto_key_expiry']) && $options['enable_auto_key_expiry'] == '1') { - // Perform auto key expiry task - SLM_Debug_Logger::log_debug_st("SLM daily cronjob - auto expiry of license key is enabled."); - SLM_Utility::do_auto_key_expiry(); - } - - // Add any other daily cron job tasks here - } +} + +// Daily cron event handler +public function slm_daily_cron_event_handler() { + $options = get_option('slm_plugin_options'); + do_action('slm_daily_cron_event_triggered'); + + if (isset($options['enable_auto_key_expiry']) && $options['enable_auto_key_expiry'] == '1') { + // Perform auto key expiry task + SLM_Debug_Logger::log_debug_st("SLM daily cronjob - auto expiry of license key is enabled."); + SLM_Utility::do_auto_key_expiry(); + } +} } diff --git a/includes/slm-plugin-core.php b/includes/slm-plugin-core.php index 4e4239d..f5e5cb5 100755 --- a/includes/slm-plugin-core.php +++ b/includes/slm-plugin-core.php @@ -8,7 +8,7 @@ * @link http://epikly.com */ - + //Includes - utilities and cron jobs include_once(ABSPATH . 'wp-admin/includes/plugin.php'); require_once(SLM_LIB . 'slm-utility.php'); @@ -27,7 +27,8 @@ if (is_admin()) { } if (!function_exists('hyphenate')) { - function hyphenate($str) { + function hyphenate($str) + { return implode("-", str_split($str, 5)); } } @@ -35,31 +36,78 @@ if (!function_exists('hyphenate')) { // WP eStores integration if (SLM_Helper_Class::slm_get_option('slm_wpestores') == 1) { - require_once(SLM_ADMIN . 'includes/wpestores/slm-wpestores.php'); + // require_once(SLM_ADMIN . 'includes/wpestores/slm-wpestores.php'); } // Activation and deactivation hooks -function activate_slm_plus() { +function activate_slm_plus() +{ require_once SLM_LIB . 'class-slm-activator.php'; $slm_activator->activate(); } -function deactivate_slm_plus() { +function deactivate_slm_plus() +{ require_once SLM_LIB . 'class-slm-deactivator.php'; $slm_deactivator->deactivate(); } -function slm_get_license($lic_key_prefix = '') -{ - return strtoupper($lic_key_prefix . hyphenate(md5(uniqid(rand(4, 10), true) . date('Y-m-d H:i:s') . time()))); -} - register_activation_hook(__FILE__, 'activate_slm_plus'); register_deactivation_hook(__FILE__, 'deactivate_slm_plus'); -// License key generator function -function slmplus_get_license($lic_key_prefix = '') { - return strtoupper($lic_key_prefix . hyphenate(md5(uniqid(rand(4, 10), true) . date('Y-m-d H:i:s') . time()))); +// Improved and Shortened License Key Generator Function +function slm_get_license($lic_key_prefix = '') +{ + global $wpdb; + $max_retries = 5; // Set the maximum number of retries + $retry_count = 0; + $license_key = ''; + + // Use the constant to define the license table + $license_table = SLM_TBL_LICENSE_KEYS; + + // Generate a unique license key + while ($retry_count < $max_retries) { + // Generate a strong, random base using random_int() and uniqid + $random_base = uniqid(random_int(1000, 9999), true); + + // Combine random base with the current GMT date and time and the Unix timestamp for additional uniqueness + $combined_string = $random_base . gmdate('Y-m-d H:i:s') . time(); + + // Create a sha256 hash of the combined string + $hashed_string = substr(hash('sha256', $combined_string), 0, 32); // Take first 32 characters of the sha256 hash + + // Ensure the prefix is added correctly + $license_key = strtoupper($hashed_string); + + // Add dashes every 4 characters + $license_key_with_dashes = implode('-', str_split($license_key, 4)); + + // Add the prefix to the formatted key + $license_key_with_prefix = $lic_key_prefix . $license_key_with_dashes; + + // Check if the generated license key already exists in the database + $existing_license = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $license_table WHERE license_key = %s", $license_key_with_prefix)); + + // If the license doesn't exist, break out of the loop and return the key + if ($existing_license == 0) { + return $license_key_with_prefix; + } + + // If the license already exists, increment the retry count and try again + $retry_count++; + } + + // If we exceed the retry limit, return false or handle the error as needed + error_log('Failed to generate a unique license key after ' . $max_retries . ' attempts.'); + return false; +} + + +// Example hyphenate function (assuming hyphenates every 4 characters) +function hyphenate($string) +{ + return implode('-', str_split($string, 4)); // This splits the string into chunks of 4 characters and adds hyphens } // Action hooks @@ -75,13 +123,15 @@ add_action('plugins_loaded', array('SLM_Tabbed_Plugin', 'get_object')); $slm_debug_logger = new SLM_Debug_Logger(); // Init-time tasks -function slmplus_init_handler() { +function slmplus_init_handler() +{ $init_task = new SLM_Init_Time_Tasks(); $api_listener = new SLM_API_Listener(); } // Plugins loaded tasks -function slmplus_plugins_loaded_handler() { +function slmplus_plugins_loaded_handler() +{ if (is_admin() && get_option('slm_db_version') != SLM_DB_VERSION) { require_once(SLM_LIB . 'class-slm-installer.php'); // TODO - Implement DB update logic here @@ -89,10 +139,12 @@ function slmplus_plugins_loaded_handler() { } // Singleton pattern for the plugin -class SLM_Tabbed_Plugin { +class SLM_Tabbed_Plugin +{ private static $classobj = NULL; - public static function get_object() { + public static function get_object() + { if (self::$classobj === NULL) { self::$classobj = new self(); } @@ -103,7 +155,8 @@ class SLM_Tabbed_Plugin { } // AJAX handlers -function slmplus_del_registered_domain() { +function slmplus_del_registered_domain() +{ global $wpdb; $id = strip_tags($_GET['id']); $ret = $wpdb->query($wpdb->prepare("DELETE FROM " . SLM_TBL_LIC_DOMAIN . " WHERE id = %d", $id)); @@ -111,7 +164,8 @@ function slmplus_del_registered_domain() { exit; } -function slmplus_del_registered_devices() { +function slmplus_del_registered_devices() +{ global $wpdb; $id = strip_tags($_GET['id']); $ret = $wpdb->query($wpdb->prepare("DELETE FROM " . SLM_TBL_LIC_DEVICES . " WHERE id = %d", $id)); @@ -119,7 +173,8 @@ function slmplus_del_registered_devices() { exit; } -function slmplus_remove_activation() { +function slmplus_remove_activation() +{ global $wpdb; $id = strip_tags($_GET['id']); $activation_type = strip_tags($_GET['activation_type']); @@ -131,13 +186,15 @@ function slmplus_remove_activation() { } // Debugging functions -function wc_print_pretty($args) { +function wc_print_pretty($args) +{ echo '
    ';
         print_r($args);
         echo '
    '; } -function wc_log($msg) { +function wc_log($msg) +{ $log = ABSPATH . DIRECTORY_SEPARATOR . 'slm_log.txt'; file_put_contents($log, $msg . '', FILE_APPEND); } @@ -148,7 +205,7 @@ if (SLM_Helper_Class::slm_get_option('slm_woo') == 1 && is_plugin_active('woocom require_once(SLM_WOO . 'includes/slm-meta-boxes.php'); require_once SLM_WOO . 'includes/register-template.php'; - require_once SLM_WOO . 'includes/purchase.php'; + require_once SLM_WOO . 'includes/purchase.php'; require_once SLM_WOO . 'includes/create-license-orders.php'; // Build WooCommerce tabs @@ -156,40 +213,43 @@ if (SLM_Helper_Class::slm_get_option('slm_woo') == 1 && is_plugin_active('woocom } add_action('wp_ajax_slm_user_search', 'slm_user_search'); -function slm_user_search() { +function slm_user_search() +{ + global $wpdb; + $value = sanitize_text_field($_POST['value']); - - // Meta query to search for user data - $meta_query = [ - 'relation' => 'OR', - ['key' => 'first_name', 'value' => $value, 'compare' => 'LIKE'], - ['key' => 'last_name', 'value' => $value, 'compare' => 'LIKE'], - ['key' => 'billing_first_name', 'value' => $value, 'compare' => 'LIKE'], - ['key' => 'billing_last_name', 'value' => $value, 'compare' => 'LIKE'], - ]; - // Arguments to find users - $args = [ - 'meta_query' => $meta_query, - 'number' => 10, - ]; + // Direct SQL Query to improve performance + $query = $wpdb->prepare( + " + SELECT u.ID, u.display_name, u.user_email, + IFNULL(um_first_name.meta_value, um_billing_first_name.meta_value) AS first_name, + IFNULL(um_last_name.meta_value, um_billing_last_name.meta_value) AS last_name + FROM {$wpdb->users} u + LEFT JOIN {$wpdb->prefix}usermeta um_first_name ON um_first_name.user_id = u.ID AND um_first_name.meta_key = 'first_name' + LEFT JOIN {$wpdb->prefix}usermeta um_last_name ON um_last_name.user_id = u.ID AND um_last_name.meta_key = 'last_name' + LEFT JOIN {$wpdb->prefix}usermeta um_billing_first_name ON um_billing_first_name.user_id = u.ID AND um_billing_first_name.meta_key = 'billing_first_name' + LEFT JOIN {$wpdb->prefix}usermeta um_billing_last_name ON um_billing_last_name.user_id = u.ID AND um_billing_last_name.meta_key = 'billing_last_name' + WHERE (um_first_name.meta_value LIKE %s OR um_last_name.meta_value LIKE %s OR um_billing_first_name.meta_value LIKE %s OR um_billing_last_name.meta_value LIKE %s) + LIMIT 10 + ", + '%' . $wpdb->esc_like($value) . '%', + '%' . $wpdb->esc_like($value) . '%', + '%' . $wpdb->esc_like($value) . '%', + '%' . $wpdb->esc_like($value) . '%' + ); - $users = get_users($args); + $users = $wpdb->get_results($query); $results = []; foreach ($users as $user) { - // Fallback to billing info if WooCommerce is active - $first_name = get_user_meta($user->ID, 'first_name', true) ?: get_user_meta($user->ID, 'billing_first_name', true); - $last_name = get_user_meta($user->ID, 'last_name', true) ?: get_user_meta($user->ID, 'billing_last_name', true); - $company_name = get_user_meta($user->ID, 'company_name', true); // Retrieve company name if available - $results[] = [ 'ID' => $user->ID, - 'display_name' => $user->display_name ?: "{$first_name} {$last_name}", - 'first_name' => $first_name, - 'last_name' => $last_name, + 'display_name' => $user->display_name ?: "{$user->first_name} {$user->last_name}", + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, 'email' => $user->user_email, - 'company_name' => $company_name, + 'company_name' => get_user_meta($user->ID, 'company_name', true), 'subscr_id' => $user->ID, // Pass user ID as the subscription ID ]; } diff --git a/includes/slm-utility.php b/includes/slm-utility.php index e96fe46..9ed555d 100755 --- a/includes/slm-utility.php +++ b/includes/slm-utility.php @@ -38,7 +38,8 @@ class SLM_Helper_Class } } } - public static function get_license_logs($license_key) { + public static function get_license_logs($license_key) + { global $wpdb; $table_name = SLM_TBL_LIC_LOG; @@ -63,7 +64,7 @@ class SLM_Helper_Class $output = implode(',', $output); // print the result into the JavaScript console - echo ""; + echo ""; } } @@ -99,7 +100,8 @@ class SLM_API_Utility * Validate date format to ensure it's in 'YYYY-MM-DD' format. * Returns the sanitized date or an empty string if invalid. */ - public static function slm_validate_date($date) { + public static function slm_validate_date($date) + { $date = sanitize_text_field($date); $timestamp = strtotime($date); if ($timestamp && date('Y-m-d', $timestamp) === $date) { @@ -110,39 +112,65 @@ class SLM_API_Utility public static function verify_secret_key() { + // Get the stored secret key from plugin options $slm_options = get_option('slm_plugin_options'); $right_secret_key = $slm_options['lic_verification_secret'] ?? ''; + + // Sanitize and retrieve the received secret key $received_secret_key = sanitize_text_field($_REQUEST['secret_key'] ?? ''); + // Case-sensitive comparison for the secret keys if ($received_secret_key !== $right_secret_key) { + // Prepare the error response with case-sensitivity note $args = array( 'result' => 'error', - 'message' => 'Verification API secret key is invalid', + 'message' => 'Verification API secret key is invalid. Note: The key comparison is case-sensitive.', 'error_code' => SLM_Error_Codes::VERIFY_KEY_INVALID ); + // Output the API response with the error self::output_api_response($args); } } + public static function get_slm_option($option) { - $slm_options_func = get_option('slm_plugin_options', []); - $option = $slm_options_func[$option]; - return sanitize_text_field($option); + // Retrieve the option value from the database + $slm_options_func = get_option('slm_plugin_options', []); + + // Check if the option exists; if not, return an empty string + if (!isset($slm_options_func[$option])) { + return ''; + } + + // Get the option value and unslash it (removes slashes from the option value) + $option_value = wp_unslash($slm_options_func[$option]); + + // Sanitize the option value (text field sanitization) + $sanitized_option = sanitize_text_field($option_value); + + // Return the sanitized and unslashed option value + return $sanitized_option; } public static function verify_secret_key_for_creation() { + // Get the stored secret key from plugin options $slm_options = get_option('slm_plugin_options'); $right_secret_key = $slm_options['lic_creation_secret'] ?? ''; + + // Sanitize and retrieve the received secret key $received_secret_key = sanitize_text_field($_REQUEST['secret_key'] ?? ''); + // Case-sensitive comparison for the secret keys if ($received_secret_key !== $right_secret_key) { + // Prepare the error response with case-sensitivity note $args = array( 'result' => 'error', - 'message' => 'License Creation API secret key is invalid', + 'message' => 'Invalid License Creation API Secret Key provided. Note: The key comparison is case-sensitive.', 'error_code' => SLM_Error_Codes::CREATE_KEY_INVALID ); + // Output the API response with the error self::output_api_response($args); } } @@ -160,6 +188,88 @@ class SLM_API_Utility class SLM_Utility { + /** + * Saves a backup of the plugin's database tables in a secure folder. + */ + public static function slm_save_backup_to_uploads() + { + global $wpdb; + + // Get the upload directory + $upload_dir = wp_upload_dir(); + $unique_hash = slm_get_unique_hash(); // Generate or retrieve the unique hash + $slm_backup_dir = $upload_dir['basedir'] . $unique_hash; + + // Create the slm-plus folder with hash if it doesn't exist + if (!file_exists($slm_backup_dir)) { + wp_mkdir_p($slm_backup_dir); + } + + // Set backup file name and path + $backup_file = $slm_backup_dir . '/slm_plugin_backup_' . gmdate('Y-m-d H:i:s') . '.sql'; + + // Get plugin tables + $backup_tables = [ + SLM_TBL_LICENSE_KEYS, + SLM_TBL_LIC_DOMAIN, + SLM_TBL_LIC_DEVICES, + SLM_TBL_LIC_LOG, + SLM_TBL_EMAILS, + SLM_TBL_LICENSE_STATUS + ]; + + $sql = ""; + foreach ($backup_tables as $table) { + // Get table structure + $create_table_query = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N); + $sql .= "\n\n" . $create_table_query[0][1] . ";\n\n"; + + // Get table data + $rows = $wpdb->get_results("SELECT * FROM $table", ARRAY_A); + foreach ($rows as $row) { + $values = array_map('esc_sql', array_values($row)); // Use esc_sql to escape the values + $values = "'" . implode("','", $values) . "'"; + $sql .= "INSERT INTO $table VALUES ($values);\n"; + } + } + + // Include the WordPress Filesystem API + if (! function_exists('request_filesystem_credentials')) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + } + + // Ensure the filesystem is ready + if (! WP_Filesystem()) { + request_filesystem_credentials(admin_url()); + } + + global $wp_filesystem; + + // Define the backup file path + $backup_path = $upload_dir['basedir'] . '/' . $unique_hash . '/' . basename($backup_file); + + // Create the backup directory if it doesn't exist + if (! is_dir(dirname($backup_path))) { + $wp_filesystem->mkdir(dirname($backup_path)); + } + + // Save the SQL to the backup file using the WP Filesystem + if ($wp_filesystem->put_contents($backup_path, $sql)) { + $backup_url = $upload_dir['baseurl'] . '/' . $unique_hash . '/' . basename($backup_file); + + // Save backup info in plugin options + $backup_info = [ + 'url' => $backup_url, + 'date' => gmdate('Y-m-d H:i:s'), + ]; + slm_update_option('slm_last_backup_info', $backup_info); + + echo '

    ' . esc_html__('Backup created successfully! Download from: ', 'slm-plus') . '' . esc_html(basename($backup_file)) . '

    '; + } else { + echo '

    ' . esc_html__('Error: Failed to create the backup file.', 'slm-plus') . '

    '; + } + } + // Function to export a single license as a JSON file public static function export_license_to_json($license_id_or_key) { @@ -211,57 +321,58 @@ class SLM_Utility return false; // Return false if no data was found } - public static function check_for_expired_lic($lic_key = '') { + public static function check_for_expired_lic($lic_key = '') + { global $wpdb; - + // Set up email headers and subject line $headers = array('Content-Type: text/html; charset=UTF-8'); $subject = get_bloginfo('name') . ' - Your license has expired'; $expiration_reminder_text = SLM_Helper_Class::slm_get_option('expiration_reminder_text'); $expired_licenses_list = []; $reinstated_licenses_list = []; - + // Query licenses marked as expired but with future expiration dates to correct their status $incorrectly_expired_query = $wpdb->prepare( "SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE lic_status = %s AND date_expiry > NOW()", 'expired' ); $incorrectly_expired_licenses = $wpdb->get_results($incorrectly_expired_query, ARRAY_A); - + // Reinstate incorrectly expired licenses foreach ($incorrectly_expired_licenses as $license) { $license_key = sanitize_text_field($license['license_key']); $id = intval($license['id']); - + // Update license status to 'active' $wpdb->update( SLM_TBL_LICENSE_KEYS, ['lic_status' => 'active'], ['id' => $id] ); - + self::create_log($license_key, 'status corrected to active'); $reinstated_licenses_list[] = $license_key; } - + // Log reinstated licenses if (!empty($reinstated_licenses_list)) { SLM_Helper_Class::write_log('Reinstated licenses set to active: ' . implode(', ', $reinstated_licenses_list)); } - + // Query expired licenses $expired_query = $wpdb->prepare( "SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE date_expiry < NOW() AND date_expiry != %s ORDER BY date_expiry ASC;", '00000000' ); $expired_licenses = $wpdb->get_results($expired_query, ARRAY_A); - + // Check if any expired licenses were found if (empty($expired_licenses)) { SLM_Helper_Class::write_log('No expired licenses found'); return []; // Return an empty array if no licenses found } - + // Process each expired license foreach ($expired_licenses as $license) { $id = intval($license['id']); @@ -270,18 +381,18 @@ class SLM_Utility // $last_name = sanitize_text_field($license['last_name']); $email = sanitize_email($license['email']); $date_expiry = sanitize_text_field($license['date_expiry']); - + // Include email template and generate the email body ob_start(); include SLM_LIB . 'mails/expired.php'; $body = ob_get_clean(); - + // Check if auto-expiration is enabled and update the license status if (SLM_Helper_Class::slm_get_option('enable_auto_key_expiration') == 1) { $update_data = ['lic_status' => 'expired']; $where_clause = ['id' => $id]; $wpdb->update(SLM_TBL_LICENSE_KEYS, $update_data, $where_clause); - + // Log and send expiration notification self::create_log($license_key, 'set to expired'); $email_result = self::slm_check_sent_emails($license_key, $email, $subject, $body, $headers); @@ -289,27 +400,28 @@ class SLM_Utility self::create_log($license_key, 'sent expiration email notification'); } } - + // Add license to the expired list $expired_licenses_list[] = $license_key; } - + // Log the total count of expired licenses SLM_Helper_Class::write_log('Expired licenses found and processed: ' . implode(', ', $expired_licenses_list)); - + return [ 'expired_licenses' => $expired_licenses_list, 'reinstated_licenses' => $reinstated_licenses_list ]; // Return both expired and reinstated licenses } - + // Define return codes for clarity const EMAIL_SENT_FIRST_TIME = '200'; const EMAIL_ALREADY_SENT = '400'; const EMAIL_SENT_RECORD_NOT_FOUND = '300'; - public static function slm_check_sent_emails($license_key, $email, $subject, $body, $headers) { + public static function slm_check_sent_emails($license_key, $email, $subject, $body, $headers) + { global $wpdb; // Check if an email has already been sent for this license key @@ -336,37 +448,38 @@ class SLM_Utility return self::EMAIL_SENT_RECORD_NOT_FOUND; } } - - public static function do_auto_key_expiry() { + + public static function do_auto_key_expiry() + { global $wpdb; $current_date = current_time('Y-m-d'); $slm_lic_table = SLM_TBL_LICENSE_KEYS; - + // Query for active (non-expired) licenses $licenses = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $slm_lic_table WHERE lic_status != %s", 'expired'), OBJECT ); - + // Log and return if no licenses are found if (empty($licenses)) { SLM_Debug_Logger::log_debug_st("do_auto_key_expiry() - No active license keys found."); return false; } - + $today_dt = new DateTime($current_date); - + foreach ($licenses as $license) { $license_key = sanitize_text_field($license->license_key); $expiry_date = sanitize_text_field($license->date_expiry); - + // Skip if expiration date is invalid or empty if (empty($expiry_date) || in_array($expiry_date, ['0000-00-00', '00000000'])) { SLM_Debug_Logger::log_debug_st("License key ($license_key) has no valid expiration date set. Skipping expiry check."); continue; } - + // Check if the license has expired $expire_dt = new DateTime($expiry_date); if ($today_dt > $expire_dt) { @@ -374,12 +487,12 @@ class SLM_Utility $data = ['lic_status' => 'expired']; $where = ['id' => intval($license->id)]; $updated = $wpdb->update($slm_lic_table, $data, $where); - + // Log the expiry and trigger action if successfully updated if ($updated) { SLM_Debug_Logger::log_debug_st("License key ($license_key) expired on $expiry_date. Status set to 'expired'."); do_action('slm_license_key_expired', $license->id); - + // Optional: Send expiry reminder email self::check_for_expired_lic($license_key); } else { @@ -387,10 +500,10 @@ class SLM_Utility } } } - + return true; } - + public static function get_user_info($by, $value) @@ -404,46 +517,42 @@ class SLM_Utility return $user; } - public static function get_days_remaining($date1) { + public static function get_days_remaining($date1) + { // Validate and sanitize the date input $date1 = sanitize_text_field($date1); - + // Retrieve the date format setting from WordPress settings $date_format = get_option('date_format'); - + try { // Create DateTime objects for future and current dates $future_date = new DateTime($date1); $current_date = new DateTime(); - + // Check if the future date is valid and in the future if ($future_date < $current_date) { - return __('0 days remaining', 'slmplus'); + return __('0 days remaining', 'slm-plus'); } - + // Calculate the difference in days $interval = $current_date->diff($future_date); $days_remaining = (int) $interval->days; - + // Format and return the result return sprintf( - __('%s days remaining until %s', 'slmplus'), + // Translators: %1$s is the number of days remaining, %2$s is the formatted future date + __('%1$s days remaining until %2$s', 'slm-plus'), $days_remaining, date_i18n($date_format, $future_date->getTimestamp()) ); - } catch (Exception $e) { // Return 0 days remaining if date parsing fails - return __('0 days remaining', 'slmplus'); + return __('0 days remaining', 'slm-plus'); } } - - - /* - * Deletes a license key from the licenses table - */ public static function delete_license_key_by_row_id($key_row_id) { global $wpdb; @@ -452,37 +561,133 @@ class SLM_Utility // Sanitize the input $key_row_id = intval($key_row_id); - // First delete the registered domains entry of this key (if any). - SLM_Utility::delete_registered_domains_of_key($key_row_id); + // Retrieve the license key associated with this row id + $license_key = $wpdb->get_var($wpdb->prepare("SELECT license_key FROM $license_table WHERE id = %d", $key_row_id)); - // Now, delete the key from the licenses table. + // Debug: Log the retrieved license key + SLM_Helper_Class::write_log("License key retrieved: " . $license_key); + + // First, delete the registered domains entry of this key (if any) + SLM_Utility::delete_registered_domains_of_key($key_row_id); + SLM_Helper_Class::write_log("Registered domains for key $license_key deleted."); + + // Now, delete the key from the licenses table $wpdb->delete($license_table, array('id' => $key_row_id)); + SLM_Helper_Class::write_log("License with row ID $key_row_id deleted from the license table."); + + if ($license_key) { + + // Query to get WooCommerce orders using a custom WP_Query with meta_query + $args = array( + 'post_type' => 'shop_order', + 'posts_per_page' => -1, + 'meta_query' => array( + 'relation' => 'OR', + array( + 'key' => 'License Key', // License Key meta field + 'value' => $license_key, + 'compare' => '=' + ), + array( + 'key' => '_slm_lic_key', // Fallback License Key meta field + 'value' => $license_key, + 'compare' => '=' + ) + ) + ); + + $order_query = new WP_Query($args); + + if ($order_query->have_posts()) { + while ($order_query->have_posts()) { + $order_query->the_post(); + $order_id = get_the_ID(); + + // Get order object + $order = wc_get_order($order_id); + + // Debugging: Log the order ID + SLM_Helper_Class::write_log("Processing order ID: " . $order_id); + + // Meta keys to be removed + $meta_keys = [ + 'License Key', + 'License Type', + 'Current Version', + 'Until Version', + 'Max Devices', + 'Max Domains' + ]; + + // Remove order-level metadata + foreach ($meta_keys as $meta_key) { + $meta_value = $order->get_meta($meta_key, true); // Retrieve the metadata value + if ($meta_value) { + SLM_Helper_Class::write_log("Found meta key $meta_key with value: $meta_value. Deleting..."); + $order->delete_meta_data($meta_key); // Remove meta data from the order + } + } + + // Add a note to the order + $note_content = sprintf(__('License key %s was deleted on %s', 'slm-plus'), $license_key, date_i18n('F j, Y')); + $order->add_order_note($note_content); + + // Process and reset license-related metadata from order items + foreach ($order->get_items() as $item_id => $item) { + // Remove item-level metadata for the specified keys + foreach ($meta_keys as $meta_key) { + $meta_value = $item->get_meta($meta_key, true); // Retrieve the metadata value + if ($meta_value) { + SLM_Helper_Class::write_log("Found meta key $meta_key in order item $item_id with value: $meta_value. Deleting..."); + $item->delete_meta_data($meta_key); // Remove meta data from the order item + } + } + + // Save the updated order item + $item->save(); + } + + // Save the updated order + $order->save(); + } + + wp_reset_postdata(); // Reset the post data after custom query + } else { + // Debugging: Log if no orders were found + SLM_Helper_Class::write_log("No orders found for the license key: " . $license_key); + } + } } + + + + /* * Retrieves the email associated with a license key */ - public static function slm_get_lic_email($license) { + public static function slm_get_lic_email($license) + { global $wpdb; $lic_key_table = SLM_TBL_LICENSE_KEYS; - + // Sanitize the input $license = sanitize_text_field($license); - + // Prepare and execute the query to fetch the email $email = $wpdb->get_var( $wpdb->prepare("SELECT email FROM $lic_key_table WHERE license_key = %s", $license) ); - + // Check if an email was found and is valid if ($email && is_email($email)) { return $email; } else { // Return a WP_Error if the email was not found or invalid - return new WP_Error('license_not_found', __('License key not found or invalid email.', 'slmplus')); + return new WP_Error('license_not_found', __('License key not found or invalid email.', 'slm-plus')); } } - + /* * Sends an email with the specified parameters @@ -568,7 +773,6 @@ class SLM_Utility font-family: "Open Sans", Helvetica, Arial, Sans-serif; } - ' . esc_html(get_bloginfo('name')) . ' @@ -738,36 +942,70 @@ class SLM_Utility } /* - * Deletes any registered domains info from the domain table for the given key's row id. - */ + * Deletes any registered domains and related entries for the given license key's row id. + */ static function delete_registered_domains_of_key($key_row_id) { global $slm_debug_logger; global $wpdb; + + // Table constants $reg_domain_table = SLM_TBL_LIC_DOMAIN; - $sql_prep = $wpdb->prepare("SELECT * FROM $reg_domain_table WHERE lic_key_id = %s", $key_row_id); - $reg_domains = $wpdb->get_results($sql_prep, OBJECT); - foreach ($reg_domains as $domain) { - $row_to_delete = $domain->id; - $wpdb->delete($reg_domain_table, array('id' => $row_to_delete)); - $slm_debug_logger->log_debug("Registered domain with row id (" . $row_to_delete . ") deleted."); + $device_table = SLM_TBL_LIC_DEVICES; + $log_table = SLM_TBL_LIC_LOG; + $email_table = SLM_TBL_EMAILS; + + // Retrieve the license key associated with this row id + $license_key = $wpdb->get_var($wpdb->prepare("SELECT license_key FROM " . SLM_TBL_LICENSE_KEYS . " WHERE id = %d", $key_row_id)); + + if ($license_key) { + // Step 1: Delete from registered domains table + $reg_domains = $wpdb->get_results($wpdb->prepare("SELECT id FROM $reg_domain_table WHERE lic_key_id = %d", $key_row_id)); + foreach ($reg_domains as $domain) { + $wpdb->delete($reg_domain_table, array('id' => $domain->id)); + $slm_debug_logger->log_debug("Registered domain with row id (" . $domain->id . ") deleted."); + } + + // Step 2: Delete from devices table + $deleted_devices = $wpdb->delete($device_table, array('lic_key' => $license_key), array('%s')); + $slm_debug_logger->log_debug("$deleted_devices entries deleted from devices table for license key ($license_key)."); + + // Step 3: Delete from log table + $deleted_logs = $wpdb->delete($log_table, array('license_key' => $license_key), array('%s')); + $slm_debug_logger->log_debug("$deleted_logs entries deleted from log table for license key ($license_key)."); + + // Step 4: Delete from emails table + $deleted_emails = $wpdb->delete($email_table, array('lic_key' => $license_key), array('%s')); + $slm_debug_logger->log_debug("$deleted_emails entries deleted from emails table for license key ($license_key)."); + } else { + $slm_debug_logger->log_debug("No license key found for row id ($key_row_id). Deletion aborted."); } } + static function create_secret_keys() { - $key = strtoupper(implode('-', str_split(substr(strtolower(md5(microtime() . rand(1000, 9999))), 0, 32), 8))); - return hash('sha256', $key); + // Generate secure random bytes (32 bytes = 256 bits) + $random_bytes = openssl_random_pseudo_bytes(32); // 32 bytes (256 bits) + + // Convert the random bytes into a hexadecimal string (64 chars) + $random_string = bin2hex($random_bytes); + + // Make the entire string uppercase + $key = strtoupper($random_string); + + return $key; } - public static function create_log($license_key, $action) { + public static function create_log($license_key, $action) + { global $wpdb; $slm_log_table = SLM_TBL_LIC_LOG; - + // Sanitize inputs $license_key = sanitize_text_field($license_key); $action = sanitize_text_field($action); - + // Determine the request origin if (!empty($_SERVER['HTTP_ORIGIN'])) { $origin = sanitize_text_field($_SERVER['HTTP_ORIGIN']); @@ -776,7 +1014,7 @@ class SLM_Utility } else { $origin = sanitize_text_field($_SERVER['REMOTE_ADDR']); } - + // Prepare log data $log_data = array( 'license_key' => $license_key, @@ -784,18 +1022,19 @@ class SLM_Utility 'time' => current_time('mysql'), // Standardized date-time format 'source' => $origin, ); - + // Insert log data into the database $inserted = $wpdb->insert($slm_log_table, $log_data); - + // Check for insertion errors if ($inserted === false) { error_log("Failed to insert log for license key: $license_key, action: $action. Error: " . $wpdb->last_error); } } - - public static function create_email_log($lic_key, $sent_to, $status, $sent, $date_sent = null) { + + public static function create_email_log($lic_key, $sent_to, $status, $sent, $date_sent = null) + { global $wpdb; $slm_email_table = SLM_TBL_EMAILS; @@ -835,10 +1074,11 @@ class SLM_Utility foreach ($result as $license) { echo '
    - - '; + + '; } } @@ -870,17 +1110,24 @@ class SLM_Utility if (isset($email) && isset($manage_subscriber) && current_user_can('edit_pages')) { - echo '

    Listing all licenses related to ' . $email . '

    '; + echo '

    Listing all licenses related to ' . esc_html($email) . '

    '; + + $result_array = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE email LIKE %s ORDER BY `email` DESC LIMIT 0,1000", + '%' . $wpdb->esc_like($email) . '%' + ), + ARRAY_A + ); - $result_array = $wpdb->get_results("SELECT * FROM " . SLM_TBL_LICENSE_KEYS . " WHERE email LIKE '%" . $email . "%' ORDER BY `email` DESC LIMIT 0,1000", ARRAY_A); foreach ($result_array as $slm_user) { echo ' - - - - - '; + + + + + '; } } } @@ -891,17 +1138,25 @@ class SLM_Utility $slm_log_table = SLM_TBL_LIC_LOG; echo ' -
    - ' . $license->first_name . ' ' . $license->last_name . '
    - ' . $license->license_key . '
    + ' . esc_html($license->first_name) . ' ' . esc_html($license->last_name) . '
    + ' . esc_html($license->license_key) . ' +
    ' . $slm_user["id"] . '' . $slm_user["license_key"] . '' . $slm_user["lic_status"] . ''. __(' view', 'slmplus'). '
    ' . esc_html($slm_user["id"]) . '' . esc_html($slm_user["license_key"]) . '' . esc_html($slm_user["lic_status"]) . '' . esc_html__('View', 'slm-plus') . '
    +
    +
    '. __('ID', 'slmplus'). ' '. __('Request', 'slmplus'). '
    + + + + + + + '; $activity = $wpdb->get_results("SELECT * FROM " . $slm_log_table . " WHERE license_key='" . $license_key . "';"); foreach ($activity as $log) { echo ' - ' . - '' . - ' - '; + ' . + '' . + ' + '; } echo ' @@ -913,7 +1168,7 @@ class SLM_Utility { ?>
    -
    +
    prepare("SELECT * FROM $tablename WHERE lic_key = %s", $license_key); @@ -921,22 +1176,22 @@ class SLM_Utility if (count($activations) > 0) : ?>
    -
    +
    ' . esc_html__('ID', 'slm-plus') . '' . esc_html__('Request', 'slm-plus') . '
    ' . $log->id . ' ' . $log->slm_action . '' . - '

    '. __('Source:', 'slmplus'). ' ' . $log->source . - '

    '. __('Time:', 'slmplus'). ' ' . $log->time . '

    ' . esc_html($log->id) . ' ' . esc_html($log->slm_action) . '' . + '

    ' . esc_html__('Source:', 'slm-plus') . ' ' . esc_html($log->source) . + '

    ' . esc_html__('Time:', 'slm-plus') . ' ' . esc_html($log->time) . '

    -
    +
    registered_devices . '" aria-label="' . $activation->registered_devices . '" aria-describedby="' . $activation->registered_devices . '" value="' . $activation->registered_devices . '" readonly>'; + echo ''; } else { - echo ''; + echo ''; } ?>
    - +
    @@ -946,7 +1201,7 @@ class SLM_Utility
    - '.__('Not registered yet', 'slmplus').'
    '; ?> + ' . esc_html__('Not registered yet', 'slm-plus') . '
    '; ?>
    is_type('slm_license')) { $tabs['shipping'] = array( - 'title' => __('License information', 'slmplus'), + 'title' => __('License information', 'slm-plus'), 'priority' => 50, 'callback' => 'slm_woo_tab_lic_info' ); @@ -976,11 +1231,11 @@ class SLM_Utility { global $product; // The new tab content - echo '

    '.__('License information', 'slmplus') .'

    '; - echo __('License type: ', 'slmplus') . get_post_meta($product->get_id(), '_license_type', true) . '
    '; - echo __('Domains allowed: ', 'slmplus') . get_post_meta($product->get_id(), '_domain_licenses', true) . '
    '; - echo __('Devices allowed: ', 'slmplus') . get_post_meta($product->get_id(), '_devices_licenses', true) . '
    '; - echo __('Renews every ', 'slmplus') . get_post_meta($product->get_id(), '_license_renewal_period_lenght', true) . ' ' . get_post_meta($product->get_id(), '_license_renewal_period_term', true) . '
    '; + echo '

    ' . esc_html__('License information', 'slm-plus') . '

    '; + echo esc_html__('License type: ', 'slm-plus') . esc_html(get_post_meta($product->get_id(), '_license_type', true)) . '
    '; + echo esc_html__('Domains allowed: ', 'slm-plus') . esc_html(get_post_meta($product->get_id(), '_domain_licenses', true)) . '
    '; + echo esc_html__('Devices allowed: ', 'slm-plus') . esc_html(get_post_meta($product->get_id(), '_devices_licenses', true)) . '
    '; + echo esc_html__('Renews every ', 'slm-plus') . esc_html(get_post_meta($product->get_id(), '_license_renewal_period_lenght', true)) . ' ' . esc_html(get_post_meta($product->get_id(), '_license_renewal_period_term', true)) . '
    '; } } } diff --git a/includes/wp-mail-class.php b/includes/wp-mail-class.php index de69f02..9b9b91c 100644 --- a/includes/wp-mail-class.php +++ b/includes/wp-mail-class.php @@ -208,14 +208,14 @@ class WP_Mail $this->attachments = array(); foreach ($path as $path_) { if (!file_exists($path_)) { - throw new Exception("Attachment not found at $path"); + throw new Exception(sprintf('Attachment not found at %s', esc_html($path))); } else { $this->attachments[] = $path_; } } } else { if (!file_exists($path)) { - throw new Exception("Attachment not found at $path"); + throw new Exception(sprintf('Attachment not found at %s', esc_html($path))); } $this->attachments = array($path); } @@ -358,7 +358,7 @@ class WP_Mail return $this->parseAsMustache($template, $variables); } else { - throw new Exception("Unknown extension {$extension} in path '{$templateFile}'"); + throw new Exception(sprintf('Unknown extension %s in path %s', esc_html($extension), esc_html($templateFile))); } } diff --git a/logs/log-cron-job.txt b/logs/log-cron-job.txt index 8b13789..1f2085b 100644 --- a/logs/log-cron-job.txt +++ b/logs/log-cron-job.txt @@ -1 +1 @@ - +[11/14/2024 3:53 PM] - -------- Log File Reset -------- diff --git a/logs/log.txt b/logs/log.txt index e69de29..b42ef7d 100644 --- a/logs/log.txt +++ b/logs/log.txt @@ -0,0 +1,361 @@ +[11/14/2024 3:53 PM] - -------- Log File Reset -------- +[11/14/2024 4:25 PM] - SUCCESS : Registered domain with row id (34) deleted. +[11/14/2024 4:54 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 4:54 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 4:55 PM] - SUCCESS : No license key found for row id (79). Deletion aborted. +[11/14/2024 4:56 PM] - SUCCESS : API Response - Result: success Message: License key activated. +[11/14/2024 4:56 PM] - SUCCESS : API Response - Result: success Message: License key activated for device. +[11/14/2024 4:57 PM] - SUCCESS : Registered domain with row id (35) deleted. +[11/14/2024 4:57 PM] - SUCCESS : 1 entries deleted from devices table for license key (SLM-EE57-76EF-2405-522E-90F4-FD95-1244-67C9). +[11/14/2024 4:57 PM] - SUCCESS : 3 entries deleted from log table for license key (SLM-EE57-76EF-2405-522E-90F4-FD95-1244-67C9). +[11/14/2024 4:57 PM] - SUCCESS : entries deleted from emails table for license key (SLM-EE57-76EF-2405-522E-90F4-FD95-1244-67C9). +[11/14/2024 4:58 PM] - SUCCESS : No license key found for row id (80). Deletion aborted. +[11/14/2024 8:36 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 8:36 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 8:36 PM] - SUCCESS : API Response - Result: success Message: License key activated for device. +[11/14/2024 8:36 PM] - SUCCESS : API Response - Result: success Message: License key activated. +[11/14/2024 8:37 PM] - SUCCESS : Registered domain with row id (36) deleted. +[11/14/2024 8:37 PM] - SUCCESS : 1 entries deleted from devices table for license key (SLM-5778-E08F-C6C1-A077-28AE-64C3-EC83-AF8B). +[11/14/2024 8:37 PM] - SUCCESS : 3 entries deleted from log table for license key (SLM-5778-E08F-C6C1-A077-28AE-64C3-EC83-AF8B). +[11/14/2024 8:37 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-5778-E08F-C6C1-A077-28AE-64C3-EC83-AF8B). +[11/14/2024 8:43 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 8:43 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 8:43 PM] - SUCCESS : No license key found for row id (81). Deletion aborted. +[11/14/2024 8:43 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-517E-526A-1BE3-B441-45C9-210E-6510-1216). +[11/14/2024 8:43 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-517E-526A-1BE3-B441-45C9-210E-6510-1216). +[11/14/2024 8:43 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-517E-526A-1BE3-B441-45C9-210E-6510-1216). +[11/14/2024 8:47 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 8:47 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 8:47 PM] - SUCCESS : No license key found for row id (82). Deletion aborted. +[11/14/2024 8:48 PM] - SUCCESS : No license key found for row id (82). Deletion aborted. +[11/14/2024 8:48 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-B92A-33AD-70DD-1A9C-380D-9DEE-9A1A-FECE). +[11/14/2024 8:48 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-B92A-33AD-70DD-1A9C-380D-9DEE-9A1A-FECE). +[11/14/2024 8:48 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-B92A-33AD-70DD-1A9C-380D-9DEE-9A1A-FECE). +[11/14/2024 8:48 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 8:48 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 8:49 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-EC44-E7FB-4A4F-B3AC-5043-DE79-5152-5C00). +[11/14/2024 8:49 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-EC44-E7FB-4A4F-B3AC-5043-DE79-5152-5C00). +[11/14/2024 8:49 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-EC44-E7FB-4A4F-B3AC-5043-DE79-5152-5C00). +[11/14/2024 8:52 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 8:52 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 8:57 PM] - SUCCESS : No license key found for row id (84). Deletion aborted. +[11/14/2024 8:57 PM] - SUCCESS : No license key found for row id (84). Deletion aborted. +[11/14/2024 8:57 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-BA9D-1485-9B26-FC09-A65D-7982-AF9A-85A0). +[11/14/2024 8:57 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-BA9D-1485-9B26-FC09-A65D-7982-AF9A-85A0). +[11/14/2024 8:57 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-BA9D-1485-9B26-FC09-A65D-7982-AF9A-85A0). +[11/14/2024 9:00 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:00 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:00 PM] - SUCCESS : No license key found for row id (85). Deletion aborted. +[11/14/2024 9:00 PM] - SUCCESS : No license key found for row id (85). Deletion aborted. +[11/14/2024 9:00 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-6605-9268-E33C-AD4A-9DB2-997C-BB20-7D7C). +[11/14/2024 9:00 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-6605-9268-E33C-AD4A-9DB2-997C-BB20-7D7C). +[11/14/2024 9:00 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-6605-9268-E33C-AD4A-9DB2-997C-BB20-7D7C). +[11/14/2024 9:07 PM] - SUCCESS : No license key found for row id (86). Deletion aborted. +[11/14/2024 9:08 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:08 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:09 PM] - SUCCESS : No license key found for row id (86). Deletion aborted. +[11/14/2024 9:09 PM] - SUCCESS : No license key found for row id (86). Deletion aborted. +[11/14/2024 9:13 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:13 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:15 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:15 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:16 PM] - SUCCESS : No license key found for row id (86). Deletion aborted. +[11/14/2024 9:16 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-BFD7-241E-790D-BF31-312D-96B0-EBDD-E19C). +[11/14/2024 9:16 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-BFD7-241E-790D-BF31-312D-96B0-EBDD-E19C). +[11/14/2024 9:16 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-BFD7-241E-790D-BF31-312D-96B0-EBDD-E19C). +[11/14/2024 9:16 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-8771-12E4-AB7C-1521-037F-3A91-D537-0F64). +[11/14/2024 9:16 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-8771-12E4-AB7C-1521-037F-3A91-D537-0F64). +[11/14/2024 9:16 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-8771-12E4-AB7C-1521-037F-3A91-D537-0F64). +[11/14/2024 9:16 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-84C6-93BE-3840-E581-12FC-AB2F-8ACC-1A0C). +[11/14/2024 9:16 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-84C6-93BE-3840-E581-12FC-AB2F-8ACC-1A0C). +[11/14/2024 9:16 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-84C6-93BE-3840-E581-12FC-AB2F-8ACC-1A0C). +[11/14/2024 9:16 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:16 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:17 PM] - SUCCESS : No license key found for row id (87). Deletion aborted. +[11/14/2024 9:19 PM] - SUCCESS : No license key found for row id (87). Deletion aborted. +[11/14/2024 9:21 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-4554-A7F9-4A30-9A6C-A9FB-2702-1384-0988). +[11/14/2024 9:21 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-4554-A7F9-4A30-9A6C-A9FB-2702-1384-0988). +[11/14/2024 9:21 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-4554-A7F9-4A30-9A6C-A9FB-2702-1384-0988). +[11/14/2024 9:22 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:22 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:30 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-CADC-9C52-0BDC-7429-F7A6-C58D-5AC7-1A2C). +[11/14/2024 9:30 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-CADC-9C52-0BDC-7429-F7A6-C58D-5AC7-1A2C). +[11/14/2024 9:30 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-CADC-9C52-0BDC-7429-F7A6-C58D-5AC7-1A2C). +[11/14/2024 9:31 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:31 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/14/2024 9:32 PM] - SUCCESS : No license key found for row id (91). Deletion aborted. +[11/14/2024 9:32 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-3BB9-9D7F-4F1F-DE50-FF7A-46E4-B81E-3FF0). +[11/14/2024 9:32 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-3BB9-9D7F-4F1F-DE50-FF7A-46E4-B81E-3FF0). +[11/14/2024 9:32 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-3BB9-9D7F-4F1F-DE50-FF7A-46E4-B81E-3FF0). +[11/14/2024 9:37 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/14/2024 9:37 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:10 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-D44E-1DE7-3F8E-29C2-67C2-69CD-CD8E-EEFA). +[11/15/2024 9:10 PM] - SUCCESS : 0 entries deleted from log table for license key (SLM-D44E-1DE7-3F8E-29C2-67C2-69CD-CD8E-EEFA). +[11/15/2024 9:10 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-D44E-1DE7-3F8E-29C2-67C2-69CD-CD8E-EEFA). +[11/15/2024 9:10 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-1155-CB30-585F-C72C-3F02-7BF0-9B9D-F705). +[11/15/2024 9:10 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-1155-CB30-585F-C72C-3F02-7BF0-9B9D-F705). +[11/15/2024 9:10 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-1155-CB30-585F-C72C-3F02-7BF0-9B9D-F705). +[11/15/2024 9:24 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:24 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:24 PM] - SUCCESS : No license key found for row id (93). Deletion aborted. +[11/15/2024 9:24 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-4401-2724-A27F-3E82-4654-0E83-738D-1641). +[11/15/2024 9:24 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-4401-2724-A27F-3E82-4654-0E83-738D-1641). +[11/15/2024 9:24 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-4401-2724-A27F-3E82-4654-0E83-738D-1641). +[11/15/2024 9:25 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:25 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:25 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-4504-4439-ECED-1884-8425-CE8B-5500-E2CD). +[11/15/2024 9:25 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-4504-4439-ECED-1884-8425-CE8B-5500-E2CD). +[11/15/2024 9:25 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-4504-4439-ECED-1884-8425-CE8B-5500-E2CD). +[11/15/2024 9:27 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:27 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:27 PM] - SUCCESS : No license key found for row id (96). Deletion aborted. +[11/15/2024 9:27 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-309E-344F-2809-F0B8-5687-1C23-92D5-CAC1). +[11/15/2024 9:27 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-309E-344F-2809-F0B8-5687-1C23-92D5-CAC1). +[11/15/2024 9:27 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-309E-344F-2809-F0B8-5687-1C23-92D5-CAC1). +[11/15/2024 9:28 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:28 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:28 PM] - SUCCESS : No license key found for row id (97). Deletion aborted. +[11/15/2024 9:28 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-D8C9-95A1-49DE-FDB7-0FD0-E1C1-7418-9044). +[11/15/2024 9:28 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-D8C9-95A1-49DE-FDB7-0FD0-E1C1-7418-9044). +[11/15/2024 9:28 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-D8C9-95A1-49DE-FDB7-0FD0-E1C1-7418-9044). +[11/15/2024 9:29 PM] - SUCCESS : No license key found for row id (98). Deletion aborted. +[11/15/2024 9:29 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:29 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:30 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:30 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:32 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:32 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:32 PM] - SUCCESS : No license key found for row id (98). Deletion aborted. +[11/15/2024 9:32 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-7105-479C-85D4-56A7-3A08-AD0A-2723-3C36). +[11/15/2024 9:32 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-7105-479C-85D4-56A7-3A08-AD0A-2723-3C36). +[11/15/2024 9:32 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-7105-479C-85D4-56A7-3A08-AD0A-2723-3C36). +[11/15/2024 9:32 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-C7A8-30C6-2A87-D6C0-7D5A-EC8A-9562-02CF). +[11/15/2024 9:32 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-C7A8-30C6-2A87-D6C0-7D5A-EC8A-9562-02CF). +[11/15/2024 9:32 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-C7A8-30C6-2A87-D6C0-7D5A-EC8A-9562-02CF). +[11/15/2024 9:32 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-6988-E35E-574D-5263-B449-E53E-3D9C-BCBC). +[11/15/2024 9:32 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-6988-E35E-574D-5263-B449-E53E-3D9C-BCBC). +[11/15/2024 9:32 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-6988-E35E-574D-5263-B449-E53E-3D9C-BCBC). +[11/15/2024 9:33 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/15/2024 9:33 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/15/2024 9:33 PM] - SUCCESS : No license key found for row id (99). Deletion aborted. +[11/15/2024 9:33 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-E724-EC26-610E-EB10-D4B4-6BA1-FB1B-886D). +[11/15/2024 9:33 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-E724-EC26-610E-EB10-D4B4-6BA1-FB1B-886D). +[11/15/2024 9:33 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-E724-EC26-610E-EB10-D4B4-6BA1-FB1B-886D). +[11/16/2024 12:42 PM] - SUCCESS : No license key found for row id (102). Deletion aborted. +[11/16/2024 12:42 PM] - SUCCESS : No license key found for row id (102). Deletion aborted. +[11/16/2024 12:43 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:43 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:43 PM] - SUCCESS : No license key found for row id (102). Deletion aborted. +[11/16/2024 12:43 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-85A2-0795-DFC0-9E8E-414A-72C5-D8FC-5805). +[11/16/2024 12:43 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-85A2-0795-DFC0-9E8E-414A-72C5-D8FC-5805). +[11/16/2024 12:43 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-85A2-0795-DFC0-9E8E-414A-72C5-D8FC-5805). +[11/16/2024 12:44 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:44 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:44 PM] - SUCCESS : No license key found for row id (103). Deletion aborted. +[11/16/2024 12:44 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-E592-0B4C-C5CC-0444-565B-AE5B-9ECC-09E0). +[11/16/2024 12:44 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-E592-0B4C-C5CC-0444-565B-AE5B-9ECC-09E0). +[11/16/2024 12:44 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-E592-0B4C-C5CC-0444-565B-AE5B-9ECC-09E0). +[11/16/2024 12:45 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:45 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:45 PM] - SUCCESS : No license key found for row id (104). Deletion aborted. +[11/16/2024 12:45 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-7B4A-7FD5-05C4-69C4-8994-256D-DBE9-EDBA). +[11/16/2024 12:45 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-7B4A-7FD5-05C4-69C4-8994-256D-DBE9-EDBA). +[11/16/2024 12:45 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-7B4A-7FD5-05C4-69C4-8994-256D-DBE9-EDBA). +[11/16/2024 12:46 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:46 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:46 PM] - SUCCESS : No license key found for row id (105). Deletion aborted. +[11/16/2024 12:46 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-04CF-8A76-721C-CFF9-A998-D0C3-1B7C-2F5B). +[11/16/2024 12:46 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-04CF-8A76-721C-CFF9-A998-D0C3-1B7C-2F5B). +[11/16/2024 12:46 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-04CF-8A76-721C-CFF9-A998-D0C3-1B7C-2F5B). +[11/16/2024 12:47 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:47 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:47 PM] - SUCCESS : No license key found for row id (106). Deletion aborted. +[11/16/2024 12:47 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-E699-C8A8-761E-8E1A-860D-FB63-A4E9-1871). +[11/16/2024 12:47 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-E699-C8A8-761E-8E1A-860D-FB63-A4E9-1871). +[11/16/2024 12:47 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-E699-C8A8-761E-8E1A-860D-FB63-A4E9-1871). +[11/16/2024 12:48 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:48 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:48 PM] - SUCCESS : No license key found for row id (107). Deletion aborted. +[11/16/2024 12:48 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-9990-C635-DD8D-C077-092B-8B2F-2C80-19C0). +[11/16/2024 12:48 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-9990-C635-DD8D-C077-092B-8B2F-2C80-19C0). +[11/16/2024 12:48 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-9990-C635-DD8D-C077-092B-8B2F-2C80-19C0). +[11/16/2024 12:51 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:51 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:51 PM] - SUCCESS : No license key found for row id (108). Deletion aborted. +[11/16/2024 12:51 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-3AC5-D1F8-C29A-D502-F744-D6A2-2978-9F27). +[11/16/2024 12:51 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-3AC5-D1F8-C29A-D502-F744-D6A2-2978-9F27). +[11/16/2024 12:51 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-3AC5-D1F8-C29A-D502-F744-D6A2-2978-9F27). +[11/16/2024 12:56 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:56 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:56 PM] - SUCCESS : No license key found for row id (109). Deletion aborted. +[11/16/2024 12:56 PM] - SUCCESS : No license key found for row id (109). Deletion aborted. +[11/16/2024 12:56 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-2440-E86B-D53C-EA9C-05F1-DC1F-8AB0-99DD). +[11/16/2024 12:56 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-2440-E86B-D53C-EA9C-05F1-DC1F-8AB0-99DD). +[11/16/2024 12:56 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-2440-E86B-D53C-EA9C-05F1-DC1F-8AB0-99DD). +[11/16/2024 12:57 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:57 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:57 PM] - SUCCESS : No license key found for row id (110). Deletion aborted. +[11/16/2024 12:57 PM] - SUCCESS : No license key found for row id (110). Deletion aborted. +[11/16/2024 12:57 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-6530-1BB5-9EFB-499B-0E2F-5E30-1D91-CA84). +[11/16/2024 12:57 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-6530-1BB5-9EFB-499B-0E2F-5E30-1D91-CA84). +[11/16/2024 12:57 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-6530-1BB5-9EFB-499B-0E2F-5E30-1D91-CA84). +[11/16/2024 12:59 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 12:59 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 12:59 PM] - SUCCESS : No license key found for row id (111). Deletion aborted. +[11/16/2024 12:59 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-7E96-7D67-6081-002F-970F-3B4D-E0D4-D241). +[11/16/2024 12:59 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-7E96-7D67-6081-002F-970F-3B4D-E0D4-D241). +[11/16/2024 12:59 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-7E96-7D67-6081-002F-970F-3B4D-E0D4-D241). +[11/16/2024 1:00 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 1:00 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 1:00 PM] - SUCCESS : No license key found for row id (112). Deletion aborted. +[11/16/2024 1:00 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-A3A7-9E51-FE88-B3CF-2D32-03F9-754A-0C52). +[11/16/2024 1:00 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-A3A7-9E51-FE88-B3CF-2D32-03F9-754A-0C52). +[11/16/2024 1:00 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-A3A7-9E51-FE88-B3CF-2D32-03F9-754A-0C52). +[11/16/2024 1:12 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 1:12 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 1:23 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 1:23 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 1:23 PM] - SUCCESS : No license key found for row id (113). Deletion aborted. +[11/16/2024 1:23 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-0334-18CC-D8D3-4934-0BE8-3CDE-5027-8650). +[11/16/2024 1:23 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-0334-18CC-D8D3-4934-0BE8-3CDE-5027-8650). +[11/16/2024 1:23 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-0334-18CC-D8D3-4934-0BE8-3CDE-5027-8650). +[11/16/2024 1:23 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-5677-AF06-907B-08A5-B32E-9913-AFFB-F4F8). +[11/16/2024 1:23 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-5677-AF06-907B-08A5-B32E-9913-AFFB-F4F8). +[11/16/2024 1:23 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-5677-AF06-907B-08A5-B32E-9913-AFFB-F4F8). +[11/16/2024 1:23 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 1:23 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 1:25 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 1:25 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 1:25 PM] - SUCCESS : No license key found for row id (114). Deletion aborted. +[11/16/2024 1:25 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-CB2B-6D87-E702-594A-809F-6CC9-50D7-31A5). +[11/16/2024 1:25 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-CB2B-6D87-E702-594A-809F-6CC9-50D7-31A5). +[11/16/2024 1:25 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-CB2B-6D87-E702-594A-809F-6CC9-50D7-31A5). +[11/16/2024 1:25 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-3D21-3109-BC19-98F3-9EE8-8891-E33F-0F2A). +[11/16/2024 1:25 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-3D21-3109-BC19-98F3-9EE8-8891-E33F-0F2A). +[11/16/2024 1:25 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-3D21-3109-BC19-98F3-9EE8-8891-E33F-0F2A). +[11/16/2024 2:37 PM] - SUCCESS : No license key found for row id (117). Deletion aborted. +[11/16/2024 2:37 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 2:37 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 2:38 PM] - SUCCESS : No license key found for row id (117). Deletion aborted. +[11/16/2024 2:38 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-4AA8-C044-3F7D-A2D7-0C96-B028-3C0B-8DC6). +[11/16/2024 2:38 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-4AA8-C044-3F7D-A2D7-0C96-B028-3C0B-8DC6). +[11/16/2024 2:38 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-4AA8-C044-3F7D-A2D7-0C96-B028-3C0B-8DC6). +[11/16/2024 2:52 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 2:52 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 2:52 PM] - SUCCESS : No license key found for row id (118). Deletion aborted. +[11/16/2024 2:52 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-2F2D-0A50-589A-2218-FA9D-57CF-CDF1-AFDB). +[11/16/2024 2:52 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-2F2D-0A50-589A-2218-FA9D-57CF-CDF1-AFDB). +[11/16/2024 2:52 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-2F2D-0A50-589A-2218-FA9D-57CF-CDF1-AFDB). +[11/16/2024 2:53 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 2:53 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 2:53 PM] - SUCCESS : No license key found for row id (119). Deletion aborted. +[11/16/2024 2:53 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-5E7A-1E46-65B8-E0A9-20C8-3DCA-405D-0286). +[11/16/2024 2:53 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-5E7A-1E46-65B8-E0A9-20C8-3DCA-405D-0286). +[11/16/2024 2:53 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-5E7A-1E46-65B8-E0A9-20C8-3DCA-405D-0286). +[11/16/2024 2:54 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 2:54 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 2:55 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 2:55 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 2:59 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 2:59 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 3:00 PM] - SUCCESS : No license key found for row id (120). Deletion aborted. +[11/16/2024 3:01 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-CB3E-34BD-01A2-C01B-C6DA-FA9C-52D9-84E3). +[11/16/2024 3:01 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-CB3E-34BD-01A2-C01B-C6DA-FA9C-52D9-84E3). +[11/16/2024 3:01 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-CB3E-34BD-01A2-C01B-C6DA-FA9C-52D9-84E3). +[11/16/2024 3:02 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-16C2-D95B-90F5-E9B4-5B77-C4D7-17D2-EB74). +[11/16/2024 3:02 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-16C2-D95B-90F5-E9B4-5B77-C4D7-17D2-EB74). +[11/16/2024 3:02 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-16C2-D95B-90F5-E9B4-5B77-C4D7-17D2-EB74). +[11/16/2024 3:02 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-8265-D551-F989-EB4B-B5EF-F2AC-9CC2-E64F). +[11/16/2024 3:02 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-8265-D551-F989-EB4B-B5EF-F2AC-9CC2-E64F). +[11/16/2024 3:02 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-8265-D551-F989-EB4B-B5EF-F2AC-9CC2-E64F). +[11/16/2024 3:02 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 3:02 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 3:02 PM] - SUCCESS : No license key found for row id (122). Deletion aborted. +[11/16/2024 3:02 PM] - SUCCESS : No license key found for row id (121). Deletion aborted. +[11/16/2024 3:03 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-55AC-E91A-F0FA-61C8-9DF3-1A1F-38C8-82D1). +[11/16/2024 3:03 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-55AC-E91A-F0FA-61C8-9DF3-1A1F-38C8-82D1). +[11/16/2024 3:03 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-55AC-E91A-F0FA-61C8-9DF3-1A1F-38C8-82D1). +[11/16/2024 3:03 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 3:03 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 3:07 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 3:07 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 3:07 PM] - SUCCESS : No license key found for row id (124). Deletion aborted. +[11/16/2024 3:07 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-E488-1E7D-F14C-43D9-F1ED-B23D-EA38-60A9). +[11/16/2024 3:07 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-E488-1E7D-F14C-43D9-F1ED-B23D-EA38-60A9). +[11/16/2024 3:07 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-E488-1E7D-F14C-43D9-F1ED-B23D-EA38-60A9). +[11/16/2024 3:07 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-E4AC-924C-78A2-189D-2633-E4A6-39EE-1E99). +[11/16/2024 3:07 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-E4AC-924C-78A2-189D-2633-E4A6-39EE-1E99). +[11/16/2024 3:07 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-E4AC-924C-78A2-189D-2633-E4A6-39EE-1E99). +[11/16/2024 3:08 PM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/16/2024 3:08 PM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/16/2024 3:08 PM] - SUCCESS : No license key found for row id (125). Deletion aborted. +[11/16/2024 3:08 PM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-BD7C-BACD-412E-D268-61AC-DBF0-A557-B7AE). +[11/16/2024 3:08 PM] - SUCCESS : 1 entries deleted from log table for license key (SLM-BD7C-BACD-412E-D268-61AC-DBF0-A557-B7AE). +[11/16/2024 3:08 PM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-BD7C-BACD-412E-D268-61AC-DBF0-A557-B7AE). +[11/19/2024 1:32 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:32 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:33 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-D799-8DDC-3172-AF54-3A4C-C881-7A9E-C353). +[11/19/2024 1:33 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-D799-8DDC-3172-AF54-3A4C-C881-7A9E-C353). +[11/19/2024 1:33 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-D799-8DDC-3172-AF54-3A4C-C881-7A9E-C353). +[11/19/2024 1:33 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:33 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:36 AM] - SUCCESS : No license key found for row id (128). Deletion aborted. +[11/19/2024 1:36 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-6540-30EF-63A5-EF6E-3C37-A465-8846-192B). +[11/19/2024 1:36 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-6540-30EF-63A5-EF6E-3C37-A465-8846-192B). +[11/19/2024 1:36 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-6540-30EF-63A5-EF6E-3C37-A465-8846-192B). +[11/19/2024 1:43 AM] - SUCCESS : No license key found for row id (129). Deletion aborted. +[11/19/2024 1:43 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:43 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:43 AM] - SUCCESS : No license key found for row id (129). Deletion aborted. +[11/19/2024 1:44 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-AE29-5021-38EE-5C99-9982-72B2-14E2-64A1). +[11/19/2024 1:44 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-AE29-5021-38EE-5C99-9982-72B2-14E2-64A1). +[11/19/2024 1:44 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-AE29-5021-38EE-5C99-9982-72B2-14E2-64A1). +[11/19/2024 1:46 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:46 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:46 AM] - SUCCESS : No license key found for row id (130). Deletion aborted. +[11/19/2024 1:47 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-1CD0-1BA9-C29C-C09B-DCFF-19F6-E85C-7859). +[11/19/2024 1:47 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-1CD0-1BA9-C29C-C09B-DCFF-19F6-E85C-7859). +[11/19/2024 1:47 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-1CD0-1BA9-C29C-C09B-DCFF-19F6-E85C-7859). +[11/19/2024 1:50 AM] - SUCCESS : No license key found for row id (131). Deletion aborted. +[11/19/2024 1:50 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:50 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:51 AM] - SUCCESS : No license key found for row id (131). Deletion aborted. +[11/19/2024 1:52 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-6954-42D7-18A2-D4EA-E6B0-341E-1CB8-A6B1). +[11/19/2024 1:52 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-6954-42D7-18A2-D4EA-E6B0-341E-1CB8-A6B1). +[11/19/2024 1:52 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-6954-42D7-18A2-D4EA-E6B0-341E-1CB8-A6B1). +[11/19/2024 1:52 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:52 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:55 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 1:55 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 1:56 AM] - SUCCESS : No license key found for row id (132). Deletion aborted. +[11/19/2024 2:03 AM] - SUCCESS : No license key found for row id (132). Deletion aborted. +[11/19/2024 2:03 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-DFF3-16D6-C4D4-9AA1-65C6-3B48-F90F-ACA0). +[11/19/2024 2:03 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-DFF3-16D6-C4D4-9AA1-65C6-3B48-F90F-ACA0). +[11/19/2024 2:03 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-DFF3-16D6-C4D4-9AA1-65C6-3B48-F90F-ACA0). +[11/19/2024 2:03 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-57B7-0FAD-96D5-08A6-FD2E-6349-309C-E0CF). +[11/19/2024 2:03 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-57B7-0FAD-96D5-08A6-FD2E-6349-309C-E0CF). +[11/19/2024 2:03 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-57B7-0FAD-96D5-08A6-FD2E-6349-309C-E0CF). +[11/19/2024 2:03 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 2:03 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 2:06 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 2:06 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 2:26 AM] - SUCCESS : No license key found for row id (133). Deletion aborted. +[11/19/2024 2:27 AM] - SUCCESS : No license key found for row id (133). Deletion aborted. +[11/19/2024 2:28 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-6A1C-C6DC-F906-1A0A-81FD-F747-1F0A-8576). +[11/19/2024 2:28 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-6A1C-C6DC-F906-1A0A-81FD-F747-1F0A-8576). +[11/19/2024 2:28 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-6A1C-C6DC-F906-1A0A-81FD-F747-1F0A-8576). +[11/19/2024 2:28 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-89E4-8139-76B7-1003-C7C0-4BC4-6212-BD35). +[11/19/2024 2:28 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-89E4-8139-76B7-1003-C7C0-4BC4-6212-BD35). +[11/19/2024 2:28 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-89E4-8139-76B7-1003-C7C0-4BC4-6212-BD35). +[11/19/2024 2:29 AM] - SUCCESS : No license key found for row id (135). Deletion aborted. +[11/19/2024 2:32 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 2:32 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 2:32 AM] - SUCCESS : API - license creation (slm_create_new) request received. +[11/19/2024 2:32 AM] - SUCCESS : API Response - Result: success Message: License successfully created +[11/19/2024 2:33 AM] - SUCCESS : No license key found for row id (135). Deletion aborted. +[11/19/2024 2:33 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-C186-4990-98C2-901D-A226-3965-5D65-F806). +[11/19/2024 2:33 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-C186-4990-98C2-901D-A226-3965-5D65-F806). +[11/19/2024 2:33 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-C186-4990-98C2-901D-A226-3965-5D65-F806). +[11/19/2024 2:33 AM] - SUCCESS : 0 entries deleted from devices table for license key (SLM-DAB0-BF76-E594-2E3B-99CF-4EAA-AA48-502E). +[11/19/2024 2:33 AM] - SUCCESS : 1 entries deleted from log table for license key (SLM-DAB0-BF76-E594-2E3B-99CF-4EAA-AA48-502E). +[11/19/2024 2:33 AM] - SUCCESS : 0 entries deleted from emails table for license key (SLM-DAB0-BF76-E594-2E3B-99CF-4EAA-AA48-502E). diff --git a/readme.txt b/readme.txt index 0e5023c..d47e4e7 100644 --- a/readme.txt +++ b/readme.txt @@ -3,52 +3,10 @@ Contributors: Michel Velis, Tips and Tricks HQ Donate link: http://paypal.me/mvelis Tags: license, software license, woocommerce, license management Requires at least: 5.6 -Tested up to: 6.1.0 -Stable tag: 6.1.0 -Requires PHP: 7.4 +Tested up to: 6.7 +Stable tag: 6.1.9 +Tags: license manager, license key, license genrator, subscription +Requires PHP: 7.2 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html - -A comprehensive software license management solution for web applications including WordPress plugins, themes, and PHP-based software. Seamlessly integrates with WooCommerce to offer license key generation, management, and validation. Ideal for developers managing software licenses across multiple platforms with built-in multilingual support and performance optimization. - -== Description == - -SLM Plus provides a powerful solution for managing software licenses for WordPress plugins, themes, and other web applications. With WooCommerce integration, the plugin allows you to generate, activate, and manage licenses for your customers seamlessly. - -## 📦 Features: -- Generate and manage license keys for your products -- Remote license key validation and activation -- Track license key usage across different domains and devices -- Manually create licenses from the admin dashboard -- Bulk actions for managing licenses -- Export licenses for both users and admins (new) -- View licenses by subscribers (new) -- License info is now included inside WooCommerce order details (new) -- License activity logs to track key usage and activations (new) -- Admin stats widgets to visualize license usage (new) -- Automated emails for license expiration and activation reminders -- Multilingual support (English, Spanish) -- WooCommerce product type integration to manage licenses through orders -- Manage licenses directly from users' "My Account" page -- License expiration reminders and notification emails - -== Installation == - -This section describes how to install the plugin and get it working. - -1. Go to the Add New plugins screen in your WordPress admin area -2. Click the Upload tab -3. Browse for the plugin file (software-license-manager.zip) -4. Click Install Now and then activate the plugin - -== Changelog == -= 6.1.0 = -- Improved compatibility with WordPress 6.1 and WooCommerce -- Enhanced performance for large license databases -- Added multilingual support for Spanish -- New admin widgets for tracking licenses -- Improved license information in WooCommerce order details - -== Upgrade Notice == -= 6.1.0 = -- Please ensure your WordPress version is at least 5.6 and PHP version is 7.4 or higher before updating. +SLM Plus offers a powerful solution for managing licenses for WordPress plugins, themes, and web apps. With WooCommerce integration. diff --git a/samples/ActivateLicense.php b/samples/ActivateLicense.php deleted file mode 100644 index ef64a64..0000000 --- a/samples/ActivateLicense.php +++ /dev/null @@ -1,69 +0,0 @@ -licenseAPI = new LicenseAPI(); - } - - /** - * Activate a license on a specific domain or device. - * - * @param array $activationData Activation data, including license key, domain, and optionally device. - * @return void Outputs the result based on the activation response. - */ - public function activate($activationData) - { - $response = $this->licenseAPI->activateLicense($activationData); - - // Handle different scenarios based on the API response - if ($response['result'] === 'success') { - echo "License activated successfully for domain: " . $activationData['registered_domain']; - if (!empty($activationData['registered_devices'])) { - echo " and device: " . $activationData['registered_devices']; - } - } elseif (isset($response['error_code'])) { - // Specific error handling based on the API's error code - switch ($response['error_code']) { - case SLM_Error_Codes::LICENSE_EXPIRED: - echo "Error: The license has expired. Please renew your license."; - break; - case SLM_Error_Codes::LICENSE_BLOCKED: - echo "Error: The license is blocked. Contact support for assistance."; - break; - case SLM_Error_Codes::LICENSE_IN_USE: - echo "Error: This license is already in use on the specified domain or device."; - break; - case SLM_Error_Codes::REACHED_MAX_DOMAINS: - echo "Error: Maximum allowed domains reached. Upgrade your license for additional domains."; - break; - case SLM_Error_Codes::REACHED_MAX_DEVICES: - echo "Error: Maximum allowed devices reached. Upgrade your license for additional devices."; - break; - default: - echo "Error: Activation failed. " . ($response['message'] ?? 'Unknown error.'); - break; - } - } else { - // Generic error message for unexpected issues - echo "Error: Unable to activate license. " . ($response['message'] ?? 'Please try again later.'); - } - } -} - -// Usage example -$activateLicense = new ActivateLicense(); - -$activationData = [ - 'license_key' => 'YOUR_LICENSE_KEY', - 'registered_domain' => 'example.com', // Required: Domain for license activation - 'registered_devices' => 'Device12345' // Optional: Device identifier (if applicable) -]; - -$activateLicense->activate($activationData); - diff --git a/samples/CheckLicense.php b/samples/CheckLicense.php deleted file mode 100644 index 57426eb..0000000 --- a/samples/CheckLicense.php +++ /dev/null @@ -1,68 +0,0 @@ -licenseAPI = new LicenseAPI(); - } - - /** - * Check the status of a license. - * - * @param string $licenseKey The license key to check. - * @return void Outputs the result of the license status check. - */ - public function check($licenseKey) - { - $data = [ - 'license_key' => $licenseKey, - ]; - - $response = $this->licenseAPI->checkLicenseStatus($data); - - // Interpret the response based on license status and other indicators - if ($response['result'] === 'success') { - $status = $response['data']['status']; - switch ($status) { - case 'active': - echo "License is active and valid."; - break; - case 'expired': - echo "License has expired. Please renew to continue using the product."; - break; - case 'blocked': - echo "License is blocked. Contact support for further assistance."; - break; - default: - echo "License status: " . ucfirst($status) . "."; - break; - } - } elseif (isset($response['error_code'])) { - // Handle specific error codes for license check failure - switch ($response['error_code']) { - case SLM_Error_Codes::LICENSE_INVALID: - echo "Error: Invalid license key provided."; - break; - default: - echo "Error checking license status: " . ($response['message'] ?? 'Unknown error.'); - break; - } - } else { - // Fallback for unexpected issues - echo "Error: Unable to check license status. " . ($response['message'] ?? 'Please try again later.'); - } - } -} - -// Usage example -$checkLicense = new CheckLicense(); - -// License key to check -$licenseKey = 'YOUR_LICENSE_KEY'; -$checkLicense->check($licenseKey); - diff --git a/samples/CoreConfig.php b/samples/CoreConfig.php deleted file mode 100644 index c87d324..0000000 --- a/samples/CoreConfig.php +++ /dev/null @@ -1,114 +0,0 @@ - 'error', - 'message' => 'Invalid response format from the API.', - ]; - } - - // Handle success and error cases - if (isset($response['result']) && $response['result'] === 'success') { - return ['result' => 'success', 'data' => $response]; - } elseif (isset($response['result']) && $response['result'] === 'error') { - self::logError($response['message'] ?? 'Unknown error'); - return ['result' => 'error', 'message' => $response['message'] ?? 'An error occurred.']; - } - - // Fallback for unexpected response structures - return ['result' => 'error', 'message' => 'Unexpected response structure.']; - } - - /** - * Log errors for troubleshooting. - * - * @param string $message The error message to log. - */ - public static function logError($message) - { - error_log("[API ERROR] " . $message); - } - - /** - * Sanitize and validate input fields for security. - * - * @param array $fields Fields to be sanitized. - * @return array Sanitized fields. - */ - public static function sanitizeFields($fields) - { - foreach ($fields as $key => $value) { - switch ($key) { - case 'email': - $fields[$key] = filter_var($value, FILTER_SANITIZE_EMAIL); - break; - case 'max_allowed_domains': - case 'max_allowed_devices': - $fields[$key] = intval($value); - break; - default: - $fields[$key] = htmlspecialchars(strip_tags($value)); - } - } - return $fields; - } - - /** - * Send a secure API request with cURL. - * - * @param string $action API action name. - * @param array $data Data to send in the request. - * @return array Processed API response. - */ - public static function apiRequest($action, $data) - { - $data['secret_key'] = self::SECRET_KEY; - $data = self::sanitizeFields($data); - - $ch = curl_init(self::getApiUrl($action)); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - $response = curl_exec($ch); - - if (curl_errno($ch)) { - self::logError('cURL Error: ' . curl_error($ch)); - curl_close($ch); - return [ - 'result' => 'error', - 'message' => 'Network error during API request.', - ]; - } - - curl_close($ch); - - return self::processResponse(json_decode($response, true)); - } -} - diff --git a/samples/CreateLicense.php b/samples/CreateLicense.php deleted file mode 100644 index 70e9372..0000000 --- a/samples/CreateLicense.php +++ /dev/null @@ -1,47 +0,0 @@ -licenseAPI = new LicenseAPI(); - } - - /** - * Create a new license using provided data. - * - * @param array $licenseData Data for license creation. - * @return void Displays success or error message based on response. - */ - public function create($licenseData) - { - $response = $this->licenseAPI->createLicense($licenseData); - - if ($response['result'] === 'success') { - echo "License created successfully. Key: " . $response['data']['key']; - } else { - echo "Error creating license: " . $response['message']; - } - } -} - -// Usage example -$createLicense = new CreateLicense(); - -$licenseData = [ - 'first_name' => 'John', - 'last_name' => 'Doe', - 'email' => 'johndoe@example.com', - 'purchase_id_' => '12345', - 'max_allowed_domains' => 2, - 'max_allowed_devices' => 1, - 'date_created' => date('Y-m-d'), - 'product_ref' => 'ThemePro' -]; - -$createLicense->create($licenseData); - diff --git a/samples/DeactivateLicense.php b/samples/DeactivateLicense.php deleted file mode 100644 index 79a2ff1..0000000 --- a/samples/DeactivateLicense.php +++ /dev/null @@ -1,61 +0,0 @@ -licenseAPI = new LicenseAPI(); - } - - /** - * Deactivate a license on a specific domain or device. - * - * @param array $deactivationData Deactivation data, including license key, domain, and/or device. - * @return void Outputs the result based on the deactivation response. - */ - public function deactivate($deactivationData) - { - $response = $this->licenseAPI->deactivateLicense($deactivationData); - - // Handle response scenarios - if ($response['result'] === 'success') { - echo "License deactivated successfully for domain: " . ($deactivationData['registered_domain'] ?? 'N/A'); - if (!empty($deactivationData['registered_devices'])) { - echo " and device: " . $deactivationData['registered_devices']; - } - } elseif (isset($response['error_code'])) { - // Handle specific deactivation error codes - switch ($response['error_code']) { - case SLM_Error_Codes::DOMAIN_ALREADY_INACTIVE: - echo "Error: The license is already inactive on the specified domain or device."; - break; - case SLM_Error_Codes::DOMAIN_MISSING: - echo "Error: The specified domain or device was not found."; - break; - default: - echo "Error: Deactivation failed. " . ($response['message'] ?? 'Unknown error.'); - break; - } - } else { - // Fallback for unexpected issues - echo "Error: Unable to deactivate license. " . ($response['message'] ?? 'Please try again later.'); - } - } -} - -// Usage example -$deactivateLicense = new DeactivateLicense(); - -$deactivationData = [ - 'license_key' => 'YOUR_LICENSE_KEY', - 'registered_domain' => 'example.com', // Optional: Domain to deactivate the license on - 'registered_devices' => 'Device12345' // Optional: Device to deactivate (if applicable) -]; - -// If both domain and device are provided, only one needs to match for deactivation. -$deactivateLicense->deactivate($deactivationData); - diff --git a/samples/GetLicenseInfo.php b/samples/GetLicenseInfo.php deleted file mode 100644 index 215d7b7..0000000 --- a/samples/GetLicenseInfo.php +++ /dev/null @@ -1,83 +0,0 @@ -licenseAPI = new LicenseAPI(); - } - - /** - * Retrieve and display detailed information about a license. - * - * @param string $licenseKey The license key to retrieve information for. - * @return void Outputs detailed license information based on the response. - */ - public function retrieve($licenseKey) - { - $data = [ - 'license_key' => $licenseKey, - ]; - - $response = $this->licenseAPI->getLicenseInfo($data); - - // Interpret and display license information based on the API response - if ($response['result'] === 'success') { - $info = $response['data']; - - echo "License Information:\n"; - echo "-----------------------\n"; - echo "License Key: " . $info['license_key'] . "\n"; - echo "Status: " . ucfirst($info['status']) . "\n"; - echo "Registered User: " . $info['first_name'] . " " . $info['last_name'] . "\n"; - echo "Email: " . $info['email'] . "\n"; - echo "Company: " . ($info['company_name'] ?? 'N/A') . "\n"; - echo "Product: " . $info['product_ref'] . "\n"; - echo "Created Date: " . $info['date_created'] . "\n"; - echo "Expiry Date: " . ($info['date_expiry'] ?? 'N/A') . "\n"; - echo "Max Domains: " . $info['max_allowed_domains'] . "\n"; - echo "Max Devices: " . $info['max_allowed_devices'] . "\n"; - - if (!empty($info['registered_domains'])) { - echo "Registered Domains:\n"; - foreach ($info['registered_domains'] as $domain) { - echo " - " . $domain->registered_domain . "\n"; - } - } - - if (!empty($info['registered_devices'])) { - echo "Registered Devices:\n"; - foreach ($info['registered_devices'] as $device) { - echo " - " . $device->registered_devices . "\n"; - } - } - echo "-----------------------\n"; - - } elseif (isset($response['error_code'])) { - // Handle specific error codes for information retrieval - switch ($response['error_code']) { - case SLM_Error_Codes::LICENSE_INVALID: - echo "Error: Invalid license key provided."; - break; - default: - echo "Error retrieving license information: " . ($response['message'] ?? 'Unknown error.'); - break; - } - } else { - // Fallback for unexpected issues - echo "Error: Unable to retrieve license information. " . ($response['message'] ?? 'Please try again later.'); - } - } -} - -// Usage example -$getLicenseInfo = new GetLicenseInfo(); - -// License key to retrieve information for -$licenseKey = 'YOUR_LICENSE_KEY'; -$getLicenseInfo->retrieve($licenseKey); - diff --git a/samples/LicenseAPI.php b/samples/LicenseAPI.php deleted file mode 100644 index 8cb5cf9..0000000 --- a/samples/LicenseAPI.php +++ /dev/null @@ -1,73 +0,0 @@ -' . __('Settings') . ''; - // $github_link = '' . __('GitHub') . ''; +function slm_settings_link($links) +{ + $settings_link = '' . __('Settings', 'slm-plus') . ''; + // $github_link = '' . __('GitHub') . ''; $links[] = $settings_link; //$links[] = $github_link; return $links; } add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'slm_settings_link'); + define('SLM_DEFAULT_MAX_DOMAINS', SLM_API_Utility::get_slm_option('default_max_domains')); define('SLM_DEFAULT_MAX_DEVICES', SLM_API_Utility::get_slm_option('default_max_devices')); diff --git a/uninstall.php b/uninstall.php index 46ff238..99c743e 100755 --- a/uninstall.php +++ b/uninstall.php @@ -34,7 +34,7 @@ foreach ($slm_options as $option) { delete_option($option); } -// Sanitize and list all tables related to the plugin +// List all tables related to the plugin $tables_to_drop = array( $wpdb->prefix . 'lic_key_tbl', $wpdb->prefix . 'lic_reg_domain_tbl', @@ -45,36 +45,45 @@ $tables_to_drop = array( $wpdb->prefix . 'slm_activations_tbl', ); -// Drop custom database tables +// Drop custom database tables using the `prepare` method foreach ($tables_to_drop as $table) { - $wpdb->query("DROP TABLE IF EXISTS `$table`"); + // Check if the table exists before attempting to drop it + if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table)) !== null) { + // Drop the table if it exists + $wpdb->query($wpdb->prepare("DROP TABLE IF EXISTS %s", $table)); + } } -// Delete Custom Post Type posts and related metadata +// Delete Custom Post Type posts and related metadata using the `delete` method $post_types = array('slm_manage_license', 'slm_license_product'); // Add any other custom post types if needed foreach ($post_types as $post_type) { - $wpdb->query( - $wpdb->prepare( - "DELETE posts, meta FROM {$wpdb->posts} posts - LEFT JOIN {$wpdb->postmeta} meta ON posts.ID = meta.post_id - WHERE posts.post_type = %s", - $post_type - ) - ); + // Check if post type data is cached + $cached_posts = wp_cache_get($post_type, 'slm_posts'); + if ($cached_posts) { + wp_cache_delete($post_type, 'slm_posts'); + } + + // Safely delete posts and metadata for this post type + $wpdb->delete($wpdb->posts, array('post_type' => $post_type)); + $wpdb->delete($wpdb->postmeta, array('post_id' => $post_type)); } -// Clean orphaned postmeta entries +// Clean orphaned postmeta entries using `DELETE` queries $wpdb->query( - "DELETE pm FROM {$wpdb->postmeta} pm - LEFT JOIN {$wpdb->posts} p ON pm.post_id = p.ID - WHERE p.ID IS NULL" + $wpdb->prepare( + "DELETE pm FROM {$wpdb->postmeta} pm + LEFT JOIN {$wpdb->posts} p ON pm.post_id = p.ID + WHERE p.ID IS NULL" + ) ); // Clean orphaned term relationships if there are custom taxonomies involved $wpdb->query( - "DELETE tr FROM {$wpdb->term_relationships} tr - LEFT JOIN {$wpdb->posts} p ON tr.object_id = p.ID - WHERE p.ID IS NULL" + $wpdb->prepare( + "DELETE tr FROM {$wpdb->term_relationships} tr + LEFT JOIN {$wpdb->posts} p ON tr.object_id = p.ID + WHERE p.ID IS NULL" + ) ); // Delete custom user meta related to the plugin (if applicable) @@ -84,10 +93,14 @@ $user_meta_keys = array( ); foreach ($user_meta_keys as $meta_key) { - $wpdb->query( - $wpdb->prepare( - "DELETE FROM {$wpdb->usermeta} WHERE meta_key = %s", - $meta_key - ) - ); + // Check if user meta data is cached + $cached_meta = wp_cache_get($meta_key, 'slm_usermeta'); + if ($cached_meta) { + wp_cache_delete($meta_key, 'slm_usermeta'); + } + + $wpdb->delete($wpdb->usermeta, array('meta_key' => $meta_key)); } + +// Clear the relevant cache after heavy operations +wp_cache_flush(); diff --git a/woocommerce/includes/create-license-orders.php b/woocommerce/includes/create-license-orders.php index 2920a18..37a3fdc 100644 --- a/woocommerce/includes/create-license-orders.php +++ b/woocommerce/includes/create-license-orders.php @@ -13,7 +13,8 @@ $slm_options = get_option('slm_plugin_options'); // Retrieve plugin options add_action('wp_ajax_slm_generate_licenses', 'slm_generate_licenses_callback'); -function slm_generate_licenses_callback() { +function slm_generate_licenses_callback() +{ check_ajax_referer('slm_generate_licenses_nonce', 'security'); global $wpdb; @@ -30,16 +31,16 @@ function slm_generate_licenses_callback() { ? sanitize_text_field($_POST['subscription_type']) : 'subscription'; - SLM_Helper_Class::write_log("Starting license generation with Product ID: {$default_product_id} and License Type: {$slm_lic_type}."); + //SLM_Helper_Class::write_log("Starting license generation with Product ID: {$default_product_id} and License Type: {$slm_lic_type}."); // Check if Product ID is missing; if so, log an error, add an error response, and exit. if (empty($default_product_id)) { - SLM_Helper_Class::write_log('Error: Product ID is missing in the request.'); + //SLM_Helper_Class::write_log('Error: Product ID is missing in the request.'); // Track failure and skip reason for the response $failure_count++; $skipped_orders[] = 0; - $skipped_reasons[0] = __('Product ID is missing in the request.', 'slmplus'); + $skipped_reasons[0] = __('Product ID is missing in the request.', 'slm-plus'); // Return early with a JSON error response for AJAX display $response_data['html'] .= '
  • Error: Product ID is missing in the request. Please provide a valid product ID.
  • '; @@ -50,12 +51,12 @@ function slm_generate_licenses_callback() { // Check if the Product ID corresponds to an existing WooCommerce product $product = wc_get_product($default_product_id); if (!$product) { - SLM_Helper_Class::write_log("Error: Product with ID $default_product_id does not exist in WooCommerce."); + //SLM_Helper_Class::write_log("Error: Product with ID $default_product_id does not exist in WooCommerce."); // Track failure and skip reason for the response $failure_count++; $skipped_orders[] = 0; - $skipped_reasons[0] = __('The provided Product ID does not correspond to a valid WooCommerce product. Please check the ID and try again.', 'slmplus'); + $skipped_reasons[0] = __('The provided Product ID does not correspond to a valid WooCommerce product. Please check the ID and try again.', 'slm-plus'); // Return early with a JSON error response for AJAX display $response_data['html'] .= '
  • Error: The provided Product ID does not correspond to a valid WooCommerce product. Please check the ID and try again.
  • '; @@ -119,7 +120,7 @@ function slm_generate_licenses_callback() { } } - SLM_Helper_Class::write_log("Interval: {$slm_billing_interval} - Length: {$slm_billing_length}"); + //SLM_Helper_Class::write_log("Interval: {$slm_billing_interval} - Length: {$slm_billing_length}"); $order_items = $order->get_items(); @@ -128,7 +129,7 @@ function slm_generate_licenses_callback() { $product = wc_get_product($default_product_id); if (!$product) { - SLM_Helper_Class::write_log("Error: Product with ID {$default_product_id} does not exist."); + //SLM_Helper_Class::write_log("Error: Product with ID {$default_product_id} does not exist."); continue; } @@ -184,12 +185,13 @@ function slm_generate_licenses_callback() { $license_key = sanitize_text_field($api_response['key']); $success_count++; - $item->add_meta_data('_slm_lic_key', $license_key, true); - $item->add_meta_data('_slm_lic_type', $slm_lic_type, true); - $order->add_order_note( - sprintf(__('License Key generated: %s', 'slmplus'), $license_key) - ); + $item->add_meta_data('License Key', $license_key, true); + $item->add_meta_data('License Type', $slm_lic_type, true); + $order->add_order_note( + // Translators: %s is the generated license key + sprintf(__('License Key generated: %s', 'slm-plus'), $license_key) + ); $generated_licenses[] = [ 'license_key' => $license_key, 'order_id' => $order_id, @@ -233,10 +235,12 @@ function slm_generate_licenses_callback() { $success_count++; $generated_licenses[] = ['license_key' => $license_key, 'order_id' => $order_id]; - $item->add_meta_data('_slm_lic_key', $license_key, true); - $item->add_meta_data('_slm_lic_type', $slm_lic_type, true); + $item->add_meta_data('License Key', $license_key, true); + $item->add_meta_data('License Type', $slm_lic_type, true); + $order->add_order_note( - sprintf(__('License Key generated: %s', 'slmplus'), $license_key) + // Translators: %s is the generated license key + sprintf(__('License Key generated: %s', 'slm-plus'), $license_key) ); } else { $failure_count++; @@ -251,17 +255,16 @@ function slm_generate_licenses_callback() { } if (!empty($skipped_orders)) { - foreach ($skipped_orders as $order_id) { - SLM_Helper_Class::write_log("Skipping Order ID {$order_id}: {$skipped_reasons[$order_id]}."); - } - } - - if (!empty($skipped_orders)) { - $response_data['html'] .= '
  • ' . sprintf(__('%d orders were skipped:', 'slmplus'), count($skipped_orders)) . '
      '; + $response_data['html'] .= '
    • ' . sprintf( + // Translators: %1$d is the number of orders skipped + __('%1$d orders were skipped:', 'slm-plus'), + count($skipped_orders) + ) . '
        '; foreach ($skipped_orders as $order_id) { if ($order_id !== 0) { $order_link = admin_url('post.php?post=' . $order_id . '&action=edit'); - $response_data['html'] .= '
      • ' . sprintf(__('Order ID %d was skipped due to: %s. View Order', 'slmplus'), $order_id, esc_html($skipped_reasons[$order_id]), esc_url($order_link)) . '
      • '; + // Translators: %1$d is the order ID, %2$s is the reason why the order was skipped, %3$s is the order view link + $response_data['html'] .= '
      • ' . sprintf(__('Order ID %1$d was skipped due to: %2$s. View Order', 'slm-plus'), $order_id, esc_html($skipped_reasons[$order_id]), esc_url($order_link)) . '
      • '; } else { $response_data['html'] .= '
      • ' . esc_html($skipped_reasons[0]) . '
      • '; } @@ -270,16 +273,25 @@ function slm_generate_licenses_callback() { } if ($success_count > 0) { - $response_data['html'] .= '
      • ' . sprintf(__('%d licenses generated successfully:', 'slmplus'), $success_count) . '
          '; + $response_data['html'] .= '
        • ' . sprintf( + // Translators: %1$d is the number of successfully generated licenses + __('%1$d licenses generated successfully:', 'slm-plus'), + $success_count + ) . '
            '; foreach ($generated_licenses as $license_data) { $order_link = admin_url('post.php?post=' . $license_data['order_id'] . '&action=edit'); - $response_data['html'] .= '
          • ' . sprintf(__('License Key: %s for Order ID %d - View Order', 'slmplus'), esc_html($license_data['license_key']), $license_data['order_id'], esc_url($order_link)) . '
          • '; + // Translators: %1$s is the license key, %2$d is the order ID, %3$s is the order view link + $response_data['html'] .= '
          • ' . sprintf(__('License Key: %1$s for Order ID %2$d - View Order', 'slm-plus'), esc_html($license_data['license_key']), $license_data['order_id'], esc_url($order_link)) . '
          • '; } $response_data['html'] .= '
        • '; } if ($failure_count > 0) { - $response_data['html'] .= '
        • ' . sprintf(__('%d licenses failed to generate.', 'slmplus'), $failure_count) . '
        • '; + $response_data['html'] .= '
        • ' . sprintf( + // Translators: %1$d is the number of licenses that failed to generate + __('%1$d licenses failed to generate.', 'slm-plus'), + $failure_count + ) . '
        • '; } wp_send_json_success($response_data); diff --git a/woocommerce/includes/purchase.php b/woocommerce/includes/purchase.php index f740b0e..a34b233 100755 --- a/woocommerce/includes/purchase.php +++ b/woocommerce/includes/purchase.php @@ -32,31 +32,9 @@ if ($affect_downloads) { // Add additional license management after order completion add_action('woocommerce_order_status_completed', 'wc_slm_on_complete_purchase', 10); -// Hide license key metadata from order item meta table in the backend -add_filter('woocommerce_hidden_order_itemmeta', 'slm_hide_order_meta', 10, 1); - // Display license key information more nicely in the order item meta table add_action('woocommerce_after_order_itemmeta', 'slm_display_nice_item_meta', 10, 3); -// Uncomment the following if you want to display a message on the thank-you page -// add_action('woocommerce_thankyou', 'slm_show_msg', 80); - - - -/** - * Disable display of some metadata. - * - * @param array $hide_meta List of meta data to hide. - * @return array Modified list of meta data to hide. - * @since 4.5.5 - */ -function slm_hide_order_meta($hide_meta) { - // Adding metadata to hide from the order item meta table - $hide_meta[] = '_slm_lic_key'; - $hide_meta[] = '_slm_lic_type'; - return $hide_meta; -} - /** * Display order meta data in Order items table in a user-friendly way. * @@ -66,10 +44,11 @@ function slm_hide_order_meta($hide_meta) { * * @since 4.5.5 */ -function slm_display_nice_item_meta($item_id, $item, $product) { +function slm_display_nice_item_meta($item_id, $item, $product) +{ // Fetch the metadata associated with the license key if ($meta_data = wc_get_order_item_meta($item_id, '_slm_lic_key', false)) { - ?> +?>
          + ?> - - + +
          - get_id(); - SLM_Helper_Class::write_log('Purchase ID: ' . $purchase_id_); + //SLM_Helper_Class::write_log('Purchase ID: ' . $purchase_id_); global $user_id; $user_id = $order->get_user_id(); - SLM_Helper_Class::write_log('User ID: ' . $user_id); + //SLM_Helper_Class::write_log('User ID: ' . $user_id); if (!$user_id) { - SLM_Helper_Class::write_log('User ID not found for Order ID: ' . $order_id); + //SLM_Helper_Class::write_log('User ID not found for Order ID: ' . $order_id); return; // Stop if user ID cannot be found } @@ -183,17 +161,10 @@ function wc_slm_create_license_keys($order_id) } // Log renewal details - SLM_Helper_Class::write_log('Renewal Period: ' . $renewal_period); - SLM_Helper_Class::write_log('Expiration Date: ' . $expiration); - SLM_Helper_Class::write_log('Renewal Term: ' . $renewal_term); + //SLM_Helper_Class::write_log('Renewal Period: ' . $renewal_period); + //SLM_Helper_Class::write_log('Expiration Date: ' . $expiration); + //SLM_Helper_Class::write_log('Renewal Term: ' . $renewal_term); - // Get allowed sites/devices and verify them - $sites_allowed = wc_slm_get_sites_allowed($product_id); - if (!$sites_allowed) { - wc_insert_payment_note($purchase_id_, __('License could not be created: Invalid sites allowed number.', 'slmplus')); - SLM_Helper_Class::write_log('License could not be created: Invalid sites allowed number'); - break; - } // Collect product details $item_data = $values->get_data(); @@ -204,6 +175,7 @@ function wc_slm_create_license_keys($order_id) $license_type = get_post_meta($product_id, '_license_type', true); $lic_item_ref = get_post_meta($product_id, '_license_item_reference', true); $transaction_id = wc_get_payment_transaction_id($order_id); + $sites_allowed = wc_slm_get_sites_allowed($product_id); // Prepare API parameters for license creation $api_params = array( @@ -232,7 +204,7 @@ function wc_slm_create_license_keys($order_id) // Send the request to create a license key $url = esc_url_raw(SLM_SITE_HOME_URL) . '?' . http_build_query($api_params); - SLM_Helper_Class::write_log('URL: ' . $url); + //SLM_Helper_Class::write_log('URL: ' . $url); $response = wp_safe_remote_get($url, array('timeout' => 20, 'sslverify' => false)); $license_key = wc_slm_get_license_key($response); @@ -251,28 +223,35 @@ function wc_slm_create_license_keys($order_id) 'version' => $_license_current_version, 'until' => $_license_until_version ); + $item_id = $values->get_id(); - // Store license details for the product in the order item meta - wc_add_order_item_meta($item_id, '_slm_lic_key', sanitize_text_field($license_key)); - wc_add_order_item_meta($item_id, '_slm_lic_type', sanitize_text_field($license_type)); - wc_add_order_item_meta($item_id, 'Current Version: ', sanitize_text_field($_license_current_version)); - wc_add_order_item_meta($item_id, 'Until Version:', sanitize_text_field($_license_until_version)); - wc_add_order_item_meta($item_id, 'Max Devices', sanitize_text_field($amount_of_licenses_devices)); - wc_add_order_item_meta($item_id, 'Max Domains', sanitize_text_field($sites_allowed)); + + // Update order meta with license details + $order = wc_get_order($order_id); + if ($order) { + $order->update_meta_data('License Key', sanitize_text_field($license_key)); + $order->update_meta_data('License Type', sanitize_text_field($license_type)); // Save the license type + $order->save(); // Save changes to the order + } + + // Update order item meta with license details + $order_item = new WC_Order_Item_Product($item_id); + if ($order_item) { + $order_item->update_meta_data('License Key', sanitize_text_field($license_key)); + $order_item->update_meta_data('License Type', sanitize_text_field($license_type)); + $order_item->update_meta_data('Current Ver.', sanitize_text_field($_license_current_version)); + $order_item->update_meta_data('Until Ver.', sanitize_text_field($_license_until_version)); + $order_item->update_meta_data('Max Devices', sanitize_text_field($amount_of_licenses_devices)); + $order_item->update_meta_data('Max Domains', sanitize_text_field($sites_allowed)); + $order_item->save(); // Save changes to the order item + } } } } } - - // If licenses were successfully generated, add a payment note - if (count($licenses) > 0) { - wc_slm_payment_note($order_id, $licenses); - //slm_add_lic_key_meta_update($order_id, $licenses); - } } - -function wc_slm_get_license_key($response) +function wc_slm_get_license_key($response) { // Check for error in the response if (is_wp_error($response)) { @@ -291,7 +270,7 @@ function wc_slm_get_license_key($response) if (json_last_error() !== JSON_ERROR_NONE) { // Handle JSON decoding error appropriately, e.g., log the error - error_log('Failed to decode JSON response: ' . json_last_error_msg()); + //SLM_Helper_Class::write_log('Failed to decode JSON response: ' . json_last_error_msg()); return false; } @@ -300,7 +279,7 @@ function wc_slm_get_license_key($response) if ($cleaned_data === false) { // If the cleaning fails, return false - error_log('Failed to clean the JSON response body.'); + //SLM_Helper_Class::write_log('Failed to clean the JSON response body.'); return false; } @@ -315,8 +294,7 @@ function wc_slm_get_license_key($response) return $license_data->key; } - -function wc_slm_get_license_id($license) +function wc_slm_get_license_id($license) { global $wpdb; @@ -334,53 +312,6 @@ function wc_slm_get_license_id($license) return $license_id ? intval($license_id) : false; } -function wc_slm_payment_note($order_id, $licenses) -{ - // Get the order object - $order = wc_get_order($order_id); - - // Check if the order is valid and licenses are provided - if ($order && !empty($licenses) && is_array($licenses)) { - $message = __('License Key(s) generated:', 'slmplus'); - - foreach ($licenses as $license) { - // Check if required license information is available - if (!isset($license['key']) || !isset($license['item'])) { - continue; // Skip if data is incomplete - } - - $license_key = sanitize_text_field($license['key']); - $item_name = sanitize_text_field($license['item']); - - // Fetch the license ID securely - $license_id = wc_slm_get_license_id($license_key); - - // Construct the link to the license edit page - $license_link = esc_url( - add_query_arg( - array( - 'page' => 'slm_manage_license', - 'edit_record' => $license_id, - ), - admin_url('admin.php') - ) - ); - - // Add to the message - $message .= '
          ' . esc_html($item_name) . ': ' . esc_html($license_key) . ''; - } - } else { - $message = __('License Key(s) could not be created.', 'slmplus'); - } - - // Add the message as an order note using the correct method - if ($order) { - $order->add_order_note( wp_kses_post($message) ); - } -} - - - function wc_slm_access_expiration($order_id, $lic_expiry = '') { global $wpdb; @@ -432,7 +363,7 @@ function wc_slm_access_expiration($order_id, $lic_expiry = '') } // Optionally, log the query for debugging (commented out by default) - //SLM_Helper_Class::write_log('log:' . $query); + ////SLM_Helper_Class::write_log('log:' . $query); } @@ -464,20 +395,6 @@ function get_licence_by_key($licence_key) return $record ? $record : false; } -/** - * Assign Licenses to Order - * - * @param int $order_id WooCommerce Order ID to assign licenses to. - * @param array $licenses An array of licenses to be assigned. - * @return void - */ -function wc_slm_assign_licenses($order_id, $licenses) -{ - // Check if licenses are available and valid - if (!empty($licenses) && is_array($licenses)) { - add_post_meta($order_id, '_wc_slm_payment_licenses', $licenses); - } -} /** * Get Allowed Number of Sites for a Product @@ -494,17 +411,6 @@ function wc_slm_get_sites_allowed($product_id) return !empty($wc_slm_sites_allowed) ? $wc_slm_sites_allowed : false; } -/** - * Get License Type - * - * @param int $product_id Product ID. - * @return string|false License type or false if not found. - */ -function wc_slm_get_lic_type($product_id) -{ - $_license_type = get_post_meta($product_id, '_license_type', true); - return !empty($_license_type) ? sanitize_text_field($_license_type) : false; -} /** * Get Number of Allowed Devices @@ -518,17 +424,6 @@ function wc_slm_get_devices_allowed($product_id) return !empty($_devices_licenses) ? $_devices_licenses : false; } -/** - * Get Quantity of Licenses - * - * @param int $product_id Product ID. - * @return int|false Quantity of licenses or false if not set. - */ -function wc_slm_get_licenses_qty($product_id) -{ - $amount_of_licenses = absint(get_post_meta($product_id, '_amount_of_licenses', true)); - return !empty($amount_of_licenses) ? $amount_of_licenses : false; -} /** * Get Licensing Renewal Period @@ -554,35 +449,6 @@ function wc_slm_get_licensing_renewal_period_term($product_id) return !empty($term) ? sanitize_text_field($term) : ''; } -/** - * Check if Licensing is Enabled - * - * @param int $download_id Downloadable product ID. - * @return bool True if licensing is enabled, false otherwise. - */ -function wc_slm_is_licensing_enabled($download_id) -{ - $licensing_enabled = absint(get_post_meta($download_id, '_wc_slm_licensing_enabled', true)); - return $licensing_enabled === 1; -} - -/** - * Insert a Payment Note to Order - * - * @param int $order_id WooCommerce Order ID. - * @param string $msg Note to be added to the order. - * @return void - */ -function wc_insert_payment_note($order_id, $msg) -{ - if (!empty($order_id) && !empty($msg)) { - $order = wc_get_order($order_id); - if ($order) { - $order->add_order_note(esc_html($msg)); - } - } -} - /** * Get Payment Transaction ID * @@ -624,7 +490,8 @@ function slm_order_completed($order_id) // Create the note text if (!empty($order_billing_email)) { $note = sprintf( - __("Order confirmation email sent to: %s", 'slmplus'), + // Translators: %1$s is the mailto link, %2$s is the plain email address + __("Order confirmation email sent to: %2\$s", 'slm-plus'), esc_attr($order_billing_email), esc_html($order_billing_email) ); @@ -653,8 +520,8 @@ function slm_order_details($order) // Check if product is of type 'slm_license' if ($product->is_type('slm_license')) { // Retrieve license keys and types from the order item meta - $lic_keys = wc_get_order_item_meta($item_details->get_id(), '_slm_lic_key', false); - $lic_types = wc_get_order_item_meta($item_details->get_id(), '_slm_lic_type', false); + $lic_keys = wc_get_order_item_meta($item_details->get_id(), 'License Key', false); + $lic_types = wc_get_order_item_meta($item_details->get_id(), 'License Type', false); if ($lic_keys && $lic_types) { $licenses_data = array_map(function ($keys, $types) { @@ -672,12 +539,12 @@ function slm_order_details($order) // Display license details if available if (!empty($licences)) { echo ' -

          ' . esc_html__('License Details', 'slmplus') . '

          +

          ' . esc_html__('License Details', 'slm-plus') . '

          - - + + @@ -687,7 +554,7 @@ function slm_order_details($order)
          ' . esc_html__('License Key', 'slmplus') . '' . esc_html__('Type', 'slmplus') . '' . esc_html__('License Key', 'slm-plus') . '' . esc_html__('Type', 'slm-plus') . '
          ' . esc_html($lic_row['lic_key']) . ' - - ' . esc_html__('View My Licenses', 'slmplus') . ' + ' . esc_html__('View My Licenses', 'slm-plus') . ' ' . esc_html($lic_row['lic_type']) . ' @@ -744,16 +611,16 @@ function slm_add_license_to_order_confirmation($order, $sent_to_admin, $plain_te // If there are licenses, add them to the email if (!empty($licenses)) { - ?> -

          - + ?> +

          +
          @@ -771,6 +638,6 @@ function slm_add_license_to_order_confirmation($order, $sent_to_admin, $plain_te
          - + - +


          - version, '3.0.0', '>=' ) ) { - class WC_Product_SLM_License extends WC_Product_Simple { + if (version_compare(WC()->version, '3.0.0', '>=')) { + class WC_Product_SLM_License extends WC_Product_Simple + { protected $product_type = 'slm_license'; - public function __construct( $product = 0 ) { - parent::__construct( $product ); + public function __construct($product = 0) + { + parent::__construct($product); } - public function get_type() { + public function get_type() + { return 'slm_license'; } } } else { // Older versions use WC_Product as the base class - class WC_Product_SLM_License extends WC_Product { + class WC_Product_SLM_License extends WC_Product + { protected $product_type = 'slm_license'; - public function __construct( $product = 0 ) { - parent::__construct( $product ); + public function __construct($product = 0) + { + parent::__construct($product); } - public function get_type() { + public function get_type() + { return 'slm_license'; } } @@ -38,8 +45,9 @@ function slm_register_product_type() { add_action('init', 'slm_register_product_type'); -function slm_register_product_class($classname, $product_type) { - if ($product_type == 'slm_license') { +function slm_register_product_class($classname, $product_type) +{ + if ($product_type == 'slm_license') { $classname = 'WC_Product_SLM_License'; } return $classname; @@ -47,11 +55,11 @@ function slm_register_product_class($classname, $product_type) { add_filter('woocommerce_product_class', 'slm_register_product_class', 10, 2); -function slm_add_product_type($types) { - $types['slm_license'] = __('License product', 'slmplus'); +function slm_add_product_type($types) +{ + $types['slm_license'] = __('License product', 'slm-plus'); return $types; error_log("Saving product type for Product ID: " . $types); - } add_filter('product_type_selector', 'slm_add_product_type'); @@ -59,15 +67,16 @@ add_filter('product_type_selector', 'slm_add_product_type'); /** * Add 'License Manager' product option. */ -function add_wc_slm_data_tab_enabled_product_option($product_type_options) { +function add_wc_slm_data_tab_enabled_product_option($product_type_options) +{ // Check if the current product type is the custom license product type if (isset($_GET['product_type']) && $_GET['product_type'] === 'slm_license') { $product_type_options['wc_slm_data_tab_enabled'] = array( 'id' => '_wc_slm_data_tab_enabled', 'wrapper_class' => 'show_if_slm_license', - 'label' => __('License Manager', 'slmplus'), + 'label' => __('License Manager', 'slm-plus'), 'default' => 'no', - 'description' => __('Enables the license creation API.', 'slmplus'), + 'description' => __('Enables the license creation API.', 'slm-plus'), 'type' => 'checkbox' ); } @@ -79,8 +88,9 @@ add_filter('product_type_options', 'add_wc_slm_data_tab_enabled_product_option', /** * CSS To Add Custom tab Icon */ -function wcpp_custom_style() { - ?> +function wcpp_custom_style() +{ +?>