init(); } return self::$instance; } /** * Initializes hooks and setup environment variables. * * @since 0.1.0 * @static */ public static function init() { $instance = self::instance(); // Load textdomain. add_action( 'init', array( $instance, 'load_textdomain' ) ); // Build our tools page. add_action( 'admin_menu', array( $instance, 'create_menu' ) ); // Load our JavaScript. add_action( 'admin_enqueue_scripts', array( $instance, 'admin_enqueue' ) ); // The action to run the compatibility test. add_action( 'wp_ajax_wpephpcompat_start_test', array( $instance, 'start_test' ) ); add_action( 'wp_ajax_wpephpcompat_check_status', array( $instance, 'check_status' ) ); add_action( 'wpephpcompat_start_test_cron', array( $instance, 'start_test' ) ); add_action( 'wp_ajax_wpephpcompat_clean_up', array( $instance, 'clean_up' ) ); // Create custom post type. add_action( 'init', array( $instance, 'create_job_queue' ) ); // Handle activation notice. register_activation_hook( __FILE__, array( $instance, 'set_activation_notice_flag' ) ); add_action( 'admin_notices', array( $instance, 'maybe_show_activation_notice' ) ); // Add plugin action link. add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $instance, 'filter_plugin_links' ) ); } /** * Returns an array of available PHP versions to test. * * @since 1.0.0 * * @return array Associative array of available PHP versions. */ function get_phpversions() { $versions = array( 'PHP 7.2' => '7.2', 'PHP 7.1' => '7.1', 'PHP 7.0' => '7.0', ); if ( version_compare( phpversion(), '5.3', '>=' ) ) { $versions = array( 'PHP 7.3' => '7.3' ) + $versions; } $old_versions = array( '5.6', '5.5', '5.4', '5.3' ); while ( ! empty( $old_versions ) ) { $oldest = array_pop( $old_versions ); if ( version_compare( phpversion(), $oldest, '<' ) ) { array_push( $old_versions, $oldest ); foreach ( $old_versions as $old_version ) { $old_version_label = "PHP {$old_version}"; $versions[ $old_version_label ] = $old_version; } break; } } return apply_filters( 'phpcompat_phpversions', $versions ); } /** * Starts the test. * * @since 1.0.0 * * @action wp_ajax_wpephpcompat_start_test * @action wpephpcompat_start_test_cron */ public function start_test() { if ( current_user_can( WPEPHPCOMPAT_CAPABILITY ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) { global $wpdb; $wpephpc = new WPEPHPCompat( dirname( __FILE__ ) ); $test_data = array(); foreach ( array( 'test_version', 'only_active' ) as $key ) { if ( isset( $_POST[ $key ] ) ) { $test_data[ $key ] = sanitize_text_field( $_POST[ $key ] ); } } // New scan! if ( isset( $_POST['startScan'] ) ) { // Make sure we clean up after the last test. $wpephpc->clean_after_scan(); // Fork so we can close the connection. $this->fork_scan( $test_data['test_version'], $test_data['only_active'] ); } else { if ( isset( $test_data['test_version'] ) ) { $wpephpc->test_version = $test_data['test_version']; } if ( isset( $test_data['only_active'] ) ) { $wpephpc->only_active = $test_data['only_active']; } $wpephpc->start_test(); } wp_die(); } } /** * Checks the progress or result of the tests. * * @todo Use heartbeat API. * @since 1.0.0 * * @action wp_ajax_wpephpcompat_check_status */ public function check_status() { if ( current_user_can( WPEPHPCOMPAT_CAPABILITY ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) { $scan_status = get_option( 'wpephpcompat.status' ); $count_jobs = wp_count_posts( 'wpephpcompat_jobs' ); $total_jobs = get_option( 'wpephpcompat.numdirs' ); $test_version = get_option( 'wpephpcompat.test_version' ); $only_active = get_option( 'wpephpcompat.only_active' ); $active_job = false; $jobs = get_posts( array( 'posts_per_page' => -1, 'post_type' => 'wpephpcompat_jobs', 'orderby' => 'title', 'order' => 'ASC', ) ); if ( 0 < count( $jobs ) ) { $active_job = $jobs[0]->post_title; } $to_encode = array( 'status' => $scan_status, 'count' => $count_jobs->publish, 'total' => $total_jobs, 'activeJob' => $active_job, 'version' => $test_version, 'onlyActive' => $only_active, ); // If the scan is still running. if ( $scan_status ) { $to_encode['results'] = '0'; $to_encode['progress'] = ( ( $total_jobs - $count_jobs->publish ) / $total_jobs ) * 100; } else { // Else return the results and clean up! $scan_results = get_option( 'wpephpcompat.scan_results' ); // Not using esc_html since the results are shown in a textarea. $to_encode['results'] = $scan_results; $wpephpc = new WPEPHPCompat( dirname( __FILE__ ) ); $wpephpc->clean_after_scan(); } wp_send_json( $to_encode ); } } /** * Makes an Ajax call to start the scan in the background. * * @since 1.3.2 * * @param string $test_version Version of PHP to test. * @param string $only_active Whether to scan only active plugins or all. */ public function fork_scan( $test_version, $only_active ) { $query = array( 'action' => 'wpephpcompat_start_test', ); // Keep track of these variables. $body = array( 'test_version' => $test_version, 'only_active' => $only_active, ); // Instantly return! $args = array( 'timeout' => 0.01, 'blocking' => false, 'body' => $body, 'cookies' => $_COOKIE, 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), ); // Build our URL. $url = add_query_arg( $query, admin_url( 'admin-ajax.php' ) ); /** * Modify the URL used to fork a request. * * When running in a Docker container the url used to access the site internally * can be different from the external url. For example internally the port * is 80, and externally it's 8081. * * @since 1.4.6 * * @param string $url The url used to make the fork request. */ $url = apply_filters( 'phpcompat_fork_url', $url ); // POST. wp_remote_post( esc_url_raw( $url ), $args ); } /** * Removes all database options from the database. * * @since 1.3.2 * * @action wp_ajax_wpephpcompat_clean_up */ public function clean_up() { if ( current_user_can( WPEPHPCOMPAT_CAPABILITY ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) { $wpephpc = new WPEPHPCompat( dirname( __FILE__ ) ); $wpephpc->clean_after_scan(); delete_option( 'wpephpcompat.scan_results' ); wp_send_json( 'success' ); } } /** * Creates custom post type to store the directories we need to process. * * @since 1.0.0 */ public function create_job_queue() { register_post_type( 'wpephpcompat_jobs', array( 'labels' => array( 'name' => __( 'Jobs', 'php-compatibility-checker' ), 'singular_name' => __( 'Job', 'php-compatibility-checker' ), ), 'public' => false, 'has_archive' => false, ) ); } /** * Loads textdomain for WP < 4.6 translation support. * * @since 1.4.7 * * @action admin_init */ public function load_textdomain() { load_plugin_textdomain( 'php-compatibility-checker' ); } /** * Enqueues our JavaScript and CSS. * * @since 1.0.0 * * @action admin_enqueue_scripts * * @param string $hook Current page hook name. */ public function admin_enqueue( $hook ) { // Only enqueue these assets on the settings page. if ( $this->page !== $hook ) { return; } // Grab the plugin version. $plugin_data = get_plugin_data( __FILE__, false, false ); if ( isset( $plugin_data['Version'] ) ) { $version = $plugin_data['Version']; } // Styles. wp_enqueue_style( 'wpephpcompat-style', plugins_url( '/src/css/style.css', __FILE__ ), array(), $version ); // Scripts. wp_enqueue_script( 'wpephpcompat-handlebars', plugins_url( '/src/js/handlebars.js', __FILE__ ), array( 'jquery' ), $version ); wp_enqueue_script( 'wpephpcompat-download', plugins_url( '/src/js/download.min.js', __FILE__ ), array(), $version ); wp_enqueue_script( 'wpephpcompat', plugins_url( '/src/js/run.js', __FILE__ ), array( 'jquery', 'wpephpcompat-handlebars', 'wpephpcompat-download' ), $version ); /** * Strings for i18n. * * These translated strings can be access in jquery with window.wpephpcompat object. */ $strings = array( 'name' => __( 'Name', 'php-compatibility-checker' ), 'compatible' => __( 'compatible', 'php-compatibility-checker' ), 'are_not' => __( 'plugins/themes may not be compatible', 'php-compatibility-checker' ), 'is_not' => __( 'Your WordPress site is possibly not PHP', 'php-compatibility-checker' ), 'out_of' => __( 'out of', 'php-compatibility-checker' ), 'run' => __( 'Scan site', 'php-compatibility-checker' ), 'rerun' => __( 'Scan site again', 'php-compatibility-checker' ), 'your_wp' => __( 'Your WordPress site is', 'php-compatibility-checker' ), ); wp_localize_script( 'wpephpcompat', 'wpephpcompat', $strings ); } /** * Add the settings page to the wp-admin menu. * * @since 1.0.0 * * @action admin_menu */ public function create_menu() { // Create Tools sub-menu. $this->page = add_submenu_page( 'tools.php', __( 'PHP Compatibility', 'php-compatibility-checker' ), __( 'PHP Compatibility', 'php-compatibility-checker' ), WPEPHPCOMPAT_CAPABILITY, WPEPHPCOMPAT_ADMIN_PAGE_SLUG, array( self::instance(), 'settings_page' ) ); } /** * Render method for the settings page. * * @since 1.0.0 */ public function settings_page() { // Discover last options used. $test_version = get_option( 'wpephpcompat.test_version' ); $only_active = get_option( 'wpephpcompat.only_active' ); // Determine if current site is a WP Engine customer. $is_wpe_customer = ! empty( $_SERVER['IS_WPE'] ) && $_SERVER['IS_WPE']; $phpversions = $this->get_phpversions(); // Assigns defaults for the scan if none are found in the database. $test_version = ( ! empty( $test_version ) ) ? $test_version : '7.0'; $only_active = ( ! empty( $only_active ) ) ? $only_active : 'yes'; // Content variables. $url_get_hosting = esc_url( 'https://wpeng.in/5a0336/' ); $url_wpe_agency_partners = esc_url( 'https://wpeng.in/fa14e4/' ); $url_wpe_customer_upgrade = esc_url( 'https://wpeng.in/407b79/' ); $url_wpe_logo = esc_url( 'https://wpeng.in/22f22b/' ); $url_codeable_submit = esc_url( 'https://codeable.io/wp-admin/admin-ajax.php?action=wp_engine_phpcompat' ); $update_url = site_url( 'wp-admin/update-core.php', 'admin' ); ?>
PHP Compatibility Checker. Start scanning your plugins and themes for compatibility with the latest PHP versions now!', 'php-compatibility-checker' ), esc_url( $url ) ); ?>