gocodebox/lifterlms

View on GitHub
includes/class.llms.data.php

Summary

Maintainability
B
5 hrs
Test Coverage
B
86%
<?php
/**
 * Retrieve data sets used by various other classes and functions
 *
 * @package LifterLMS/Classes
 *
 * @since 3.0.0
 * @version 4.13.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * LLMS_Data
 *
 * @since 3.0.0
 */
class LLMS_Data {

    /**
     * Get the data data
     *
     * @since 3.0.0
     * @since 3.17.0 Added browser/os data section.
     * @since 4.13.0 Added constant data.
     *
     * @param string $dataset Dataset to retrieve data for [tracker|system_report].
     * @param string $format  Data return format (unused for unrecalled reasons).
     * @return array
     */
    public static function get_data( $dataset, $format = 'array' ) {

        $data = array();

        // Add admin email for tracker requests.
        if ( 'tracker' === $dataset ) {
            $data['email'] = apply_filters( 'llms_get_data_admin_email', get_option( 'admin_email' ) );
        }

        // General data.
        $data['url'] = home_url();

        // Wp info.
        $data['wordpress'] = self::get_wp_data();

        // Llms settings.
        $data['settings'] = self::get_llms_settings();

        if ( 'system_report' === $dataset ) {
            // Constants.
            $data['constants'] = self::get_constants_data();
        }

        // Gateways.
        $data['gateways'] = self::get_gateway_data();

        // Server info.
        $data['server'] = self::get_server_data();

        // Browser / os.
        $data['browser'] = self::get_browser_data();

        // Theme info.
        $data['theme'] = self::get_theme_data();

        // Plugin info.
        $data['plugins'] = self::get_plugin_data();

        if ( 'tracker' === $dataset ) {

            // Published content type counts.
            $data['post_counts'] = self::get_post_type_counts();

            // User data.
            $data['user_counts'] = self::get_user_counts();

            // Count student engagements.
            $data['engagement_counts'] = self::get_engagement_counts();

            // Order data.
            $data['order_counts'] = self::get_order_counts();

        }

        $data['integrations'] = self::get_integrations_data();

        $data['template_overrides'] = self::get_templates_data();

        return $data;

    }

    /**
     * add browser and os info to the system report
     *
     * @since 3.17.0
     * @since 3.35.0 Sanitize `$_SERVER` data.
     *
     * @return array
     */
    private static function get_browser_data() {

        $data = array(
            'HTTP_USER_AGENT' => ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '',

        );

        return $data;

    }

    /**
     * Retrieve data about LifterLMS constants
     *
     * @since 4.13.0
     *
     * @return array
     */
    private static function get_constants_data() {

        $data = array(
            'LLMS_REMOVE_ALL_DATA'                 => 'undefined',
            'LLMS_REST_DISABLE'                    => 'undefined',
            'LLMS_SITE_FEATURE_RECURRING_PAYMENTS' => 'undefined',
            'LLMS_SITE_IS_CLONE'                   => 'undefined',
        );

        foreach ( $data as $constant => &$value ) {

            if ( defined( $constant ) ) {
                $value = constant( $constant ) ? 'true' : 'false';
            }
        }

        return $data;

    }

    /**
     * Get student engagement counts for various llms interactions
     *
     * @since 3.0.0
     *
     * @return array
     */
    private static function get_engagement_counts() {

        global $wpdb;

        $data = array();

        $data['certificates']       = absint( $wpdb->get_var( "SELECT COUNT( * ) FROM {$wpdb->prefix}lifterlms_user_postmeta WHERE meta_key = '_certificate_earned'" ) );
        $data['achievements']       = absint( $wpdb->get_var( "SELECT COUNT( * ) FROM {$wpdb->prefix}lifterlms_user_postmeta WHERE meta_key = '_achievement_earned'" ) );
        $enrollments                = $wpdb->get_results( "SELECT meta_id FROM {$wpdb->prefix}lifterlms_user_postmeta WHERE meta_key = '_status' AND ( meta_value = 'Enrolled' OR meta_value = 'enrolled' ) GROUP BY user_id, post_id" );
        $data['enrollments']        = count( $enrollments );
        $data['course_completions'] = absint( $wpdb->get_var( "SELECT COUNT( * ) FROM {$wpdb->prefix}lifterlms_user_postmeta WHERE meta_key = '_is_complete' AND meta_value = 'yes' " ) );

        return $data;

    }

    /**
     * Retrieve metadata from a file.
     * Copied from WCs get_file_version which is based on WP Core's get_file_data function.
     *
     * @since 3.11.2
     *
     * @param string $file Path to the file.
     * @return string
     */
    private static function get_file_version( $file ) {

        // Avoid notices if file does not exist.
        if ( ! file_exists( $file ) ) {
            return '';
        }

        // We don't need to write to the file, so just open for reading..
        $fp = fopen( $file, 'r' );

        // Pull only the first 8kiB of the file in..
        $file_data = fread( $fp, 8192 );

        // PHP will close file handle, but we are good citizens..
        fclose( $fp );

        // Make sure we catch CR-only line endings..
        $file_data = str_replace( "\r", "\n", $file_data );
        $version   = '';

        if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( '@version', '/' ) . '(.*)$/mi', $file_data, $match ) && $match[1] ) {
            $version = _cleanup_header_comment( $match[1] );
        }

        return $version;

    }

    /**
     * Get data about llms payment gateways
     *
     * @since 3.0.0
     * @since 3.17.8 Unknown.
     *
     * @return array
     */
    private static function get_gateway_data() {

        $data = array();

        foreach ( llms()->payment_gateways()->get_payment_gateways() as $obj ) {

            $data[ $obj->get_admin_title() ] = $obj->is_enabled() ? 'Enabled' : 'Disabled';

            if ( $obj->supports( 'test_mode' ) ) {
                $data[ $obj->get_admin_title() . '_test_mode' ] = $obj->is_test_mode_enabled() ? 'Enabled' : 'Disabled';
            }

            $data[ $obj->get_admin_title() . '_logging' ] = $obj->get_logging_enabled();
            $data[ $obj->get_admin_title() . '_order' ]   = $obj->get_display_order();

        }

        return $data;

    }

    /**
     * Get data about existing llms integrations
     *
     * @since 3.0.0
     * @since 3.17.8 Unknown.
     *
     * @return array
     */
    private static function get_integrations_data() {

        $data = array();

        $integrations = llms()->integrations();

        foreach ( $integrations->integrations() as $obj ) {

            if ( method_exists( $obj, 'is_available' ) ) {

                $data[ $obj->title ] = $obj->is_available() ? 'Yes' : 'No';

            }
        }

        return $data;

    }

    /**
     * Get LifterLMS settings
     *
     * @since 3.0.0
     * @since 3.24.0 Unknown.
     *
     * @return array
     */
    private static function get_llms_settings() {

        $data = array();

        $data['version']    = llms()->version;
        $data['db_version'] = get_option( 'lifterlms_db_version' );

        $data['course_catalog']     = self::get_page_data( 'lifterlms_shop_page_id' );
        $data['membership_catalog'] = self::get_page_data( 'lifterlms_memberships_page_id' );
        $data['student_dashboard']  = self::get_page_data( 'lifterlms_myaccount_page_id' );
        $data['checkout_page']      = self::get_page_data( 'lifterlms_checkout_page_id' );

        $data['course_catalog_per_page'] = get_option( 'lifterlms_shop_courses_per_page' );
        $data['course_catalog_sorting']  = get_option( 'lifterlms_shop_ordering' );

        $data['membership_catalog_per_page'] = get_option( 'lifterlms_memberships_per_page' );
        $data['membership_catalog_sorting']  = get_option( 'lifterlms_memberships_ordering' );

        $data['site_membership'] = self::get_page_data( 'lifterlms_membership_required' );

        $data['courses_endpoint']       = get_option( 'lifterlms_myaccount_courses_endpoint' );
        $data['edit_endpoint']          = get_option( 'lifterlms_myaccount_edit_account_endpoint' );
        $data['lost_password_endpoint'] = get_option( 'lifterlms_myaccount_lost_password_endpoint' );
        $data['vouchers_endpoint']      = get_option( 'lifterlms_myaccount_redeem_vouchers_endpoint' );

        $data['autogenerate_username'] = get_option( 'lifterlms_registration_generate_username', 'no' );

        $data['password_strength_meter']   = get_option( 'lifterlms_registration_password_strength', 'no' );
        $data['minimum_password_strength'] = get_option( 'lifterlms_registration_password_min_strength' );

        $data['terms_required'] = get_option( 'lifterlms_registration_require_agree_to_terms', 'no' );
        $data['terms_page']     = self::get_page_data( 'lifterlms_terms_page_id' );

        $data['checkout_names']              = get_option( 'lifterlms_user_info_field_names_checkout_visibility' );
        $data['checkout_address']            = get_option( 'lifterlms_user_info_field_address_checkout_visibility' );
        $data['checkout_phone']              = get_option( 'lifterlms_user_info_field_phone_checkout_visibility' );
        $data['checkout_email_confirmation'] = get_option( 'lifterlms_user_info_field_email_confirmation_checkout_visibility', 'no' );

        $data['open_registration']               = get_option( 'lifterlms_enable_myaccount_registration', 'no' );
        $data['registration_names']              = get_option( 'lifterlms_user_info_field_names_registration_visibility' );
        $data['registration_address']            = get_option( 'lifterlms_user_info_field_address_registration_visibility' );
        $data['registration_phone']              = get_option( 'lifterlms_user_info_field_phone_registration_visibility' );
        $data['registration_voucher']            = get_option( 'lifterlms_voucher_field_registration_visibility' );
        $data['registration_email_confirmation'] = get_option( 'lifterlms_user_info_field_email_confirmation_registration_visibility', 'no' );

        $data['account_names']              = get_option( 'lifterlms_user_info_field_names_account_visibility' );
        $data['account_address']            = get_option( 'lifterlms_user_info_field_address_account_visibility' );
        $data['account_phone']              = get_option( 'lifterlms_user_info_field_phone_account_visibility' );
        $data['account_email_confirmation'] = get_option( 'lifterlms_user_info_field_email_confirmation_account_visibility', 'no' );

        $data['confirmation_endpoint'] = get_option( 'lifterlms_myaccount_confirm_payment_endpoint' );
        $data['force_ssl_checkout']    = get_option( 'lifterlms_checkout_force_ssl' );
        $data['country']               = get_lifterlms_country();
        $data['currency']              = get_lifterlms_currency();
        $data['currency_position']     = get_option( 'lifterlms_currency_position' );
        $data['thousand_separator']    = get_option( 'lifterlms_thousand_separator' );
        $data['decimal_separator']     = get_option( 'lifterlms_decimal_separator' );
        $data['decimals']              = get_option( 'lifterlms_decimals' );
        $data['trim_zero_decimals']    = get_option( 'lifterlms_trim_zero_decimals', 'no' );

        $data['recurring_payments'] = ( LLMS_Site::get_feature( 'recurring_payments' ) ) ? 'yes' : 'no';

        $data['email_from_address'] = get_option( 'lifterlms_email_from_address' );
        $data['email_from_name']    = get_option( 'lifterlms_email_from_name' );
        $data['email_footer_text']  = get_option( 'lifterlms_email_footer_text' );
        $data['email_header_image'] = get_option( 'lifterlms_email_header_image' );
        $data['cert_bg_width']      = get_option( 'lifterlms_certificate_bg_img_width' );
        $data['cert_bg_height']     = get_option( 'lifterlms_certificate_bg_img_height' );
        $data['cert_legacy_compat'] = get_option( 'lifterlms_certificate_legacy_image_size' );

        return $data;

    }

    /**
     * Get number of orders per order status
     *
     * @since 3.0.0
     *
     * @return array
     */
    private static function get_order_counts() {

        $data = array();

        $orders = wp_count_posts( 'llms_order' );

        foreach ( llms_get_order_statuses() as $status => $name ) {

            $data[ $status ] = absint( $orders->{$status} );

        }

        return $data;

    }

    /**
     * Get an option that should return a page ID and return the page name and ID as a formatted string
     *
     * @since 3.0.0
     *
     * @param string $option Option name in the wp_options table.
     * @return string
     */
    private static function get_page_data( $option ) {
        $id = get_option( $option );
        if ( absint( $id ) ) {
            return sprintf( '%1$s (#%2$d) [%3$s]', get_the_title( $id ), $id, get_permalink( $id ) );
        }
        return 'Not Set'; // Don't translate this or you won't be able to read it smartypants.
    }

    /**
     * get an array of plugin data, sorted into two arrays (active and inactive)
     *
     * @since 3.0.0
     *
     * @return array
     */
    private static function get_plugin_data() {

        // Ensure we have our plugin function.
        if ( ! function_exists( 'get_plugins' ) ) {
            include ABSPATH . '/wp-admin/includes/plugin.php';
        }

        $plugins = get_plugins();

        $active   = array();
        $inactive = array();

        foreach ( get_plugins() as $path => $data ) {

            if ( is_plugin_active( $path ) ) {
                $active[ $path ] = $data;
            } else {
                $inactive[ $path ] = $data;
            }
        }

        return array(
            'active'   => $active,
            'inactive' => $inactive,
        );

    }

    /**
     * Retrieve the number of published posts for various LLMS post types
     *
     * @since 3.0.0
     *
     * @return array
     */
    private static function get_post_type_counts() {

        $data = array();

        $posts = array(
            'course',
            'section',
            'lesson',
            'llms_quiz',
            'llms_question',
            'llms_review',

            'llms_membership',

            'llms_access_plan',
            'llms_coupon',
            'llms_voucher',

            'llms_engagement',
            'llms_achievement',
            'llms_certificate',
            'llms_email',
        );

        foreach ( $posts as $post_type ) {
            $count = wp_count_posts( $post_type );
            $data[ str_replace( 'llms_', '', $post_type ) ] = absint( $count->publish );
        }

        return $data;

    }

    /**
     * Get PHP & Server Data
     *
     * @since 3.0.0
     * @since 3.35.0 Sanitize `$_SERVER` data.
     *
     * @return array
     */
    private static function get_server_data() {

        global $wpdb;

        $data = array();

        if ( function_exists( 'ini_get' ) ) {
            $data['php_max_input_vars'] = ini_get( 'max_input_vars' );
            $data['php_memory_limit']   = ini_get( 'memory_limit' );
            $data['php_post_max_size']  = ini_get( 'post_max_size' );
            $data['php_time_limt']      = ini_get( 'max_execution_time' );
            $data['php_suhosin']        = extension_loaded( 'suhosin' ) ? 'Yes' : 'No';
        }

        $data['mysql_version'] = $wpdb->db_version();

        $data['php_curl']             = function_exists( 'curl_init' ) ? 'Yes' : 'No';
        $data['php_default_timezone'] = date_default_timezone_get();
        $data['php_fsockopen']        = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
        $data['php_max_upload_size']  = size_format( wp_max_upload_size() );
        $data['php_soap']             = class_exists( 'SoapClient' ) ? 'Yes' : 'No';

        if ( function_exists( 'phpversion' ) ) {
            $data['php_version'] = phpversion();
        }

        if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
            $data['software'] = ! empty( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
        }

        $data['wp_memory_limit'] = WP_MEMORY_LIMIT;

        ksort( $data );

        return $data;
    }

    /**
     * Retrieve information about template overrides
     *
     * @since 3.11.2
     *
     * @return array
     */
    private static function get_templates_data() {

        $path = llms()->plugin_path() . '/templates/';

        $templates = array_merge( glob( $path . '*.php' ), glob( $path . '**/*.php' ) );

        $overrides = array();

        foreach ( $templates as $file ) {

            $name  = str_replace( $path, '', $file );
            $found = llms_get_template_override( $name );
            if ( $found ) {
                $overrides[] = array(
                    'core_version' => self::get_file_version( $file ),
                    'location'     => $found,
                    'version'      => self::get_file_version( $found . $name ),
                    'template'     => $name,
                );
            }
        }

        return $overrides;

    }

    /**
     * Get an array of theme data
     *
     * @since 3.0.0
     * @since 3.11.2 Unknown.
     *
     * @return   array
     */
    private static function get_theme_data() {

        $data                 = array();
        $theme_data           = wp_get_theme();
        $data['name']         = $theme_data->get( 'Name' );
        $data['version']      = $theme_data->get( 'Version' );
        $data['themeuri']     = $theme_data->get( 'ThemeURI' );
        $data['authoruri']    = $theme_data->get( 'AuthorURI' );
        $data['template']     = $theme_data->get( 'Template' );
        $data['child_theme']  = is_child_theme() ? 'Yes' : 'No';
        $data['llms_support'] = ( ! current_theme_supports( 'lifterlms' ) ) ? 'No' : 'Yes';

        return $data;

    }

    /**
     * Det the number of users and users by role registered on the site
     *
     * @since 3.0.0
     *
     * @return array
     */
    private static function get_user_counts() {

        $data = array();

        $users = count_users();

        $data          = $users['avail_roles'];
        $data['total'] = $users['total_users'];

        return $data;

    }

    /**
     * Get some WP core settings and info
     *
     * @since 3.0.0
     * @since 3.24.0 Unknown.
     *
     * @return array
     */
    private static function get_wp_data() {

        $data = array();

        $data['home_url']            = get_home_url();
        $data['site_url']            = get_site_url();
        $data['login_url']           = wp_login_url();
        $data['version']             = get_bloginfo( 'version' );
        $data['debug_mode']          = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No';
        $data['debug_log']           = ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) ? 'Yes' : 'No';
        $data['debug_display']       = ( defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY ) ? 'Yes' : 'No';
        $data['locale']              = get_locale();
        $data['multisite']           = is_multisite() ? 'Yes' : 'No';
        $data['page_for_posts']      = self::get_page_data( 'page_for_posts' );
        $data['page_on_front']       = self::get_page_data( 'page_on_front' );
        $data['permalink_structure'] = get_option( 'permalink_structure' );
        $data['show_on_front']       = get_option( 'show_on_front' );
        $data['wp_cron']             = ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) ? 'Yes' : 'No';

        return $data;

    }

}