HEX
Server: nginx/1.29.3
System: Linux mail.sarafai.ru 6.1.0-40-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.153-1 (2025-09-20) x86_64
User: www-data (33)
PHP: 7.4.33
Disabled: dl,exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source
Upload Files
File: /var/www/levasheva.ru/public/wp-content/plugins/weekly-class/classes/class.shortcodes.php
<?php

new CurlyWeeklyClassShortcodes();

/**
* Weekly Classe
*/
class CurlyWeeklyClassShortcodes {

	public $_classes;

	public function __construct(){

		add_shortcode( 'wcs_timetable', array( $this, 'timetable' ) );
		add_shortcode( 'wcs-schedule', array( $this, 'wcs_schedule') );

		$settings = wcs_get_settings();

		add_action( 'wp_footer', array( $this, 'check_for_schedules' ) );
		add_action( wp_validate_boolean( $settings['wcs_get_footer'] ) ? 'get_footer' : 'wp_footer', array( $this, 'modal_templates' ) );
		add_action( 'wp_head', array( $this, 'global_styles' ) );

		add_filter( 'wcs_filter_front_tdata', array( $this, 'filter_tdata' ), 10, 2 );
		add_filter( 'wcs_view_css', array( $this, 'default_css' ), 10, 3 );

		add_action( 'wp_enqueue_scripts', array( $this, 'assets' ) );

		$views = apply_filters( 'wcs_views', array() );

		if( is_array( $views ) ){
			foreach( $views as $view ){
				$file = ! isset( $view['front_path'] ) ? WCS_PATH . "/assets/defaults/front/view.{$view['slug']}.php" : $view['front_path'];
				if( file_exists( $file ) ) require_once( $file );
			}
		}

	}


	function global_styles(){
		echo '<style type="text/css" media="all" id="wcs_styles"></style>';
	}

	public static function set_dependency( $dep ){

		global $wcs_page_dependencies;

		if( empty( $wcs_page_dependencies ) ){

			$wcs_page_dependencies = array( $dep );


		} else if( ! in_array( $dep, $wcs_page_dependencies ) ){

			$wcs_page_dependencies[] = $dep;

		}

	}

	/** Front Assets */
	function assets(){

		$google_maps_api_key = esc_attr( get_option( 'wcs_api_key', '' ) );

		wp_register_script(
			'google-maps-js',
			add_query_arg( array( 'key' => $google_maps_api_key, 'sensor' => true, 'v' => 3 ), 'https://maps.googleapis.com/maps/api/js'),
			array( 'jquery' ),
			null
		);

		wp_register_script(
			'wcs-images-loaded',
			plugins_url() . '/weekly-class/assets/libs/metafizzy/imagesloaded.pkgd.min.js',
			array( 'jquery' ),
			null,
			true
		);

		wp_register_script(
			'wcs-match-height',
			plugins_url() . '/weekly-class/assets/libs/matchheight/jquery.matchHeight-min.js',
			array( 'jquery'  ),
			null,
			true
		);

		wp_register_script(
			'countdown-js',
			plugins_url() . '/weekly-class/assets/libs/countdown-js/countdown-js.js',
			array( 'jquery'  ),
			null,
			true
		);

		wp_register_script(
			'vue-js',
			WP_DEBUG ? plugins_url() . '/weekly-class/assets/libs/vue/vue.js' : plugins_url() . '/weekly-class/assets/libs/vue/vue.min.js',
			array( 'jquery' ),
			null,
			true
		);


		wp_register_script(
			'wcs-images-loaded-vue',
			plugins_url() . '/weekly-class/assets/libs/vue/vueimagesloaded.js',
			array( 'jquery', 'vue-js', 'wcs-images-loaded' ),
			null,
			true
		);

		wp_register_script(
			'wcs-owl',
			plugins_url() . '/weekly-class/assets/libs/owlcarousel/js/owl.carousel.min.js',
			array( 'jquery', 'wcs-images-loaded-vue' ),
			null,
			true
		);

		wp_register_script(
			'wcs-isotope-native',
			plugins_url() . '/weekly-class/assets/libs/metafizzy/isotope.pkgd.min.js',
			array( 'jquery' ),
			null,
			true
		);

		wp_register_script(
			'lodash',
			plugins_url() . '/weekly-class/assets/libs/lodash/lodash.min.js',
			array( 'jquery' ),
			'1.8.3',
			true
		);

		wp_register_script(
			'wcs-isotope',
			plugins_url() . '/weekly-class/assets/libs/vue/vue_isotope.js',
			array( 'jquery', 'vue-js', 'wcs-isotope-native', 'lodash', 'wcs-images-loaded-vue' ),
			'1.2',
			true
		);

		wp_register_script(
			'moment-js',
			plugins_url() . '/weekly-class/assets/libs/moment/moment.js',
			array( 'jquery' ),
			null,
			true
		);

		if( ! wp_script_is( 'vue-resource', 'registered' ) ){
			wp_register_script(
				'vue-resource',
				plugins_url() . '/weekly-class/assets/libs/vue/vue-resource.min.js',
				array( 'jquery', 'vue-js' ),
				null,
				true
			);
		}

		wp_register_script(
			'wcs-main',
			plugins_url() . '/weekly-class/assets/front/js/min/scripts-min.js',
			empty( $google_maps_api_key ) ? array( 'jquery', 'vue-js', 'wcs-images-loaded', 'vue-resource', 'moment-js' ) : array( 'jquery', 'google-maps-js', 'vue-js', 'wcs-images-loaded', 'vue-resource', 'moment-js' ),
			WP_DEBUG || is_user_logged_in() ? rand() : WCS_VERSION,
			true
		);

		wp_register_script(
			'wcs-fullcalendar',
			plugins_url() . '/weekly-class/assets/libs/fullcalendar/fullcalendar.min.js',
			array( 'jquery', 'moment-js' ),
			'2.0',
			true
		);

		global $wp_locale;

		wp_localize_script( 'wcs-main', 'wcs_locale', array(
			'firstDay' => intval( get_option( 'start_of_week') ),
			'monthNames' => array_values( $wp_locale->month ),
			'monthNamesShort' => array_values( $wp_locale->month_abbrev ),
			'dayNames' => array_values( $wp_locale->weekday ),
			'dayNamesShort' => array_values( $wp_locale->weekday_abbrev ),
			'dayNamesMin' => array_values( $wp_locale->weekday_initial ),
			'gmtOffset' => get_option( 'gmt_offset' ) * HOUR_IN_SECONDS
		));
		wp_localize_script( 'wcs-main', 'wcs_moment_locale', array(
			'firstDay' => intval( get_option( 'start_of_week') ),
			'months' => array_values( $wp_locale->month ),
			'monthsShort' => array_values( $wp_locale->month_abbrev ),
			'weekdays' => array_values( $wp_locale->weekday ),
			'weekdaysShort' => array_values( $wp_locale->weekday_abbrev ),
			'weekdaysMin' => array_values( $wp_locale->weekday_initial )
		) );

		wp_localize_script( 'wcs-main', 'wcs_settings', array(
			'hasSingle' => filter_var( esc_attr( get_option( 'wcs_single', true ) ), FILTER_VALIDATE_BOOLEAN ),
			'is_user_logged_in' => current_user_can('editor') || current_user_can('administrator') ? '1' : '0'
		));
		wp_localize_script( 'wcs-main', 'wcs_select2', array(
			'errorLoading' => esc_html__( 'The results could not be loaded.', 'WeeklyClass' ),
			'inputTooLong' => esc_html__( 'Please delete %n character(s)', 'WeeklyClass' ),
			'inputTooShort' => esc_html__( 'Please enter %n or more characters', 'WeeklyClass' ),
			'loadingMore' => esc_html__( 'Loading more results…', 'WeeklyClass' ),
			'maximumSelected' => esc_html__( 'You can only select %n item(s)', 'WeeklyClass' ),
			'noResults' => esc_html__( 'No results found', 'WeeklyClass' ),
			'searching' => esc_html__( 'Searching…', 'WeeklyClass' ),
		));
		wp_localize_script( 'wcs-main', 'ajaxurl', admin_url( 'admin-ajax.php' ) );
		//wp_localize_script( 'wcs-main', 'wcs_maps_url', $maps_url );

		wp_register_style(
			'wcs-display-monthly',
			plugins_url() . '/weekly-class/assets/libs/fullcalendar/fullcalendar.min.css',
			null,
			false,
			'all'
		);


		wp_register_style(
			'wcs-timetable',
			plugins_url() . '/weekly-class/assets/front/css/timetable.css',
			array(),
			WP_DEBUG || is_user_logged_in() ? rand() : WCS_VERSION,
			'all'
		);

		wp_enqueue_style( 'wcs-timetable' );

	}

	function wcs_schedule( $atts = null, $content = null ){
		$atts = shortcode_atts( array( 'id' => null ), $atts, 'wcs_schedule' );
		return do_shortcode( "[wcs_timetable id='{$atts['id']}']" );
	}

	function check_for_schedules(){

		global $wcs_has_shortcode;
		global $wcs_page_dependencies;

		if( ! filter_var( $wcs_has_shortcode, FILTER_VALIDATE_BOOLEAN ) ) return;

		$wcs_page_dependencies = empty( $wcs_page_dependencies ) ? array() : $wcs_page_dependencies;

		foreach( $wcs_page_dependencies as $key => $dep ){
			if( ! wp_script_is( $dep ) ) wp_enqueue_script( $dep );
		}

		if( ! wp_script_is( 'wcs-main' ) ) wp_enqueue_script( 'wcs-main' );

	}

	function modal_templates(){

		global $wcs_has_shortcode;
		global $wcs_page_dependencies;
		global $wcs_apps;

		if( ! filter_var( $wcs_has_shortcode, FILTER_VALIDATE_BOOLEAN ) ) return;

			$templates = apply_filters( 'wcs_register_templates_filters', array() );

			foreach( $templates as $key => $data ){
				foreach( $data as $key_data => $url ){
					include( $url );
				}
			}

			if( is_array( $wcs_apps ) ){
				foreach( $wcs_apps as $key => $app ){
					extract( $app );
					$template_app = wcs_get_template_part( 'app' );
					if( $template_app && ! empty( $template_app ) )  include( $template_app );
				}
			}

		?>

		<div id="wcs-vue-modal"></div>

		<?php


	}


	public static function hex2rgb( $colour, $opacity = 1, $array = false ) {

		if ( ! is_array( $colour ) && strpos( $colour, '#') !== false ) {
		    $colour = substr( $colour, 1 );
		}
		if ( strlen( $colour ) == 6 ) {
		        list( $r, $g, $b ) = array( $colour[0] . $colour[1], $colour[2] . $colour[3], $colour[4] . $colour[5] );
		} elseif ( strlen( $colour ) == 3 ) {
		        list( $r, $g, $b ) = array( $colour[0] . $colour[0], $colour[1] . $colour[1], $colour[2] . $colour[2] );
		} else {
		        return false;
		}
		$r = hexdec( $r );
		$g = hexdec( $g );
		$b = hexdec( $b );

		if( $array === true )
			return array( 'r' => $r, 'g' => $g, 'b' => $b );

		return "rgba( $r, $g, $b, $opacity)";

	}

	public static function contrast( $color, $opacity1 = 1, $opacity2 = 1 ) {
		return (abs(self::brightness('#ffffff') - self::brightness(self::darken($color))) > abs(self::brightness('#000000') - self::brightness(self::darken($color)))) ? self::hex2rgb('#ffffff', $opacity1) : self::hex2rgb('#000000', $opacity2);
	}

	public static function brightness( $hexStr ) {
		$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr);
		$rgbArray = array();
		if (strlen($hexStr) == 6) {
			$colorVal = hexdec($hexStr);
			$rgbArray['red'] = 0xFF & ($colorVal >> 0x10);
			$rgbArray['green'] = 0xFF & ($colorVal >> 0x8);
			$rgbArray['blue'] = 0xFF & $colorVal;
		} elseif (strlen($hexStr) == 3) {
			$rgbArray['red'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));
			$rgbArray['green'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));
			$rgbArray['blue'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));
		} else {
			return false;
		}
		return (($rgbArray['red']*299) + ($rgbArray['green']*587) + ($rgbArray['blue']*114))/1000;
	}
	public static function darken( $color, $dif=20 ){
	    $color = str_replace('#', '', $color);
	    if (strlen($color) != 6){ return '000000'; }
	    $rgb = '';
	    for ($x=0;$x<3;$x++){
	        $c = hexdec(substr($color,(2*$x),2)) - $dif;
	        $c = ($c < 0) ? 0 : dechex($c);
	        $rgb .= (strlen($c) < 2) ? '0'.$c : $c;
	    }
	    return '#'.$rgb;
	}


	static function set_filters( $filter = null, $key = null, $filters = array() ){

		if( ! is_null( $filter ) ){

			if( strpos( $filter, ',' ) !== false ){
				if( strpos( $filter, ' ' ) !== false){
					$filter = str_replace( ' ', '', $filter );
				}
				$filter = explode( ',', $filter );
				foreach( $filter as $value ){
					$filters[] = array( 'name' => $key, 'value' => $value );
				}
			} else{
				$filters[] = array( 'name' => $key, 'value' => $filter );
			}

		}

		return $filters;
	}


	function filter_tdata( $data, $id ){
		$data = apply_filters( 'wcs_filter_migration_tdata', $data );

		$data['id'] = isset( $data['id'] ) ? $data['id'] : $id;
		$data['color_special_contrast'] =  self::contrast( isset( $data['color_special'] ) && ! empty( $data['color_special'] ) ? $data['color_special'] : '#BF392B', 1, 1 );
		$data['terms_colors'] = array();
		if( ! isset( $data['content'] ) || ! is_array( $data['content'] ) ){
			$content = array();
			$taxes = WeeklyClass::get_object_taxonomies( 'class', 'objects' );
			foreach( $taxes as $tax =>$tax_value ){
				$content[$tax] = array();
				$terms = get_terms( $tax, array( 'hide_empty' => true ) );
				foreach($terms as $term){
					$content[$tax][] = $term->term_id;
				}
			}
		} else{
			$content = $data['content'];
		}

		foreach( $content as $tax => $terms ){
			foreach( $terms as $term ){
				$term_data  = get_option( "taxonomy_$term" );

				if( $term_data !== false && ! empty( $term_data ) && isset( $term_data['color'] ) && ! empty( $term_data['color'] ) ){
					$data['terms_colors'][$term] = $term_data['color'];
				}
			}
		}

		foreach ( $data as $key => $value ) {
			if( strpos( $key, 'show_' ) === 0 ){
				$data[$key] = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
			}
			if( ! isset( $data['show_filter_time_of_day'] ) && $key === 'show_filter_time' ){
				$data['show_filter_time_of_day'] = $value;
			}
			if( ! isset( $data['show_filter_day_of_week'] ) && $key === 'show_filter_day' ){
				$data['show_filter_day_of_week'] = $value;
			}
			if( strpos( $key, 'dateformat' ) !== false  ){
				$data[$key] = stripslashes( $value );
			}
		}
		return $data;
	}


	function default_css( $css, $data, $schedule_id ){
		$color_text = isset( $data['color_text'] ) && ! empty( $data['color_text'] ) && $data['color_text'] !== 'undefined' ? $data['color_text'] : 'inherit';
		$color_special = isset( $data['color_special'] ) && ! empty( $data['color_special'] ) && $data['color_special'] !== 'undefined' ? $data['color_special'] : '#BF392B';
		$css .= "
			.wcs-timetable--$schedule_id.wcs-timetable__container{
				color: {$color_text};
			}
			.wcs-timetable--$schedule_id .wcs-timetable{
				border-color: {$color_text};
			}
			.wcs-timetable--$schedule_id .wcs-filters__title,
			.wcs-timetable--$schedule_id .wcs-filters__filter-wrapper:hover,
			.wcs-timetable--$schedule_id .wcs-filter:checked + span{
				color: {$color_special};
			}
			.wcs-timetable--$schedule_id .wcs-btn--action,
			.wcs-timetable--$schedule_id .wcs-btn--action:hover{
				background-color: {$color_special};
				color: " . self::contrast( $color_special, 1, 0.75 ) . ";
			}

			.wcs-modal[data-wcs-modal-id='$schedule_id'] .wcs-btn--action,
			.wcs-modal[data-wcs-modal-id='$schedule_id'] .wcs-btn--action:hover{
				background-color: {$color_special};
				color: " . self::contrast( $color_special, 1, 0.75 ) . ";
			}
		";


		if( isset( $data['filters_style'] ) && filter_var( $data['filters_style'], FILTER_VALIDATE_BOOLEAN ) ){

			$css .= "
				.wcs-timetable--$schedule_id .wcs-filters--switches input:checked + .wcs-switcher__switch{
					color: $color_special;
				}
				.wcs-timetable--$schedule_id .wcs-switcher__switch{
					color: " . ( $color_text === 'inherit' ? 'inherit' : self::hex2rgb( $color_text, 0.25 ) ) . ";
					border-color: " . ( $color_text === 'inherit' ? 'inherit' : self::hex2rgb( $color_text, 0.25 ) ) . ";
				}
			";

		}

		return $css;

	}

	public static function get_view( $views, $view ){
		if( is_array( $views ) ){
			foreach( $views as $key => $item ){
				if( intval( $item['value'] ) === intval( $view ) ){
					return $item;
				}
			}
		}
	}


	static public function timetable( $atts, $content = null ){

		$atts = shortcode_atts( array( 'id' => null ), $atts, 'wcs_timetable' );
		extract( $atts );

		$prepend_filters = true;

		$views = apply_filters( 'wcs_views', array() );
		$settings = wcs_get_settings();

		$tdata_transient = is_user_logged_in() ? false : get_transient( 'wcs_tdata_' . $id );

		if( ! $tdata_transient ){

			$data = get_option( "__wcs_schedule_$id" );


			if( $data === false )
				return;

			$data = apply_filters( 'wcs_filter_front_tdata', maybe_unserialize( $data ), $id );

			$view_object 	= self::get_view( $views, isset( $data['view'] ) ? $data['view'] : 0 );
			$has_filters 	= isset( $view_object['filters'] ) ? filter_var( $view_object['filters'], FILTER_VALIDATE_BOOLEAN ) : true;

			$template 	= isset( $view_object['slug'] ) ? esc_attr( $view_object['slug'] ) : false;
			$template_filters = $has_filters ? isset( $view_object['filters_template'] ) ? esc_attr( $view_object['filters_template'] ) : 'default' : false;

			$mixins = isset( $view_object['mixins'] ) ? esc_attr( $view_object['mixins'] ) : false;

			$tdata_transient = array();
			$tdata_transient['is_single'] = isset( $view_object['single'] ) && filter_var( $view_object['single'], FILTER_VALIDATE_BOOLEAN ) ? true : false;
			$tdata_transient['filters'] = $has_filters ? WeeklyClass::get_filters_json( $data ) : array();
			$tdata_transient['options'] = array_merge( $data, array( 'el_id' => $id, 'mixins' => $mixins, 'is_single' => $tdata_transient['is_single'] ) );
			$tdata_transient['css'] 		= apply_filters( 'wcs_view_css', '', $data, $id );
			$tdata_transient['template'] = $template;
			$tdata_transient['template_filters'] = $template_filters;

			if( ! is_user_logged_in() && wp_validate_boolean( $settings['wcs_caching'] ) ){
				set_transient( 'wcs_tdata_' . $id, $tdata_transient, WEEK_IN_SECONDS );
			}

		}

		$data = $tdata_transient['options'];

		if( $tdata_transient['template'] !== false ){
			$template = wcs_get_template_part( 'display/' . $tdata_transient['template'] );
		}

		if( $tdata_transient['template_filters'] !== false ){
			$template_filters = wcs_get_template_part( 'filters/filters', $tdata_transient['template_filters'] );
		}

		if( ! $tdata_transient['is_single'] ){

			$days = isset( $data['days'] ) && $data['days'] !== 0 && $data['days'] !== '0' ? intval( $data['days'] ) : apply_filters( 'wcs_all_days', 365 * 5 );

			$start_tstamp = apply_filters( 'wcs_start', strtotime( date_i18n( 'Y/m/d', current_time( 'timestamp' ) ) ), $data );
			$stop_tstamp 	= apply_filters( 'wcs_stop', $start_tstamp + ( $days - 1 ) * DAY_IN_SECONDS, $data );

			$start 	= date_i18n( 'Y-m-d', $start_tstamp );
			$stop 	= date_i18n( 'Y-m-d', $stop_tstamp );

			$data['limit'] = apply_filters( 'wcs_schedule_limit', isset( $data['limit'] ) ? intval( $data['limit'] ) : 0, $data );

			$feed = wp_validate_boolean( $settings['wcs_lazy_load'] ) ? array() : WeeklyClass::get_events_json( true,
				array(
					'start' => $start,
					'end' => $stop,
					'limit' => $data['limit'],
					'content' => isset( $data['content'] ) && is_array( $data['content'] ) ? $data['content'] : array()
				)
			);

			$data['ts_start'] = $start;
			$data['ts_stop'] 	= $stop;

		}

		else {
			if( ! empty( $data['single'] ) ){
				$feed = WeeklyClass::get_event_json( $data['single'] );
			}
		}

		$view_object 	= self::get_view( $views, isset( $data['view'] ) ? $data['view'] : 0 );

		$prepend_filters = isset( $view_object['prepend_filters'] ) && ! wp_validate_boolean( $view_object['prepend_filters'] ) ? false : $prepend_filters;
		$template_filters = isset( $template_filters ) ? $template_filters : ( isset( $tdata_transient['template_filters'] ) ? $tdata_transient['template_filters'] : false );

		global $wcs_apps;

		$app_array = array(
			'id' => $id,
			'prepend_filters' => $prepend_filters,
			'template_filters' => $template_filters,
			'template' => $template
		);

		if( ! $wcs_apps ){
			$wcs_apps = array( $app_array );
		} else {
			$wcs_apps[] = $app_array;
		}

		ob_start();

		if( isset( $view_object['deps'] ) ){
			CurlyWeeklyClassShortcodes::set_dependency( $view_object['deps'] );
		}

		?>
		<div class="wcs-timetable__wrapper">
			<div class="wcs-vue" id="wcs-app-<?php echo $id ?>"></div>
		</div>
		<?php

			wp_localize_script( 'wcs-main', 'EventsSchedule_' . $id, array(
				'css' => apply_filters( 'wcs_minify_css', isset( $tdata_transient['css'] ) ? $tdata_transient['css'] : '' ),
				'feed' => isset( $feed ) ? $feed : array(),
				'filters' => isset( $tdata_transient['filters'] ) ? $tdata_transient['filters'] : array(),
				'options' => $data
			));

			global $wcs_has_shortcode;

			$wcs_has_shortcode = true;

			return ob_get_clean();

	    }

}


?>