<?php
/**
 * Plugin Name:  CyberPress
 * Description:  Plugin for Electronic Sports matches and tournaments
 * Version:      2.5.7
 * Plugin URI:   https://getcyberpress.com/
 * Author:       nK
 * Author URI:   https://getcyberpress.com/
 * License:      GPLv2 or later
 * License URI:  https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:  cyberpress
 *
 * @package CyberPress
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * CyberPress Class
 */
class CyberPress {

    /**
     * The single class instance.
     *
     * @var $instance
     */
    private static $instance = null;

    /**
     * Path to the plugin directory
     *
     * @var $plugin_path
     */
    public $plugin_path;

    /**
     * URL to the plugin directory
     *
     * @var $plugin_url
     */
    public $plugin_url;

    /**
     * Plugin name
     *
     * @var $plugin_name
     */
    public $plugin_name;

    /**
     * Plugin version
     *
     * @var $plugin_version
     */
    public $plugin_version;

    /**
     * Plugin slug
     *
     * @var $plugin_slug
     */
    public $plugin_slug;

    /**
     * Plugin name sanitized
     *
     * @var $plugin_name_sanitized
     */
    public $plugin_name_sanitized;

    /**
     * CyberPress constructor.
     */
    public function __construct() {
        /* We do nothing here! */
    }

    /**
     * Main Instance
     * Ensures only one instance of this class exists in memory at any one time.
     */
    public static function instance() {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();
            self::$instance->init();
        }
        return self::$instance;
    }

    /**
     * Init options
     */
    public function init() {
        $this->plugin_path = plugin_dir_path( __FILE__ );
        $this->plugin_url  = plugin_dir_url( __FILE__ );

        // include helper files.
        $this->include_dependencies();

        $this->add_carbon_compatibility();

        // init classes.
        new CyberPress_Admin();
        new CyberPress_Posts_Settings();
        CyberPress_Template_Parts::init();

        // Hooks.
        add_action( 'init', array( $this, 'load_textdomain' ) );
        add_action( 'init', array( 'CyberPress_Template_Loader', 'init' ) );
        add_action( 'admin_init', array( $this, 'admin_init' ) );
        add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );

        // include blocks.
        // work only if Gutenberg available.
        if ( function_exists( 'register_block_type' ) ) {

            // add CyberPress blocks category.
            add_filter( 'block_categories_all', array( $this, 'block_categories_all' ), 9 );

            // we need to enqueue the main script earlier to let 3rd-party plugins add custom styles support.
            add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ), 9 );
            add_action( 'after_setup_theme', array( $this, 'enqueue_block_editor_styles' ) );
        }
    }

    /**
     * Activation Hook
     */
    public function activation_hook() {
        set_transient( 'cyberpress_flush_rewrite_rules', true, 0 );
    }

    /**
     * Deactivation Hook
     */
    public function deactivation_hook() {
        flush_rewrite_rules();
        delete_transient( 'cyberpress_flush_rewrite_rules' );
    }

    /**
     * Load plugin textdomain
     */
    public function load_textdomain() {
        load_plugin_textdomain( 'cyberpress', false, basename( dirname( __FILE__ ) ) . '/languages' );
    }

    /**
     * Init variables
     */
    public function admin_init() {
        // get current plugin data.
        $data                        = get_plugin_data( __FILE__ );
        $this->plugin_name           = $data['Name'];
        $this->plugin_version        = $data['Version'];
        $this->plugin_slug           = plugin_basename( __FILE__, '.php' );
        $this->plugin_name_sanitized = basename( __FILE__, '.php' );
    }

    /**
     * Register CyberPress blocks category
     *
     * @param array $categories - available categories.
     * @return array
     */
    public function block_categories_all( $categories ) {
        return array_merge(
            array(
                array(
                    'slug'  => 'cyberpress',
                    'title' => __( 'CyberPress', 'cyberpress' ),
                ),
            ),
            $categories
        );
    }

    /**
     * Enqueue editor styles
     */
    public function enqueue_block_editor_styles() {
        if ( is_rtl() ) {
            add_editor_style( plugins_url( 'assets/css/style-rtl.min.css', __FILE__ ) );
        } else {
            add_editor_style( plugins_url( 'assets/css/style.min.css', __FILE__ ) );
        }
    }

    /**
     * Enqueue editor assets
     */
    public function enqueue_block_editor_assets() {
        $js_deps = array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-data', 'wp-compose', 'wp-components', 'jquery' );

        wp_enqueue_script(
            'cyberpress-editor',
            plugins_url( 'blocks/index.min.js', __FILE__ ),
            $js_deps,
            '2.5.7',
            true
        );

        $full_country_array                 = CyberPress_Country::countries( true, false );
        $full_country_options_choices_array = array();
        foreach ( $full_country_array as $key => $country ) {
            $full_country_options_choices_array[] = array(
                'icon'  => CyberPress_Country::get_flag( $key ),
                'label' => $country['name']['common'],
                'value' => $key,
            );
        }

        wp_localize_script( 'cyberpress-editor', 'cyberpressCountriesList', $full_country_options_choices_array );
    }

    /**
     * Enqueue scripts and styles
     */
    public function wp_enqueue_scripts() {
        // Assets for Match and Tournament pages.
        if ( is_singular( array( 'match', 'tournament' ) ) ) {
            // PhotoSwipe.
            wp_register_style( 'photoswipe-default-skin', $this->plugin_url . 'assets/vendor/photoswipe/default-skin/default-skin.css', array(), '4.1.2' );
            wp_enqueue_style( 'photoswipe', $this->plugin_url . 'assets/vendor/photoswipe/photoswipe.css', array( 'photoswipe-default-skin' ), '4.1.2' );

            wp_register_script( 'photoswipe-ui-default', $this->plugin_url . 'assets/vendor/photoswipe/photoswipe-ui-default.min.js', array(), '4.1.2', true );
            wp_register_script( 'photoswipe', $this->plugin_url . 'assets/vendor/photoswipe/photoswipe.min.js', array( 'photoswipe-ui-default' ), '4.1.2', true );
            wp_enqueue_script( 'cyberpress-photoswipe', $this->plugin_url . 'assets/js/plugin-photoswipe.min.js', array( 'photoswipe' ), '2.5.7', true );
        }

        // CyberPress.
        wp_enqueue_style( 'cyberpress', $this->plugin_url . 'assets/css/style.min.css', array(), '2.5.7' );
        wp_style_add_data( 'cyberpress', 'rtl', 'replace' );
        wp_style_add_data( 'cyberpress', 'suffix', '.min' );
    }

    /**
     * Include dependencies
     */
    private function include_dependencies() {
        // include vendor scripts.
        require_once $this->plugin_path . 'classes/class-vendors.php';

        // include Auxiliary class for working with the Rinvex Country library.
        require_once $this->plugin_path . 'classes/class-country.php';

        // include Twitch Embed API.
        require_once $this->plugin_path . 'classes/class-twitch.php';

        // include plugin classes.
        require_once $this->plugin_path . 'classes/class-settings-api.php';
        require_once $this->plugin_path . 'classes/class-settings.php';
        require_once $this->plugin_path . 'classes/class-admin.php';
        require_once $this->plugin_path . 'classes/class-posts-settings.php';
        require_once $this->plugin_path . 'classes/class-template-parts.php';
        require_once $this->plugin_path . 'classes/class-template-loader.php';
        require_once $this->plugin_path . 'classes/class-custom-post-api.php';
        require_once $this->plugin_path . 'classes/class-game-api.php';
        require_once $this->plugin_path . 'classes/class-player-api.php';
        require_once $this->plugin_path . 'classes/class-team-api.php';
        require_once $this->plugin_path . 'classes/class-tournament-api.php';
        require_once $this->plugin_path . 'classes/class-match-api.php';
        require_once $this->plugin_path . 'classes/class-supported-themes.php';
        require_once $this->plugin_path . 'blocks/index.php';
    }

    /**
     * Function for Carbon Fields library compatibility.
     */
    private function add_carbon_compatibility() {
        if ( ! defined( 'Carbon_Fields\URL' ) ) {
            define( 'Carbon_Fields\URL', '/wp-content/plugins/cyberpress/vendor/htmlburger/carbon-fields' );
        }
        add_filter( 'carbon_field_react_select_root_uri', array( $this, 'add_carbon_field_react_select_root_uri' ) );
    }

    /**
     * Add root uri to nk react select carbon field if not set.
     *
     * @param string $uri - root uri.
     * @return string
     */
    public function add_carbon_field_react_select_root_uri( $uri ) {
        if ( empty( $uri ) ) {
            $uri = '/wp-content/plugins/cyberpress/vendor/nk-o/carbon-field-react-select';
        }
        return $uri;
    }


    /**
     * Function wrapper for work with game posts.
     *
     * @param null $id - @param null $id - post id. If null or not exist - we use global $post->ID.
     * @return CyberPress_Game_API
     */
    public function get_the_game( $id = null ) {
        return new CyberPress_Game_API( $id );
    }

    /**
     * Function wrapper for work with player posts.
     *
     * @param null $id - @param null $id - post id. If null or not exist - we use global $post->ID.
     * @return CyberPress_Player_API
     */
    public function get_the_player( $id = null ) {
        return new CyberPress_Player_API( $id );
    }

    /**
     * Function wrapper for work with team posts.
     *
     * @param null $id - @param null $id - post id. If null or not exist - we use global $post->ID.
     * @return CyberPress_Team_API
     */
    public function get_the_team( $id = null ) {
        return new CyberPress_Team_API( $id );
    }

    /**
     * Function wrapper for work with match posts.
     *
     * @param null $id - @param null $id - post id. If null or not exist - we use global $post->ID.
     * @return CyberPress_Match_API
     */
    public function get_the_match( $id = null ) {
        return new CyberPress_Match_API( $id );
    }

    /**
     * Function wrapper for work with tournament posts.
     *
     * @param null $id - @param null $id - post id. If null or not exist - we use global $post->ID.
     * @return CyberPress_Tournament_API
     */
    public function get_the_tournament( $id = null ) {
        return new CyberPress_Tournament_API( $id );
    }

    /**
     * Get array for kses with allowed attributes for <img> tag.
     *
     * @return array
     */
    public function get_kses_allowed_img() {
        return array(
            'img'   => array(
                'src'          => array(),
                'alt'          => array(),
                'srcset'       => array(),
                'sizes'        => array(),
                'width'        => array(),
                'height'       => array(),
                'class'        => array(),

                // lazy loading support.
                'loading'      => array(),
                'data-src'     => array(),
                'data-sizes'   => array(),
                'data-srcset'  => array(),
                'data-no-lazy' => array(),
            ),
            'svg'   => array(
                'class'           => true,
                'aria-hidden'     => true,
                'aria-labelledby' => true,
                'role'            => true,
                'xmlns'           => true,
                'width'           => true,
                'height'          => true,
                'viewbox'         => true,
            ),
            'g'     => array( 'fill' => true ),
            'title' => array( 'title' => true ),
            'path'  => array(
                'd'    => true,
                'fill' => true,
            ),
            'span'  => array( 'class' => true ),
        );
    }

    /**
     * Get array for kses with allowed attributes for <iframe> tag.
     *
     * @return array
     */
    public function get_kses_allowed_iframe() {
        return array(
            'iframe' => array(
                'src'             => array(),
                'frameborder'     => array(),
                'allowfullscreen' => array(),
                'scrolling'       => array(),
                'width'           => array(),
                'height'          => array(),
                'class'           => array(),
            ),
            'div' => array(
                'data-channel' => array(),
                'class'        => array(),
            ),
        );
    }

    /**
     * Check cyberpress page.
     *
     * @param int $page_id - Page ID.
     * @return boolean
     */
    public function is_cyberpress( $page_id = null ) {
        $page_id   = null === $page_id ? get_the_ID() : $page_id;
        $post_type = function_exists( 'get_post_type' ) ? get_post_type() : null;

        if ( class_exists( 'CyberPress_Settings' ) ) {
            $games_archive       = CyberPress_Settings::get_option( 'games_list_page_id', 'cyberpress_general' );
            $players_archive     = CyberPress_Settings::get_option( 'players_list_page_id', 'cyberpress_general' );
            $teams_archive       = CyberPress_Settings::get_option( 'teams_list_page_id', 'cyberpress_general' );
            $matches_archive     = CyberPress_Settings::get_option( 'matches_list_page_id', 'cyberpress_general' );
            $tournaments_archive = CyberPress_Settings::get_option( 'tournaments_list_page_id', 'cyberpress_general' );
        }

        return (
            is_post_type_archive( 'team' ) ||
            is_post_type_archive( 'game' ) ||
            is_post_type_archive( 'player' ) ||
            is_post_type_archive( 'match' ) ||
            is_post_type_archive( 'tournament' ) ||
            'match' === $post_type ||
            'tournament' === $post_type ||
            'game' === $post_type ||
            'player' === $post_type ||
            'team' === $post_type ||
            (
                isset( $games_archive ) &&
                $page_id === $games_archive
            ) ||
            (
                isset( $players_archive ) &&
                $page_id === $players_archive
            ) ||
            (
                isset( $teams_archive ) &&
                $page_id === $teams_archive
            ) ||
            (
                isset( $matches_archive ) &&
                $page_id === $matches_archive
            ) ||
            (
                isset( $tournaments_archive ) &&
                $page_id === $tournaments_archive
            )
        );
    }
}

/**
 * Function works with the CyberPress class instance
 *
 * @return object CyberPress
 */
function cyberpress() {
    return CyberPress::instance();
}
add_action( 'plugins_loaded', 'cyberpress' );

register_deactivation_hook( __FILE__, array( cyberpress(), 'activation_hook' ) );
register_activation_hook( __FILE__, array( cyberpress(), 'deactivation_hook' ) );
