Unity Nodes
Unity lets your phone take part in a global edge network. The app performs telecom tasks such as measuring internet quality. That can let you earn extra income.
<?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('ABSPATH')) { exit; } // Define plugin constants define('UNITY_PLUGIN_VERSION', '1.0.0'); define('UNITY_PLUGIN_PATH', plugin_dir_path(__FILE__)); define('UNITY_PLUGIN_URL', plugin_dir_url(__FILE__)); define('UNITY_PLUGIN_BASENAME', plugin_basename(__FILE__)); // Database table name global $wpdb; define('UNITY_LEASE_TABLE', $wpdb->prefix . 'unity_lease_codes'); // Required files require_once UNITY_PLUGIN_PATH . 'includes/class-database.php'; require_once UNITY_PLUGIN_PATH . 'includes/class-google-sheets.php'; require_once UNITY_PLUGIN_PATH . 'includes/class-email-handler.php'; require_once UNITY_PLUGIN_PATH . 'includes/class-landing-page.php'; require_once UNITY_PLUGIN_PATH . 'includes/class-admin.php'; /** * 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->init_hooks(); } private function init_hooks() { // Activation/deactivation hooks register_activation_hook(__FILE__, array($this, 'activate')); register_deactivation_hook(__FILE__, array($this, 'deactivate')); // Initialize components add_action('plugins_loaded', array($this, 'init_components')); // Add shortcode add_shortcode('unity_landing', array($this, 'landing_page_shortcode')); // AJAX handlers for frontend add_action('wp_ajax_unity_request_lease', array($this, 'ajax_request_lease')); add_action('wp_ajax_nopriv_unity_request_lease', array($this, 'ajax_request_lease')); // AJAX handlers for admin add_action('wp_ajax_unity_export_codes', array($this, 'ajax_export_codes')); add_action('wp_ajax_unity_sync_sheets', array($this, 'ajax_sync_sheets')); add_action('wp_ajax_unity_pull_sheets', array($this, 'ajax_pull_sheets')); add_action('wp_ajax_unity_push_sheets', array($this, 'ajax_push_sheets')); add_action('wp_ajax_unity_test_google_connection', array($this, 'ajax_test_google_connection')); add_action('wp_ajax_unity_reset_settings', array($this, 'ajax_reset_settings')); add_action('wp_ajax_unity_clear_logs', array($this, 'ajax_clear_logs')); add_action('wp_ajax_unity_repair_tables', array($this, 'ajax_repair_tables')); // 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( 'email_from' => 'contactunitynodes@gmail.com', 'email_reply_to' => 'contact@wavenodes.io', 'email_bcc' => 'contact@wavenodes.io', 'email_subject' => 'Your Unity App Lease Code', 'gmail_client_id' => '', 'gmail_client_secret' => '', 'gmail_refresh_token' => '', 'google_sheet_id' => '1vsi3w47p3Eu3h7YUXMxb0jLLir_WmNkrIcI5ywcJHns', 'sync_interval' => 300, // 5 minutes in seconds 'lease_expiry_hours' => 24, ); foreach ($default_options as $key => $value) { if (!get_option('unity_' . $key)) { add_option('unity_' . $key, $value); } } // Create sync script Unity_Google_Sheets::create_sync_script(); // Schedule cron jobs if (!wp_next_scheduled('unity_sync_google_sheets')) { wp_schedule_event(time(), 'five_minutes', 'unity_sync_google_sheets'); } } public function deactivate() { // Remove cron jobs wp_clear_scheduled_hook('unity_sync_google_sheets'); } public function init_components() { // Initialize components if needed if (is_admin()) { new Unity_Admin(); } // Add custom cron interval add_filter('cron_schedules', array($this, 'add_cron_intervals')); // Hook sync function to cron add_action('unity_sync_google_sheets', array($this, 'sync_google_sheets')); } public function add_cron_intervals($schedules) { $schedules['five_minutes'] = array( 'interval' => 300, 'display' => __('Every 5 minutes') ); return $schedules; } public function sync_google_sheets() { // Trigger Google Sheets sync Unity_Google_Sheets::sync(); // Update last sync time update_option('unity_last_sync', current_time('mysql')); } 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('unity_request_nonce', 'security'); $email = sanitize_email($_POST['email'] ?? ''); $reference = intval($_POST['reference'] ?? 0); $ambassador = sanitize_text_field($_POST['ambassador'] ?? ''); $user_ip = $_SERVER['REMOTE_ADDR'] ?? ''; if (!is_email($email)) { wp_send_json_error(array('message' => __('Please enter a valid email address.', 'unity-lease-manager'))); } // Process request $result = Unity_Database::assign_lease_code($email, $reference, $ambassador, $user_ip); if ($result['success']) { // Send email $email_sent = Unity_Email_Handler::send_lease_email( $email, $result['lease_code'], $result['reference'] ?? $reference, $ambassador, $user_ip ); if ($email_sent) { wp_send_json_success(array( 'message' => __('Check your e-mail inbox or spam folder for installation instructions.', 'unity-lease-manager'), 'lease_code' => $result['lease_code'] )); } else { wp_send_json_error(array( 'message' => __('Lease code assigned but email failed to send. Please contact support.', 'unity-lease-manager') )); } } else { wp_send_json_error(array('message' => $result['message'])); } } /** * AJAX handler: Export lease codes */ public function ajax_export_codes() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_die('Unauthorized'); } global $wpdb; $table_name = UNITY_LEASE_TABLE; $codes = $wpdb->get_results("SELECT * FROM $table_name ORDER BY id", ARRAY_A); if (empty($codes)) { wp_die('No lease codes to export.'); } // Set headers for CSV download header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename="unity-lease-codes-' . date('Y-m-d') . '.csv"'); $output = fopen('php://output', 'w'); // 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('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } $result = Unity_Google_Sheets::sync(); wp_send_json($result); } /** * AJAX handler: Pull from Google Sheets */ public function ajax_pull_sheets() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } $result = Unity_Google_Sheets::pull(); wp_send_json($result); } /** * AJAX handler: Push to Google Sheets */ public function ajax_push_sheets() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } $result = Unity_Google_Sheets::push(); wp_send_json($result); } /** * AJAX handler: Test Google connection */ public function ajax_test_google_connection() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } $result = Unity_Google_Sheets::test_connection(); wp_send_json($result); } /** * AJAX handler: Reset settings */ public function ajax_reset_settings() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } // Define default options $default_options = array( 'email_from' => 'contactunitynodes@gmail.com', 'email_reply_to' => 'contact@wavenodes.io', 'email_bcc' => 'contact@wavenodes.io', 'email_subject' => 'Your Unity App Lease Code', 'google_sheet_id' => '1vsi3w47p3Eu3h7YUXMxb0jLLir_WmNkrIcI5ywcJHns', 'sync_interval' => 300, 'lease_expiry_hours' => 24, ); // Reset each option foreach ($default_options as $key => $value) { update_option('unity_' . $key, $value); } wp_send_json_success(array('message' => 'Settings reset to defaults.')); } /** * AJAX handler: Clear logs */ public function ajax_clear_logs() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } global $wpdb; $logs_table = $wpdb->prefix . 'unity_logs'; $wpdb->query("TRUNCATE TABLE $logs_table"); wp_send_json_success(array('message' => 'Logs cleared.')); } /** * AJAX handler: Repair tables */ public function ajax_repair_tables() { check_ajax_referer('unity_admin_nonce', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(array('message' => 'Unauthorized')); } // Repair lease codes table Unity_Database::create_tables(); wp_send_json_success(array('message' => 'Tables repaired.')); } /** * 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('plugins_loaded', 'unity_lease_manager_init'); <!DOCTYPE html> <html <?php language_attributes(); ?>> <head> <meta charset="<?php bloginfo( 'charset' ); ?>" /> <?php elegant_description(); elegant_keywords(); elegant_canonical(); /** * Fires in the head, before {@see wp_head()} is called. This action can be used to * insert elements into the beginning of the head before any styles or scripts. * * @since 1.0 */ do_action( 'et_head_meta' ); $template_directory_uri = get_template_directory_uri(); ?> <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" /> <script type="text/javascript"> document.documentElement.className = 'js'; </script> <?php wp_head(); ?> </head> <body <?php body_class(); ?>> <?php wp_body_open(); $product_tour_enabled = et_builder_is_product_tour_enabled(); $page_container_style = $product_tour_enabled ? ' style="padding-top: 0px;"' : ''; ?> <div id="page-container"<?php echo et_core_intentionally_unescaped( $page_container_style, 'fixed_string' ); ?>> <?php if ( $product_tour_enabled || is_page_template( 'page-template-blank.php' ) ) { return; } $et_secondary_nav_items = et_divi_get_top_nav_items(); $et_phone_number = $et_secondary_nav_items->phone_number; $et_email = $et_secondary_nav_items->email; $et_contact_info_defined = $et_secondary_nav_items->contact_info_defined; $show_header_social_icons = $et_secondary_nav_items->show_header_social_icons; $et_secondary_nav = $et_secondary_nav_items->secondary_nav; $et_top_info_defined = $et_secondary_nav_items->top_info_defined; $et_slide_header = 'slide' === et_get_option( 'header_style', 'left' ) || 'fullscreen' === et_get_option( 'header_style', 'left' ) ? true : false; $show_search_icon = ( false !== et_get_option( 'show_search_icon', true ) && ! $et_slide_header ) || is_customize_preview(); ?> <?php if ( $et_top_info_defined && ! $et_slide_header || is_customize_preview() ) : ?> <?php ob_start(); ?> <div id="top-header"<?php echo $et_top_info_defined ? '' : 'style="display: none;"'; ?>> <div class="container clearfix"> <?php if ( $et_contact_info_defined ) : ?> <div id="et-info"> <?php if ( ! empty( $et_phone_number = et_get_option( 'phone_number' ) ) ) : ?> <span id="et-info-phone"><?php echo et_core_esc_previously( et_sanitize_html_input_text( strval( $et_phone_number ) ) ); ?></span> <?php endif; ?> <?php if ( ! empty( $et_email = et_get_option( 'header_email' ) ) ) : ?> <a href="<?php echo esc_attr( 'mailto:' . $et_email ); ?>"><span id="et-info-email"><?php echo esc_html( $et_email ); ?></span></a> <?php endif; ?> <?php if ( true === $show_header_social_icons ) { get_template_part( 'includes/social_icons', 'header' ); } ?> </div> <?php endif; // true === $et_contact_info_defined ?> <div id="et-secondary-menu"> <?php if ( ! $et_contact_info_defined && true === $show_header_social_icons ) { get_template_part( 'includes/social_icons', 'header' ); } else if ( $et_contact_info_defined && true === $show_header_social_icons ) { ob_start(); get_template_part( 'includes/social_icons', 'header' ); $duplicate_social_icons = ob_get_contents(); ob_end_clean(); printf( '<div class="et_duplicate_social_icons"> %1$s </div>', et_core_esc_previously( $duplicate_social_icons ) ); } if ( '' !== $et_secondary_nav ) { echo et_core_esc_wp( $et_secondary_nav ); } et_show_cart_total(); ?> </div> </div> </div> <?php $top_header = ob_get_clean(); /** * Filters the HTML output for the top header. * * @since 3.10 * * @param string $top_header */ echo et_core_intentionally_unescaped( apply_filters( 'et_html_top_header', $top_header ), 'html' ); ?> <?php endif; // true ==== $et_top_info_defined ?> <?php if ( $et_slide_header || is_customize_preview() ) : ?> <?php ob_start(); ?> <div class="et_slide_in_menu_container"> <?php if ( 'fullscreen' === et_get_option( 'header_style', 'left' ) || is_customize_preview() ) { ?> <span class="mobile_menu_bar et_toggle_fullscreen_menu"></span> <?php } ?> <?php if ( $et_contact_info_defined || true === $show_header_social_icons || false !== et_get_option( 'show_search_icon', true ) || class_exists( 'woocommerce' ) || is_customize_preview() ) { ?> <div class="et_slide_menu_top"> <?php if ( 'fullscreen' === et_get_option( 'header_style', 'left' ) ) { ?> <div class="et_pb_top_menu_inner"> <?php } ?> <?php } if ( true === $show_header_social_icons ) { get_template_part( 'includes/social_icons', 'header' ); } et_show_cart_total(); ?> <?php if ( false !== et_get_option( 'show_search_icon', true ) || is_customize_preview() ) : ?> <?php if ( 'fullscreen' !== et_get_option( 'header_style', 'left' ) ) { ?> <div class="clear"></div> <?php } ?> <form role="search" method="get" class="et-search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>"> <?php printf( '<input type="search" class="et-search-field" placeholder="%1$s" value="%2$s" name="s" title="%3$s" />', esc_attr__( 'Search …', 'Divi' ), get_search_query(), esc_attr__( 'Search for:', 'Divi' ) ); /** * Fires inside the search form element, just before its closing tag. * * @since ?? */ do_action( 'et_search_form_fields' ); ?> <button type="submit" id="searchsubmit_header"></button> </form> <?php endif; // true === et_get_option( 'show_search_icon', false ) ?> <?php if ( $et_contact_info_defined ) : ?> <div id="et-info"> <?php if ( ! empty( $et_phone_number = et_get_option( 'phone_number' ) ) ) : ?> <span id="et-info-phone"><?php echo et_core_esc_previously( et_sanitize_html_input_text( strval( $et_phone_number ) ) ); ?></span> <?php endif; ?> <?php if ( ! empty( $et_email = et_get_option( 'header_email' ) ) ) : ?> <a href="<?php echo esc_attr( 'mailto:' . $et_email ); ?>"><span id="et-info-email"><?php echo esc_html( $et_email ); ?></span></a> <?php endif; ?> </div> <?php endif; // true === $et_contact_info_defined ?> <?php if ( $et_contact_info_defined || true === $show_header_social_icons || false !== et_get_option( 'show_search_icon', true ) || class_exists( 'woocommerce' ) || is_customize_preview() ) { ?> <?php if ( 'fullscreen' === et_get_option( 'header_style', 'left' ) ) { ?> </div> <?php } ?> </div> <?php } ?> <div class="et_pb_fullscreen_nav_container"> <?php $slide_nav = ''; $slide_menu_class = 'et_mobile_menu'; $slide_nav = wp_nav_menu( array( 'theme_location' => 'primary-menu', 'container' => '', 'fallback_cb' => '', 'echo' => false, 'items_wrap' => '%3$s' ) ); $slide_nav .= wp_nav_menu( array( 'theme_location' => 'secondary-menu', 'container' => '', 'fallback_cb' => '', 'echo' => false, 'items_wrap' => '%3$s' ) ); ?> <ul id="mobile_menu_slide" class="<?php echo esc_attr( $slide_menu_class ); ?>"> <?php if ( '' === $slide_nav ) : ?> <?php if ( 'on' === et_get_option( 'divi_home_link' ) ) { ?> <li <?php if ( is_home() ) echo( 'class="current_page_item"' ); ?>><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Home', 'Divi' ); ?></a></li> <?php }; ?> <?php show_page_menu( $slide_menu_class, false, false ); ?> <?php show_categories_menu( $slide_menu_class, false ); ?> <?php else : echo et_core_esc_wp( $slide_nav ) ; endif; ?> </ul> </div> </div> <?php $slide_header = ob_get_clean(); /** * Filters the HTML output for the slide header. * * @since 3.10 * * @param string $top_header */ echo et_core_intentionally_unescaped( apply_filters( 'et_html_slide_header', $slide_header ), 'html' ); ?> <?php endif; // true ==== $et_slide_header ?> <?php ob_start(); ?> <header id="main-header" data-height-onload="<?php echo esc_attr( et_get_option( 'menu_height', '66' ) ); ?>"> <div class="container clearfix et_menu_container"> <?php $logo = ( $user_logo = et_get_option( 'divi_logo' ) ) && ! empty( $user_logo ) ? $user_logo : $template_directory_uri . '/images/logo.png'; // Get logo image size based on attachment URL. $logo_size = et_get_attachment_size_by_url( $logo ); $logo_width = ( ! empty( $logo_size ) && is_numeric( $logo_size[0] ) ) ? $logo_size[0] : '93'; // 93 is the width of the default logo. $logo_height = ( ! empty( $logo_size ) && is_numeric( $logo_size[1] ) ) ? $logo_size[1] : '43'; // 43 is the height of the default logo. ob_start(); ?> <div class="logo_container"> <span class="logo_helper"></span> <a href="<?php echo esc_url( home_url( '/' ) ); ?>"> <img src="<?php echo esc_attr( $logo ); ?>" width="<?php echo esc_attr( $logo_width ); ?>" height="<?php echo esc_attr( $logo_height ); ?>" alt="<?php echo esc_attr( get_bloginfo( 'name' ) ); ?>" id="logo" data-height-percentage="<?php echo esc_attr( et_get_option( 'logo_height', '54' ) ); ?>" /> </a> </div> <?php $logo_container = ob_get_clean(); /** * Filters the HTML output for the logo container. * * @since 3.10 * * @param string $logo_container */ echo et_core_intentionally_unescaped( apply_filters( 'et_html_logo_container', $logo_container ), 'html' ); ?> <div id="et-top-navigation" data-height="<?php echo esc_attr( et_get_option( 'menu_height', '66' ) ); ?>" data-fixed-height="<?php echo esc_attr( et_get_option( 'minimized_menu_height', '40' ) ); ?>"> <?php if ( ! $et_slide_header || is_customize_preview() ) : ?> <nav id="top-menu-nav"> <?php $menuClass = 'nav'; if ( 'on' === et_get_option( 'divi_disable_toptier' ) ) $menuClass .= ' et_disable_top_tier'; $primaryNav = ''; $primaryNav = wp_nav_menu( array( 'theme_location' => 'primary-menu', 'container' => '', 'fallback_cb' => '', 'menu_class' => $menuClass, 'menu_id' => 'top-menu', 'echo' => false ) ); if ( empty( $primaryNav ) ) : ?> <ul id="top-menu" class="<?php echo esc_attr( $menuClass ); ?>"> <?php if ( 'on' === et_get_option( 'divi_home_link' ) ) { ?> <li <?php if ( is_home() ) echo( 'class="current_page_item"' ); ?>><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php esc_html_e( 'Home', 'Divi' ); ?></a></li> <?php }; ?> <?php show_page_menu( $menuClass, false, false ); ?> <?php show_categories_menu( $menuClass, false ); ?> </ul> <?php else : echo et_core_esc_wp( $primaryNav ); endif; ?> </nav> <?php endif; ?> <?php if ( ! $et_top_info_defined && ( ! $et_slide_header || is_customize_preview() ) ) { et_show_cart_total( array( 'no_text' => true, ) ); } ?> <?php if ( $et_slide_header || is_customize_preview() ) : ?> <span class="mobile_menu_bar et_pb_header_toggle et_toggle_<?php echo esc_attr( et_get_option( 'header_style', 'left' ) ); ?>_menu"></span> <?php endif; ?> <?php if ( $show_search_icon ) : ?> <div id="et_top_search"> <span id="et_search_icon"></span> </div> <?php endif; ?> <?php /** * Fires at the end of the 'et-top-navigation' element, just before its closing tag. * * @since 1.0 */ do_action( 'et_header_top' ); ?> </div> <!-- #et-top-navigation --> </div> <!-- .container --> <?php if ( $show_search_icon ) : ?> <div class="et_search_outer"> <div class="container et_search_form_container"> <form role="search" method="get" class="et-search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>"> <?php printf( '<input type="search" class="et-search-field" placeholder="%1$s" value="%2$s" name="s" title="%3$s" />', esc_attr__( 'Search …', 'Divi' ), get_search_query(), esc_attr__( 'Search for:', 'Divi' ) ); /** * Fires inside the search form element, just before its closing tag. * * @since ?? */ do_action( 'et_search_form_fields' ); ?> </form> <span class="et_close_search_field"></span> </div> </div> <?php endif; ?> </header> <!-- #main-header --> <?php $main_header = ob_get_clean(); /** * Filters the HTML output for the main header. * * @since 3.10 * * @param string $main_header */ echo et_core_intentionally_unescaped( apply_filters( 'et_html_main_header', $main_header ), 'html' ); ?> <div id="et-main-area"> <?php /** * Fires after the header, before the main content is output. * * @since 3.10 */ do_action( 'et_before_main_content' );
Unity lets your phone take part in a global edge network. The app performs telecom tasks such as measuring internet quality. That can let you earn extra income.