<?php
/**
 * Plugin Name: Simple Custom CSS and JS
 * Plugin URI:  https://wordpress.org/plugins/custom-css-js/
 * Description: Easily add Custom CSS or JS to your website with an awesome editor.
 * Version:     3.51.1
 * Author:      SilkyPress.com
 * Author URI:  https://www.silkypress.com
 * License:     GPL2
 *
 * Text Domain: custom-css-js
 * Domain Path: /languages/
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

if ( ! class_exists( 'CustomCSSandJS' ) ) :
	/**
	 * Main CustomCSSandJS Class
	 *
	 * @class CustomCSSandJS
	 */
	final class CustomCSSandJS {

		public $search_tree         = false;
		protected static $_instance = null;
		private $settings           = array();


		/**
		 * Main CustomCSSandJS Instance
		 *
		 * Ensures only one instance of CustomCSSandJS is loaded or can be loaded
		 *
		 * @static
		 * @return CustomCSSandJS - Main instance
		 */
		public static function instance() {
			if ( is_null( self::$_instance ) ) {
				self::$_instance = new self();
			}
			return self::$_instance;
		}

		/**
		 * Cloning is forbidden.
		 */
		public function __clone() {
			_doing_it_wrong( __FUNCTION__, __( 'An error has occurred. Please reload the page and try again.' ), '1.0' );
		}

		/**
		 * Unserializing instances of this class is forbidden.
		 */
		public function __wakeup() {
			_doing_it_wrong( __FUNCTION__, __( 'An error has occurred. Please reload the page and try again.' ), '1.0' );
		}

		/**
		 * CustomCSSandJS Constructor
		 *
		 * @access public
		 */
		public function __construct() {

			if ( class_exists( 'CustomCSSandJSpro' ) ) {
				return false;
			}

			include_once 'includes/admin-install.php';
			register_activation_hook( __FILE__, array( 'CustomCSSandJS_Install', 'install' ) );
			add_action( 'init', array( 'CustomCSSandJS_Install', 'register_post_type' ) );

			$this->set_constants();

			if ( is_admin() ) {
				add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
				include_once 'includes/admin-screens.php';
				include_once 'includes/admin-config.php';
				include_once 'includes/admin-addons.php';
				include_once 'includes/admin-warnings.php';
				include_once 'includes/admin-notices.php';
			}

			$this->search_tree = get_option( 'custom-css-js-tree', array() );
			$this->settings    = get_option( 'ccj_settings', array() );
			if ( ! isset( $this->settings['remove_comments'] ) ) {
				$this->settings['remove_comments'] = false;
			}

			if ( ! $this->search_tree || count( $this->search_tree ) == 0 ) {
				return false;
			}

			if ( is_null( self::$_instance ) ) {
				$this->print_code_actions();
				if ( isset ( $this->search_tree['jquery'] ) && true === $this->search_tree['jquery'] ) {
					add_action( 'wp_enqueue_scripts', 'CustomCSSandJS::wp_enqueue_scripts' );
				}
				add_action( 'enqueue_block_assets', 'CustomCSSandJS::enqueue_block_assets' );
			}
		}

		/**
		 * Add the appropriate wp actions
		 */
		public function print_code_actions() {
			foreach ( $this->search_tree as $_key => $_value ) {
				if ( strpos( $_key, 'block' ) !== false ) continue;

				$action = 'wp_';
				if ( strpos( $_key, 'admin' ) !== false ) {
					$action = 'admin_';
				}
				if ( strpos( $_key, 'login' ) !== false ) {
					$action = 'login_';
				}
				if ( strpos( $_key, 'header' ) !== false ) {
					$action .= 'head';
				} elseif ( strpos( $_key, 'body_open' ) !== false ) {
					$action .= 'body_open';
				} else {
					$action .= 'footer';
				}

				$priority = ( 'wp_footer' === $action ) ? 40 : 10;

				add_action( $action, array( $this, 'print_' . $_key ), $priority );
			}
		}

		/**
		 * Print the custom code.
		 */
		public function __call( $function, $args ) {

			if ( strpos( $function, 'print_' ) === false ) {
				return false;
			}

			$function = str_replace( 'print_', '', $function );

			if ( ! isset( $this->search_tree[ $function ] ) ) {
				return false;
			}

			$args = $this->search_tree[ $function ];

			if ( ! is_array( $args ) || count( $args ) == 0 ) {
				return false;
			}

			$where = strpos( $function, 'external' ) !== false ? 'external' : 'internal';
			$type  = strpos( $function, 'css' ) !== false ? 'css' : '';
			$type  = strpos( $function, 'js' ) !== false ? 'js' : $type;
			$type  = strpos( $function, 'html' ) !== false ? 'html' : $type;
			$tag   = array( 'css' => 'style', 'js' => 'script' );

			$type_attr = ( 'js' === $type && ! current_theme_supports( 'html5', 'script' ) ) ? ' type="text/javascript"' : '';
			$type_attr = ( 'css' === $type && ! current_theme_supports( 'html5', 'style' ) ) ? ' type="text/css"' : $type_attr;

			$upload_url = CCJ_UPLOAD_URL . '/';
			if ( ! apply_filters( 'ccj_default_url_protocol', false ) ) {
				$upload_url = str_replace( array( 'https://', 'http://' ), '//', CCJ_UPLOAD_URL ) . '/';
			}

			if ( 'internal' === $where ) {

				$before = $this->settings['remove_comments'] ? '' : '<!-- start Simple Custom CSS and JS -->' . PHP_EOL;
				$after  = $this->settings['remove_comments'] ? '' : '<!-- end Simple Custom CSS and JS -->' . PHP_EOL;

				if ( 'css' === $type || 'js' === $type ) {
					$before .= '<' . $tag[ $type ] . ' ' . $type_attr . '>' . PHP_EOL;
					$after   = '</' . $tag[ $type ] . '>' . PHP_EOL . $after;
				}

			}

			foreach ( $args as $_filename ) {

				if ( 'internal' ===  $where && ( strstr( $_filename, 'css' ) || strstr( $_filename, 'js' ) ) ) {
					if ( $this->settings['remove_comments'] || empty( $type_attr ) ) {
						$custom_code = @file_get_contents( CCJ_UPLOAD_DIR . '/' . $_filename );
						if ( $this->settings['remove_comments'] ) {
								$custom_code = str_replace( array( 
										'<!-- start Simple Custom CSS and JS -->' . PHP_EOL, 
										'<!-- end Simple Custom CSS and JS -->' . PHP_EOL 
								), '', $custom_code );
						}
						if ( empty( $type_attr ) ) {
							$custom_code = str_replace( array( ' type="text/javascript"', ' type="text/css"' ), '', $custom_code );
						}
						echo $custom_code;
					} else {
						echo @file_get_contents( CCJ_UPLOAD_DIR . '/' . $_filename );
					}
				}

				if ( 'internal' === $where && ! strstr( $_filename, 'css' ) && ! strstr( $_filename, 'js' ) ) {
					$post = get_post( $_filename );
					echo $before . $post->post_content . $after;
				}

				if ( 'external' === $where && 'js' === $type ) {
					echo PHP_EOL . "<script{$type_attr} src='{$upload_url}{$_filename}'></script>" . PHP_EOL;
				}

				if ( 'external' === $where && 'css' === $type ) {
					$shortfilename = preg_replace( '@\.css\?v=.*$@', '', $_filename );
					echo PHP_EOL . "<link rel='stylesheet' id='{$shortfilename}-css' href='{$upload_url}{$_filename}'{$type_attr} media='all' />" . PHP_EOL;
				}

				if ( 'external' === $where && 'html' === $type ) {
					$_filename = str_replace( '.html', '', $_filename );
					$post      = get_post( $_filename );
					echo $post->post_content . PHP_EOL;
				}
			}
		}


		/**
		 * Enqueue the jQuery library, if necessary
		 */
		public static function wp_enqueue_scripts() {
			wp_enqueue_script( 'jquery' );
		}


		/**
		 * Load the CSS/JS custom codes to the Block editor.
		 */
		public static function enqueue_block_assets() {

			$search_tree = get_option( 'custom-css-js-tree', array() );

			$js_dependency = ( isset( $search_tree['jquery'] ) && true === $search_tree['jquery'] ) ? ['jquery'] : [];

			foreach ( $search_tree as $_where => $_files ) {
				if ( strpos( $_where, 'html' ) !== false || strpos( $_where, 'block' ) === false || strpos( $_where, 'external' ) === false ) continue;
				if ( ! is_array( $_files ) || count( $_files ) === 0 ) continue;


				// Load external CSS custom codes.
				if ( strpos( $_where, 'css' ) !== false ) {
					foreach ( $_files as $__file ) {
						wp_enqueue_style( $__file, CCJ_UPLOAD_URL . '/' . $__file, [], null );
					}
				} 

				// Load external JS custom codes.
				if ( strpos( $_where, 'js' ) !== false ) {
					$args = [];
					if ( strpos( $_where, 'footer' ) !== false ) {
						$args['in_footer'] = true;
					}
					foreach ( $_files as $__file ) {
						wp_enqueue_script( $__file, CCJ_UPLOAD_URL . '/' . $__file, $js_dependency, null, $args );
					}
				}
			}

			// Load internal CSS/JS codes.
			// 		Currently (WP6.8) the block editor can load only externally linked files,
			// 		therefore the internal custom codes are saved in the block_js.js and block_css.css files
			// 		and then loaded in the block editor as externally linked files.
			if ( isset( $search_tree['block-css-footer-internal'] ) || isset( $search_tree['block-css-header-internal'] ) ) {
				wp_enqueue_style( 'ccj-block_css', CCJ_UPLOAD_URL . '/block_css.css', [], rand(1, 1000) );
			}
			if ( isset( $search_tree['block-js-footer-internal'] ) || isset( $search_tree['block-js-header-internal'] ) ) {
				wp_enqueue_script( 'ccj-block_js',  CCJ_UPLOAD_URL . '/block_js.js', $js_dependency, rand(1, 1000) );
			}

		}


		/**
		 * Set constants for later use
		 */
		public function set_constants() {
			$dir       = wp_upload_dir();
			$constants = array(
				'CCJ_VERSION'     => '3.51.1',
				'CCJ_UPLOAD_DIR'  => $dir['basedir'] . '/custom-css-js',
				'CCJ_UPLOAD_URL'  => $dir['baseurl'] . '/custom-css-js',
				'CCJ_PLUGIN_FILE' => __FILE__,
			);
			foreach ( $constants as $_key => $_value ) {
				if ( ! defined( $_key ) ) {
					define( $_key, $_value );
				}
			}
		}

		/**
		 * Loads a plugin’s translated strings.
		 */
		public function load_plugin_textdomain() {
			load_plugin_textdomain( 'custom-css-js', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
		}
	}

endif;

if ( ! function_exists( 'CustomCSSandJS' ) ) {
	/**
	 * Returns the main instance of CustomCSSandJS
	 *
	 * @return CustomCSSandJS
	 */
	function CustomCSSandJS() {
		return CustomCSSandJS::instance();
	}

	CustomCSSandJS();
}

if ( ! function_exists( 'custom_css_js_plugin_action_links' ) ) {
	/**
	 * Plugin action link to Settings page.
	 *
	 * @param array $links The settings links.
	 *
	 * @return array The settings links.
	 */
	function custom_css_js_plugin_action_links( $links ) {

		$settings_link = '<a href="edit.php?post_type=custom-css-js">' .
		esc_html( __( 'Settings', 'custom-css-js' ) ) . '</a>';

		return array_merge( array( $settings_link ), $links );

	}
	add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'custom_css_js_plugin_action_links' );
}

if ( ! function_exists( 'custom_css_js_quads_pro_compat' ) ) {
	/**
	 * Compatibility with the WP Quads Pro plugin,
	 * otherwise on a Custom Code save there is a
	 * "The link you followed has expired." page shown.
	 *
	 * @param array $post_types The Post types.
	 * @return array The Post types.
	 */
	function custom_css_js_quads_pro_compat( $post_types ) {
		$match = array_search( 'custom-css-js', $post_types, true );
		if ( $match ) {
			unset( $post_types[ $match ] );
		}
		return $post_types;
	}
	add_filter( 'quads_meta_box_post_types', 'custom_css_js_quads_pro_compat', 20 );
}

