&lt;?php /** * Plugin Name: Unity Lease Manager * Plugin URI: https://wavenodes.io/unityapp/ * Description: Manage Unity app lease codes with Google Sheets sync and email automation * Version: 1.0.0 * Author: WaveNodes * License: GPL v2 or later * Text Domain: unity-lease-manager */ // Prevent direct access if (!defined(&#039;ABSPATH&#039;)) { exit; } // Define plugin constants define(&#039;UNITY_PLUGIN_VERSION&#039;, &#039;1.0.0&#039;); define(&#039;UNITY_PLUGIN_PATH&#039;, plugin_dir_path(__FILE__)); define(&#039;UNITY_PLUGIN_URL&#039;, plugin_dir_url(__FILE__)); define(&#039;UNITY_PLUGIN_BASENAME&#039;, plugin_basename(__FILE__)); // Database table name global $wpdb; define(&#039;UNITY_LEASE_TABLE&#039;, $wpdb-&gt;prefix . &#039;unity_lease_codes&#039;); // Required files require_once UNITY_PLUGIN_PATH . &#039;includes/class-database.php&#039;; require_once UNITY_PLUGIN_PATH . &#039;includes/class-google-sheets.php&#039;; require_once UNITY_PLUGIN_PATH . &#039;includes/class-email-handler.php&#039;; require_once UNITY_PLUGIN_PATH . &#039;includes/class-landing-page.php&#039;; require_once UNITY_PLUGIN_PATH . &#039;includes/class-admin.php&#039;; /** * Main plugin class */ class UnityLeaseManager { private static $instance = null; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this-&gt;init_hooks(); } private function init_hooks() { // Activation/deactivation hooks register_activation_hook(__FILE__, array($this, &#039;activate&#039;)); register_deactivation_hook(__FILE__, array($this, &#039;deactivate&#039;)); // Initialize components add_action(&#039;plugins_loaded&#039;, array($this, &#039;init_components&#039;)); // Add shortcode add_shortcode(&#039;unity_landing&#039;, array($this, &#039;landing_page_shortcode&#039;)); // AJAX handlers for frontend add_action(&#039;wp_ajax_unity_request_lease&#039;, array($this, &#039;ajax_request_lease&#039;)); add_action(&#039;wp_ajax_nopriv_unity_request_lease&#039;, array($this, &#039;ajax_request_lease&#039;)); // AJAX handlers for admin add_action(&#039;wp_ajax_unity_export_codes&#039;, array($this, &#039;ajax_export_codes&#039;)); add_action(&#039;wp_ajax_unity_sync_sheets&#039;, array($this, &#039;ajax_sync_sheets&#039;)); add_action(&#039;wp_ajax_unity_pull_sheets&#039;, array($this, &#039;ajax_pull_sheets&#039;)); add_action(&#039;wp_ajax_unity_push_sheets&#039;, array($this, &#039;ajax_push_sheets&#039;)); add_action(&#039;wp_ajax_unity_test_google_connection&#039;, array($this, &#039;ajax_test_google_connection&#039;)); add_action(&#039;wp_ajax_unity_reset_settings&#039;, array($this, &#039;ajax_reset_settings&#039;)); add_action(&#039;wp_ajax_unity_clear_logs&#039;, array($this, &#039;ajax_clear_logs&#039;)); add_action(&#039;wp_ajax_unity_repair_tables&#039;, array($this, &#039;ajax_repair_tables&#039;)); // Test Unity DB access add_action('init', array($this, 'test_unity_db')); } public function activate() { // Create database tables Unity_Database::create_tables(); // Set default options $default_options = array( &#039;email_from&#039; =&gt; &#039;contactunitynodes@gmail.com&#039;, &#039;email_reply_to&#039; =&gt; &#039;contact@wavenodes.io&#039;, &#039;email_bcc&#039; =&gt; &#039;contact@wavenodes.io&#039;, &#039;email_subject&#039; =&gt; &#039;Your Unity App Lease Code&#039;, &#039;gmail_client_id&#039; =&gt; &#039;&#039;, &#039;gmail_client_secret&#039; =&gt; &#039;&#039;, &#039;gmail_refresh_token&#039; =&gt; &#039;&#039;, &#039;google_sheet_id&#039; =&gt; &#039;1vsi3w47p3Eu3h7YUXMxb0jLLir_WmNkrIcI5ywcJHns&#039;, &#039;sync_interval&#039; =&gt; 300, // 5 minutes in seconds &#039;lease_expiry_hours&#039; =&gt; 24, ); foreach ($default_options as $key =&gt; $value) { if (!get_option(&#039;unity_&#039; . $key)) { add_option(&#039;unity_&#039; . $key, $value); } } // Create sync script Unity_Google_Sheets::create_sync_script(); // Schedule cron jobs if (!wp_next_scheduled(&#039;unity_sync_google_sheets&#039;)) { wp_schedule_event(time(), &#039;five_minutes&#039;, &#039;unity_sync_google_sheets&#039;); } } public function deactivate() { // Remove cron jobs wp_clear_scheduled_hook(&#039;unity_sync_google_sheets&#039;); } public function init_components() { // Initialize components if needed if (is_admin()) { new Unity_Admin(); } // Add custom cron interval add_filter(&#039;cron_schedules&#039;, array($this, &#039;add_cron_intervals&#039;)); // Hook sync function to cron add_action(&#039;unity_sync_google_sheets&#039;, array($this, &#039;sync_google_sheets&#039;)); } public function add_cron_intervals($schedules) { $schedules[&#039;five_minutes&#039;] = array( &#039;interval&#039; =&gt; 300, &#039;display&#039; =&gt; __(&#039;Every 5 minutes&#039;) ); return $schedules; } public function sync_google_sheets() { // Trigger Google Sheets sync Unity_Google_Sheets::sync(); // Update last sync time update_option(&#039;unity_last_sync&#039;, current_time(&#039;mysql&#039;)); } public function landing_page_shortcode($atts) { return Unity_Landing_Page::render($atts); } /** * AJAX handler: Request lease code */ public function ajax_request_lease() { check_ajax_referer(&#039;unity_request_nonce&#039;, &#039;security&#039;); $email = sanitize_email($_POST[&#039;email&#039;] ?? &#039;&#039;); $reference = intval($_POST[&#039;reference&#039;] ?? 0); $ambassador = sanitize_text_field($_POST[&#039;ambassador&#039;] ?? &#039;&#039;); $user_ip = $_SERVER[&#039;REMOTE_ADDR&#039;] ?? &#039;&#039;; if (!is_email($email)) { wp_send_json_error(array(&#039;message&#039; =&gt; __(&#039;Please enter a valid email address.&#039;, &#039;unity-lease-manager&#039;))); } // Process request $result = Unity_Database::assign_lease_code($email, $reference, $ambassador, $user_ip); if ($result[&#039;success&#039;]) { // Send email $email_sent = Unity_Email_Handler::send_lease_email( $email, $result[&#039;lease_code&#039;], $result[&#039;reference&#039;] ?? $reference, $ambassador, $user_ip ); if ($email_sent) { wp_send_json_success(array( &#039;message&#039; =&gt; __(&#039;Check your e-mail inbox or spam folder for installation instructions.&#039;, &#039;unity-lease-manager&#039;), &#039;lease_code&#039; =&gt; $result[&#039;lease_code&#039;] )); } else { wp_send_json_error(array( &#039;message&#039; =&gt; __(&#039;Lease code assigned but email failed to send. Please contact support.&#039;, &#039;unity-lease-manager&#039;) )); } } else { wp_send_json_error(array(&#039;message&#039; =&gt; $result[&#039;message&#039;])); } } /** * AJAX handler: Export lease codes */ public function ajax_export_codes() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_die(&#039;Unauthorized&#039;); } global $wpdb; $table_name = UNITY_LEASE_TABLE; $codes = $wpdb-&gt;get_results(&quot;SELECT * FROM $table_name ORDER BY id&quot;, ARRAY_A); if (empty($codes)) { wp_die(&#039;No lease codes to export.&#039;); } // Set headers for CSV download header(&#039;Content-Type: text/csv&#039;); header(&#039;Content-Disposition: attachment; filename=&quot;unity-lease-codes-&#039; . date(&#039;Y-m-d&#039;) . &#039;.csv&quot;&#039;); $output = fopen(&#039;php://output&#039;, &#039;w&#039;); // Write header fputcsv($output, array_keys($codes[0])); // Write data foreach ($codes as $code) { fputcsv($output, $code); } fclose($output); exit; } /** * AJAX handler: Sync with Google Sheets */ public function ajax_sync_sheets() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } $result = Unity_Google_Sheets::sync(); wp_send_json($result); } /** * AJAX handler: Pull from Google Sheets */ public function ajax_pull_sheets() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } $result = Unity_Google_Sheets::pull(); wp_send_json($result); } /** * AJAX handler: Push to Google Sheets */ public function ajax_push_sheets() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } $result = Unity_Google_Sheets::push(); wp_send_json($result); } /** * AJAX handler: Test Google connection */ public function ajax_test_google_connection() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } $result = Unity_Google_Sheets::test_connection(); wp_send_json($result); } /** * AJAX handler: Reset settings */ public function ajax_reset_settings() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } // Define default options $default_options = array( &#039;email_from&#039; =&gt; &#039;contactunitynodes@gmail.com&#039;, &#039;email_reply_to&#039; =&gt; &#039;contact@wavenodes.io&#039;, &#039;email_bcc&#039; =&gt; &#039;contact@wavenodes.io&#039;, &#039;email_subject&#039; =&gt; &#039;Your Unity App Lease Code&#039;, &#039;google_sheet_id&#039; =&gt; &#039;1vsi3w47p3Eu3h7YUXMxb0jLLir_WmNkrIcI5ywcJHns&#039;, &#039;sync_interval&#039; =&gt; 300, &#039;lease_expiry_hours&#039; =&gt; 24, ); // Reset each option foreach ($default_options as $key =&gt; $value) { update_option(&#039;unity_&#039; . $key, $value); } wp_send_json_success(array(&#039;message&#039; =&gt; &#039;Settings reset to defaults.&#039;)); } /** * AJAX handler: Clear logs */ public function ajax_clear_logs() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } global $wpdb; $logs_table = $wpdb-&gt;prefix . &#039;unity_logs&#039;; $wpdb-&gt;query(&quot;TRUNCATE TABLE $logs_table&quot;); wp_send_json_success(array(&#039;message&#039; =&gt; &#039;Logs cleared.&#039;)); } /** * AJAX handler: Repair tables */ public function ajax_repair_tables() { check_ajax_referer(&#039;unity_admin_nonce&#039;, &#039;nonce&#039;); if (!current_user_can(&#039;manage_options&#039;)) { wp_send_json_error(array(&#039;message&#039; =&gt; &#039;Unauthorized&#039;)); } // Repair lease codes table Unity_Database::create_tables(); wp_send_json_success(array(&#039;message&#039; =&gt; &#039;Tables repaired.&#039;)); } /** * Test database access for Unity database */ public function test_unity_db() { if (!current_user_can("manage_options") || !isset($_GET["test_unity_db"])) { return; } global $wpdb; // Try to connect to Unity database $unity_db = new wpdb(DB_USER, DB_PASSWORD, "Unity", DB_HOST); if ($unity_db->error) { echo "<pre>Connection error: " . esc_html($unity_db->error) . "</pre>"; return; } // List tables $tables = $unity_db->get_results("SHOW TABLES"); echo "<pre>Tables in Unity database:\n"; foreach ($tables as $table) { $table_name = array_values((array)$table)[0]; echo "- " . esc_html($table_name) . "\n"; } echo "</pre>"; // Create test table $unity_db->query("CREATE TABLE IF NOT EXISTS unity_test (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(100))"); $unity_db->insert("unity_test", array("data" => "test entry")); $id = $unity_db->insert_id; echo "<pre>Inserted record ID: " . esc_html($id) . "</pre>"; $row = $unity_db->get_row("SELECT * FROM unity_test WHERE id = $id"); echo "<pre>Retrieved: " . esc_html(print_r($row, true)) . "</pre>"; $unity_db->query("DROP TABLE unity_test"); echo "<pre>Test table cleaned up.</pre>"; exit; } } // Initialize plugin function unity_lease_manager_init() { return UnityLeaseManager::get_instance(); } add_action(&#039;plugins_loaded&#039;, &#039;unity_lease_manager_init&#039;); https://wavenodes.io/wp-sitemap-posts-page-1.xml