%PDF- %PDF-
Direktori : /home/emergentqj/antanimora/wp-content/plugins/td-composer/legacy/common/wp_booster/ |
Current File : /home/emergentqj/antanimora/wp-content/plugins/td-composer/legacy/common/wp_booster/td_block.php |
<?php /** * Class td_block - base class for blocks * v 5.1 - td-composer edition :) */ class td_block { var $block_uid; // the block unique id on the page, it changes on every render var $td_query; //the query used to rendering the current block protected $td_block_template_data; private $atts = array(); //the atts used for rendering the current block private $td_block_template_instance; // the current block template instance that this block is using // by default all the blocks are loop blocks private $is_loop_block = true; // if it's a loop block, we will generate AJAX js, pulldown items and other stuff /** * the base render function. This is called by all the child classes of this class * @param $atts * @param $content * @return string '' */ function render($atts, $content = null) { // build the $this->atts $this->atts = (array) $atts; // bring default values for atts that are not set or that are missing // NOTE: atts that are already set in $atts remain the same (big blocks, mega menu and related articles set atts dynamically in the // shortcode) // NOTE 2: DOES NOT SUPPORT STYLES YET. we have to bring here the style atts also! $block_map = td_api_block::get_by_id(get_class($this)); if (isset($block_map['params'])) { $mapped_params = $block_map['params']; foreach ( $mapped_params as $mapped_param ) { $value = $mapped_param['value']; // for arrays if ( is_array( $value ) ) { if (empty($value)) { /** * some map helper functions return an empty array on the frontend for optimizations. * They don't load the full map only in wp-admin * @see td_util::get_block_template_ids * @see td_util::get_category2id_array */ $value = ''; } else { /** * if the array has values, we select the first one */ foreach ( $value as $key => $val ) { $value = $val; break; } } } $param_name = $mapped_param['param_name']; //var_dump($this->atts); if (!isset($this->atts[$param_name])) { $this->atts[$param_name] = $value; } } } $this->atts = $this->add_live_filter_atts($this->atts); // add live filter atts // !!!! code in this class relies on this to be set regardless of what is mapped. // !!!! ori le scoatem intr-o clasa separata pentru block-uri cu module ori scoatem dependinta pt atributele astea $this->set_default_atts(array( 'block_template_id' => '', 'td_column_number' => td_global::vc_get_column_number(), 'header_color' => '', 'ajax_pagination_infinite_stop' => '', 'offset' => '', 'limit' => '5', 'td_ajax_preloading' => '', 'td_ajax_filter_type' => '', 'td_filter_default_txt' => '', 'td_ajax_filter_ids' => '', 'el_class' => '', 'color_preset' => '', 'ajax_pagination' => '', 'border_top' => '', 'css' => '', //custom css - used by VC 'tdc_css' => '' )); //update unique id on each render $this->block_uid = td_global::td_generate_unique_id(); /** add the unique class to the block. The _rand class is used by the blocks js. @see tdBlocks.js */ $unique_block_class = $this->block_uid; $this->add_class($unique_block_class); // Set the 'tdc_css_class' parameter $this->atts['tdc_css_class'] = $unique_block_class; /** The _rand_style class is used by td-element-style to add style */ $unique_block_class_style = $this->block_uid . '_rand_style'; $this->atts['tdc_css_class_style'] = $unique_block_class_style; $td_pull_down_items = array(); // do the query and make the AJAX filter only on loop blocks if ($this->is_loop_block() === true) { //by ref do the query $this->td_query = &td_data_source::get_wp_query($this->atts); // get the pull down items $td_pull_down_items = $this->block_loop_get_pull_down_items(); } /** * Make a new block template instance (NOTE: ON EACH RENDER WE GENERATE A NEW BLOCK TEMPLATE) * td_block_template_x - Loaded via autoload * @see td_autoload_classes::loading_classes */ if (td_util::is_mobile_theme()) { // The mobile theme uses only 'td_block_template_1' (in api this is the only registered block template) $td_block_template_id = 'td_block_template_1'; } else { $td_block_template_id = $this->atts['block_template_id']; if ( empty( $td_block_template_id ) ) { $td_block_template_id = td_options::get( 'tds_global_block_template', 'td_block_template_1' ); } /** * This allows us to overwrite the block templates that are in the theme on each demo. * it loads the block template from the demo folder ONLY IF it exists * @since 7/12/2016 */ $demo_id = td_util::get_loaded_demo_id(); if ($demo_id !== false) { $custom_block_template_path = td_global::$demo_list[$demo_id]['folder'] . $td_block_template_id . '.php'; if (file_exists($custom_block_template_path)) { require_once $custom_block_template_path; } } } $this->td_block_template_data = array( 'atts' => $this->atts, 'block_uid' => $this->block_uid, 'unique_block_class' => $unique_block_class, 'td_pull_down_items' => $td_pull_down_items, ); $this->td_block_template_instance = new $td_block_template_id($this->td_block_template_data); return ''; } /** * @deprecated Fix the 8.6 - 8.7 transition. If the old td-composer plugin from 8.6 was used on 8.7 we got an error. * @param $atts */ function set_font_settings($atts) { } private function set_default_atts($default_atts) { foreach ($default_atts as $att => $att_value) { if (!isset($this->atts[$att])) { $this->atts[$att] = $att_value; } } } protected function get_custom_css() { return ''; } /** * Returns the block css. * * !!WARNING - blocks that don't use this will not work with the TD composer design tab when Visual Composer is disabled * BUT the block will work just fine when VC is enabled * @since 30 may 2016 - before it was echoed on render - no bueno */ protected function get_block_css() { $buffy_style = ''; $buffy = $this->block_template()->get_css(); $css = $this->get_att('css'); // VC adds the CSS att automatically so we don't have to do it if (!td_util::is_vc_installed() && !empty($css)) { $buffy .= PHP_EOL . '/* inline css att */' . PHP_EOL . $css; } $custom_css = $this->get_custom_css(); if (!empty($custom_css)) { $buffy_style .= PHP_EOL . '<style>' . PHP_EOL . '/* custom css */' . PHP_EOL . $custom_css . PHP_EOL . '</style>'; } $tdcCss = $this->get_att('tdc_css'); $clearfixColumns = false; $cssOutput = ''; $beforeCssOutput = ''; $afterCssOutput = ''; if (!empty($tdcCss)) { $buffy .= $this->generate_css($tdcCss, $clearfixColumns, $cssOutput, $beforeCssOutput, $afterCssOutput ); } if (!empty($buffy)) { $buffy = PHP_EOL . '<style>' . PHP_EOL . $buffy . PHP_EOL . '</style>'; $buffy_style = $buffy . $buffy_style; } $tdcElementStyleCss = ''; if ( !empty($cssOutput) || !empty($beforeCssOutput) || !empty($afterCssOutput) ) { if ( !empty($beforeCssOutput) ) { $beforeCssOutput = PHP_EOL . '<div class="td-element-style-before"><style>' . $beforeCssOutput . '</style></div>'; } $tdcElementStyleCss = PHP_EOL . '<div class="' . $this->get_att( 'tdc_css_class_style' ) . ' td-element-style">' . $beforeCssOutput . '<style>' . $cssOutput . ' ' . $afterCssOutput . '</style></div>'; } if (!empty($buffy_style)) { if (!empty($tdcElementStyleCss)) { return $buffy_style . $tdcElementStyleCss; } return $buffy_style; } else if (!empty($tdcElementStyleCss)) { return $tdcElementStyleCss; } return ''; } private function getBorderWidth($borderWidthCssProps) { $borderWidthCss = ''; $borderSet = false; $borderSettings = array( 'border-top-width' => '0px', 'border-right-width' => '0px', 'border-bottom-width' => '0px', 'border-left-width' => '0px', ); foreach ($borderWidthCssProps as $key => $val) { switch ($key) { case 'border-top-width': if (!empty($val)) { $borderSet = true; $borderSettings[$key] = $val; } break; case 'border-right-width': if (!empty($val)) { $borderSet = true; $borderSettings[$key] = $val; } break; case 'border-bottom-width': if (!empty($val)) { $borderSet = true; $borderSettings[$key] = $val; } break; case 'border-left-width': if (!empty($val)) { $borderSet = true; $borderSettings[$key] = $val; } break; } } if ($borderSet) { $borderWidthCss = 'border-width:'; foreach ($borderSettings as $key => $val) { $borderWidthCss .= ' ' . $val; } $borderWidthCss .= ' !important;' . PHP_EOL; } return $borderWidthCss; } /** * Generate css for blocks, inner columns, inner rows, columns and rows * For inner rows and rows a new '.tdc-css' child element is added and its css is generated (This solution was adopted because we need an ::after element, and rows and inner rows already have an ::after element) * * @param $tdcCss - the property that will be decoded and parsed * @param bool $clearfixColumns - flag used to know outside if the '.clearfix' element is added as last child in vc_row and vc_row_inner * @param string $cssOutput - css output for td-element-style * @param string $beforeCssOutput - css output for td-element-style::before * @param string $afterCssOutput - css output for td-element-style::after * * @return string */ protected function generate_css( $tdcCss, &$clearfixColumns = false, &$cssOutput = '', &$beforeCssOutput = '', &$afterCssOutput = '' ) { // // Very Important! For stretched rows move the 'border' css settings on ::before, for all viewport settings // $moveBorderSettingsOnBefore = false; if (class_exists('vc_row') && $this instanceof vc_row ) { // Important! get_custom_att was introduced in composer only after 01.08.2017 (because 'full_width' att was moved from tdc_composer_block to vc_row) // This check is done to allow older versions of composer to use 'full_width'. if ( method_exists( $this, 'get_custom_att' ) ) { $attFullWidth = $this->get_custom_att( 'full_width' ); } else { $attFullWidth = $this->get_att( 'full_width' ); } if ($attFullWidth !== '') { $moveBorderSettingsOnBefore = true; } } $buffy = ''; $tdcCssDecoded = false; if ( td_util::tdc_is_installed() ) { $tdcCssDecoded = tdc_b64_decode($tdcCss); } if ( $tdcCssDecoded !== false ) { $tdcCssArray = json_decode( $tdcCssDecoded, true ); if (!is_null($tdcCssArray) && is_array($tdcCssArray)) { $tdcCssProcessed = ''; // Values of these properties must be numeric $numericCssProps = array( 'border-radius', 'width', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 'shadow-size', 'shadow-offset-h', 'shadow-offset-v', ); $borderWidthCssProps = array( 'border-top-width' => '', 'border-right-width' => '', 'border-bottom-width' => '', 'border-left-width' => '', ); $beforeCssProps = array( 'background-image', 'background-size', 'background-position', 'background-repeat', 'opacity', ); $elementStyleProps = array( 'background-color', ); if ($moveBorderSettingsOnBefore) { $beforeCssProps[] = 'border-style'; $beforeCssProps[] = 'border-color'; $beforeCssProps[] = 'border-width'; $beforeCssProps[] = 'border-top-width'; $beforeCssProps[] = 'border-right-width'; $beforeCssProps[] = 'border-bottom-width'; $beforeCssProps[] = 'border-left-width'; } $afterCssProps = array( 'color-1-overlay', 'color-2-overlay', 'gradient-direction', ); $cssBeforeSettings = "content:'' !important;" . PHP_EOL . "width:100% !important;" . PHP_EOL . "height:100% !important;" . PHP_EOL . "position:absolute !important;" . PHP_EOL . "top:0 !important;" . PHP_EOL . "left:0 !important;" . PHP_EOL . "display:block !important;" . PHP_EOL . "z-index:0 !important;" . PHP_EOL; $cssAfterSettings = "content:'' !important;" . PHP_EOL . "width:100% !important;" . PHP_EOL . "height:100% !important;" . PHP_EOL . "position:absolute !important;" . PHP_EOL . "top:0 !important;" . PHP_EOL . "left:0 !important;" . PHP_EOL . "z-index:0 !important;" . PHP_EOL . "display:block !important;" . PHP_EOL; $mediaCssAll = ''; $cssBeforeAll = ''; $cssElementStyleAll = ''; $cssAfterAll = array(); $mediaCssDesktop = ''; $borderInAll = false; $backgroundInAll = false; // 'all' css settings if (array_key_exists('all', $tdcCssArray)) { foreach ($tdcCssArray['all'] as $k1 => $v1) { if (in_array($k1, $numericCssProps) && is_numeric($v1)) { $v1 .= 'px'; } // Check for 'border' // Default values are added! if (!$borderInAll && strpos($k1, 'border') !== false) { $borderInAll = true; } // Check for 'background' // Default values are added! if (!$backgroundInAll && strpos($k1, 'background') !== false) { $backgroundInAll = true; } if ('background-style' === $k1) { $setting = 'background-size'; if ($v1 === 'repeat' || $v1 === 'no-repeat') { $setting = 'background-repeat'; } else if ($v1 === 'contain') { $cssBeforeAll .= 'background-repeat: no-repeat !important;' . PHP_EOL; } $cssBeforeAll .= $setting . ':' . $v1 . ' !important;' . PHP_EOL; continue; } if (array_key_exists($k1, $borderWidthCssProps)) { $borderWidthCssProps[$k1] = $v1; continue; } // if (array_key_exists($k1, $beforeCssProps)) { // $beforeCssProps[$k1] = $v1; // continue; // } if (in_array($k1, $elementStyleProps)) { $cssElementStyleAll .= $k1 . ':' . $v1 . ' !important;' . PHP_EOL; continue; } if (in_array($k1, $beforeCssProps)) { $cssBeforeAll .= $k1 . ':' . $v1 . ' !important;' . PHP_EOL; continue; } if (in_array($k1, $afterCssProps)) { $cssAfterAll[$k1] = $v1; continue; } if ( 'content-h-align' === $k1 ) { $k1 = 'text-align'; $v1 = str_replace( 'content-horiz-', '', $v1 ); // These settings were introduced because of vertical align switch ( $v1 ){ case 'center' : $mediaCssAll .= 'justify-content:center !important;' . PHP_EOL; break; case 'right' : $mediaCssAll .= 'justify-content:flex-end !important;' . PHP_EOL; break; } } // Shadow settings if ( 'shadow-size' === $k1 && ! empty( $v1 ) ) { $shadow_offset_h = 0; if ( ! empty( $tdcCssArray['all']['shadow-offset-h'] ) ) { $shadow_offset_h = $tdcCssArray['all']['shadow-offset-h'] . 'px'; } $shadow_offset_v = 0; if ( ! empty( $tdcCssArray['all']['shadow-offset-v'] ) ) { $shadow_offset_v = $tdcCssArray['all']['shadow-offset-v'] . 'px'; } $shadow_color = '#888888'; if ( ! empty( $tdcCssArray['all']['shadow-color'] ) ) { $shadow_color = $tdcCssArray['all']['shadow-color']; } $mediaCssAll .= 'box-shadow:' . $shadow_offset_h . ' ' . $shadow_offset_v . ' ' . $v1 . ' ' . $shadow_color . ' !important;' . PHP_EOL; continue; } if ( in_array( $k1, array( 'shadow-color', 'shadow-offset-h', 'shadow-offset-v' ) ) ) { continue; } // Display settings if ( 'display' === $k1 ) { if ( 'show' !== $v1 && '' !== $v1 ) { $mediaCssDesktop .= $k1 . ':' . $v1 . ' !important;' . PHP_EOL; } continue; } $mediaCssAll .= $k1 . ':' . $v1 . ' !important;' . PHP_EOL; } // Add default value for 'border-style' // Add default value for 'border-color' if ($borderInAll) { if (!isset($tdcCssArray['all']['border-style'])) { if ($moveBorderSettingsOnBefore) { $cssBeforeAll .= 'border-style:solid !important;' . PHP_EOL; } else { $mediaCssAll .= 'border-style:solid !important;' . PHP_EOL; } } if (!isset($tdcCssArray['all']['border-color'])) { if ($moveBorderSettingsOnBefore) { $cssBeforeAll .= 'border-color:#888888 !important;' . PHP_EOL; } else { $mediaCssAll .= 'border-color:#888888 !important;' . PHP_EOL; } } if (!isset($tdcCssArray['all']['border-top-width']) && !isset($tdcCssArray['all']['border-right-width']) && !isset($tdcCssArray['all']['border-bottom-width']) && !isset($tdcCssArray['all']['border-left-width'])) { if ($moveBorderSettingsOnBefore) { $cssBeforeAll .= 'border-width:0 !important;' . PHP_EOL; } else { $mediaCssAll .= 'border-width:0 !important;' . PHP_EOL; } } } // Set border width css for 'all' $borderCss = $this->getBorderWidth($borderWidthCssProps); if ($borderCss !== '') { if ($moveBorderSettingsOnBefore) { $cssBeforeAll .= $borderCss; } else { $mediaCssAll .= $borderCss; } } $positionElement = false; // all td-element-style if ($cssElementStyleAll !== '') { $cssOutput .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class_style' ) . '{' . PHP_EOL . $cssElementStyleAll . '}' . PHP_EOL; $positionElement = true; } // all td-element-style::before if ($cssBeforeAll !== '') { // Add default value for 'background-size' if ($backgroundInAll) { if (!isset($tdcCssArray['all']['background-style'])) { $cssBeforeAll .= 'background-size:cover !important;' . PHP_EOL; } if (!isset($tdcCssArray['all']['background-position'])) { $cssBeforeAll .= 'background-position:center top !important;' . PHP_EOL; } } //$tdcCssProcessed .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class' ) . '::before{' . PHP_EOL . $cssBeforeSettings . $cssBeforeAll . '}' . PHP_EOL; $beforeCssOutput .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class_style' ) . ' > .td-element-style-before {' . PHP_EOL . $cssBeforeSettings . $cssBeforeAll . '}' . PHP_EOL; $positionElement = true; } // all td-element-style::after if (!empty($cssAfterAll)) { $css = ''; $deg = ''; if (array_key_exists('gradient-direction', $cssAfterAll )) { $deg = $cssAfterAll['gradient-direction'] . 'deg,'; } if (array_key_exists('color-1-overlay', $cssAfterAll) && array_key_exists('color-2-overlay', $cssAfterAll)) { $css .= 'background: linear-gradient(' . $deg . $cssAfterAll['color-1-overlay'] . ', ' . $cssAfterAll['color-2-overlay'] . ') !important;' . PHP_EOL; } else if (array_key_exists('color-1-overlay', $cssAfterAll)) { $css .= 'background: ' . $cssAfterAll['color-1-overlay'] .' !important;' . PHP_EOL; } else if (array_key_exists('color-2-overlay', $cssAfterAll)) { $css .= 'background: ' . $cssAfterAll['color-2-overlay'] .' !important;' . PHP_EOL; } if (array_key_exists('opacity', $cssAfterAll)) { $css .= 'opacity: ' . $cssAfterAll['opacity'] .' !important;' . PHP_EOL; } if ( '' !== $css ) { // Important! if ( $this instanceof vc_row || $this instanceof vc_row_inner ) { $clearfixColumns = true; } //$tdcCssProcessed .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class' ) . $childElement . '::after{' . PHP_EOL . $cssAfterSettings . $css . '}' . PHP_EOL; $afterCssOutput .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class_style' ) . '::after {' . PHP_EOL . $cssAfterSettings . $css . '}' . PHP_EOL; $positionElement = true; } } if ($positionElement) { $mediaCssAll .= 'position:relative;' . PHP_EOL; } // all css if ($mediaCssAll !== '') { $tdcCssProcessed .= PHP_EOL . '.' . $this->get_att('tdc_css_class') . '{' . PHP_EOL . $mediaCssAll . '}' . PHP_EOL; if ((class_exists('vc_row') && $this instanceof vc_row) || (class_exists('vc_row_inner') && $this instanceof vc_row_inner)) { $tdcCssProcessed .= PHP_EOL . '.' . $this->get_att('tdc_css_class') . ' .td_block_wrap{ text-align:left }' . PHP_EOL; } } // desktop css if ($mediaCssDesktop !== '') { $limit_bottom = td_global::$td_viewport_intervals[ count( td_global::$td_viewport_intervals ) - 1 ]['limitBottom']; $tdcCssProcessed .= PHP_EOL . '/* desktop */ @media(min-width: ' . ( $limit_bottom + 1 ) . 'px) { ' . '.' . $this->get_att('tdc_css_class') . ' { ' . PHP_EOL . $mediaCssDesktop . '} }' . PHP_EOL; } // Temporarily commented //unset($tdcCssArray['all']); } // !!!! The css media queries must be output in reverse order. Maybe this generated css should be managed all at once, in page. // Multiple solutions have been tested to sort them in reverse order at creation. Issues: json.stringify work well only with object, and an object does not keep the order of its properties. // For this, javascript array should be used, but in that case, an array with undefined elements it would be created by json_decode php function. So, not good. $limits = array(); foreach ($tdcCssArray as $key => $val) { if (stripos($key, '_max_width') !== false) { $new_key = str_replace('_max_width', '', $key); if ( !isset($limits[$new_key])) { $limits[$new_key] = array(); } $limits[$new_key]['max_width'] = $val; } if (stripos($key, '_min_width') !== false) { $new_key = str_replace( '_min_width', '', $key); if (!isset($limits[$new_key])) { $limits[$new_key] = array(); } $limits[$new_key]['min_width'] = $val; } } foreach ($limits as $key => $val) { $mediaArray = $tdcCssArray[ $key ]; $mediaCss = ''; $cssBefore = ''; $cssElementStyle = ''; $cssAfter = array(); $borderInLimit = false; $backgroundInLimit = false; // Reset $beforeCss foreach ($borderWidthCssProps as $borderCssKey => $borderCssValue) { $borderWidthCssProps[$borderCssKey] = ''; } // // Reset $beforeCssProps // foreach ($beforeCssProps as $beforeCssKey => $beforeCssValue) { // $beforeCssProps[$beforeCssKey] = ''; // } foreach ($mediaArray as $k2 => $v2) { if (in_array($k2, $numericCssProps) && is_numeric($v2)) { $v2 .= 'px'; } // Check for 'border' // Default values are added! if (!$borderInLimit && strpos($k2, 'border') !== false) { $borderInLimit = true; } // Check for 'background' // Default values are added! if (!$backgroundInLimit && strpos($k2, 'background') !== false) { $backgroundInLimit = true; } if ('background-style' === $k2) { $setting = 'background-size'; if ($v2 === 'repeat' || $v2 === 'no-repeat') { $setting = 'background-repeat'; } else if ($v2 === 'contain') { $cssBeforeAll .= 'background-repeat: no-repeat !important;' . PHP_EOL; } $cssBeforeAll .= $setting . ':' . $v2 . ' !important;' . PHP_EOL; continue; } if (array_key_exists($k2, $borderWidthCssProps)) { $borderWidthCssProps[$k2] = $v2; continue; } // Change to 'transparent' for 'border-color: no_value' // Change to 'transparent' for 'background-color: no_value' // Change to 'transparent' for 'color-1-overlay: no_value' // Change to 'transparent' for 'color-2-overlay: no_value' // Change to 'none' for 'background-image: no_value' if ($v2 === 'no_value') { switch ($k2) { case 'border-color': case 'background-color': case 'color-1-overlay': case 'color-2-overlay': $v2 = 'transparent'; break; case 'background-image': $v2 = 'none'; break; } } // if (array_key_exists($k2, $beforeCssProps)) { // $beforeCssProps[$k2] = $v2; // continue; // } if (in_array($k2, $elementStyleProps)) { $cssElementStyle .= $k2 . ':' . $v2 . ' !important;' . PHP_EOL; continue; } if (in_array($k2, $beforeCssProps)) { $cssBefore .= $k2 . ':' . $v2 . ' !important;' . PHP_EOL; continue; } if (in_array($k2, $afterCssProps)) { $cssAfter[$k2] = $v2; continue; } if ( 'content-h-align' === $k2 ) { $k2 = 'text-align'; $v2 = str_replace( 'content-horiz-', '', $v2 ); // These settings were introduced because of vertical align switch ( $v2 ){ case 'center' : $mediaCss .= 'justify-content:center !important;' . PHP_EOL; break; case 'right' : $mediaCss .= 'justify-content:flex-end !important;' . PHP_EOL; break; } } // Do nothing for these keys - they will be checked later if ( in_array( $k2, array( 'shadow-size', 'shadow-color', 'shadow-offset-h', 'shadow-offset-v' ) ) ) { continue; } // Display if ( 'display' === $k2 ) { if ( 'show' !== $v2 && '' !== $v2 ) { $mediaCss .= $k2 . ':' . $v2 . ' !important;' . PHP_EOL; } continue; } $mediaCss .= $k2 . ':' . $v2 . ' !important;' . PHP_EOL; } // Shadow settings $shadow_size = 0; if ( array_key_exists( 'shadow-size', $mediaArray ) ) { $shadow_size = $mediaArray['shadow-size'] . 'px'; } // check media-all if ( empty( $shadow_size ) && array_key_exists('all', $tdcCssArray) && array_key_exists( 'shadow-size', $tdcCssArray['all'] ) && ! empty( $tdcCssArray['all']['shadow-size'] ) ) { $shadow_size = $tdcCssArray['all']['shadow-size'] . 'px'; } if ( ! empty( $shadow_size ) ) { $shadow_offset_h = 0; if ( array_key_exists( 'shadow-offset-h', $mediaArray ) ) { $shadow_offset_h = $mediaArray['shadow-offset-h'] . 'px'; } if ( empty( $shadow_offset_h ) && ! empty( $tdcCssArray['all'] ) && array_key_exists( 'shadow-offset-h', $tdcCssArray['all'] ) && ! empty( $tdcCssArray['all']['shadow-offset-h'] ) ) { $shadow_offset_h = $tdcCssArray['all']['shadow-offset-h'] . 'px'; } $shadow_offset_v = 0; if ( array_key_exists( 'shadow-offset-v', $mediaArray ) ) { $shadow_offset_v = $mediaArray['shadow-offset-v'] . 'px'; } if ( empty( $shadow_offset_v ) && ! empty( $tdcCssArray['all'] ) && array_key_exists( 'shadow-offset-v', $tdcCssArray['all'] ) && ! empty( $tdcCssArray['all']['shadow-offset-v'] ) ) { $shadow_offset_v = $tdcCssArray['all']['shadow-offset-v'] . 'px'; } $shadow_color = 0; if ( array_key_exists( 'shadow-color', $mediaArray ) ) { $shadow_color = $mediaArray['shadow-color']; } if ( empty( $shadow_color ) ) { if ( ! empty( $tdcCssArray['all'] ) && array_key_exists( 'shadow-color', $tdcCssArray['all'] ) && ! empty( $tdcCssArray['all']['shadow-color'] ) ) { $shadow_color = $tdcCssArray['all']['shadow-color']; } else { $shadow_color = '#888888'; } } $mediaCss .= 'box-shadow:' . $shadow_offset_h . ' ' . $shadow_offset_v . ' ' . $shadow_size . ' ' . $shadow_color . ' !important;' . PHP_EOL; } // Add default value for 'border-style' // Add default value for 'border-color' if ($borderInLimit && !$borderInAll) { if (!isset($mediaArray['border-style'])) { if ($moveBorderSettingsOnBefore) { $cssBefore .= 'border-style:solid !important;' . PHP_EOL; } else { $mediaCss .= 'border-style:solid !important;' . PHP_EOL; } } if (!isset($mediaArray['border-color'])) { if ($moveBorderSettingsOnBefore) { $cssBefore .= 'border-color:#888888 !important;' . PHP_EOL; } else { $mediaCss .= 'border-color:#888888 !important;' . PHP_EOL; } } } // Set border width css for 'all' $borderCss = $this->getBorderWidth($borderWidthCssProps); if ($borderCss !== '') { if ($moveBorderSettingsOnBefore) { $cssBefore .= $borderCss; } else { $mediaCss .= $borderCss; } } // // Set background css for limit // $backgroundCss = $this->getBackground($beforeCssProps); // // if ($backgroundCss !== '') { // $mediaCss .= $backgroundCss; // } if ( $cssElementStyle !== '' || $cssBefore !== '' || $cssAfter !== '') { $mediaQuery = ''; if ( isset( $val['min_width'] ) ) { $mediaQuery = '(min-width: ' . $val['min_width'] . 'px)'; } if ( isset( $val['max_width'] ) ) { if ( '' !== $mediaQuery ) { $mediaQuery .= ' and '; } $mediaQuery .= '(max-width: ' . $val['max_width'] . 'px)'; } if ( '' !== $mediaQuery ) { $positionElement = false; if ($cssElementStyle !== '') { $cssOutput .= PHP_EOL . '/* ' . $key . ' */' . PHP_EOL; $cssOutput .= '@media ' . $mediaQuery . PHP_EOL; $cssOutput .= '{'. PHP_EOL; $cssOutput .= '.' . $this->get_att('tdc_css_class_style') . '{' . PHP_EOL . $cssElementStyle . '}' . PHP_EOL; $cssOutput .= '}'. PHP_EOL; $positionElement = true; } if ($cssBefore !== '') { // Add default value for 'background-style' if ($backgroundInLimit && !$backgroundInAll) { if (!isset($mediaArray['background-style'])) { $cssBefore .= 'background-size:cover !important;' . PHP_EOL; } if (!isset($mediaArray['background-position'])) { $cssBefore .= 'background-position:center top !important;' . PHP_EOL; } } //$tdcCssProcessed .= '.' . $this->get_att('tdc_css_class') . '::before{' . PHP_EOL . $cssBeforeSettings . $cssBefore . '}' . PHP_EOL; $beforeCssOutput .= PHP_EOL . '/* ' . $key . ' */' . PHP_EOL; $beforeCssOutput .= '@media ' . $mediaQuery . PHP_EOL; $beforeCssOutput .= '{'. PHP_EOL; //$beforeCssOutput .= '.' . $this->get_att('tdc_css_class_style') . '::before{' . PHP_EOL . $cssBeforeSettings . $cssBefore . '}' . PHP_EOL; $beforeCssOutput .= '.' . $this->get_att('tdc_css_class_style') . ' > .td-element-style-before{' . PHP_EOL . $cssBeforeSettings . $cssBefore . '}' . PHP_EOL; $beforeCssOutput .= '}'. PHP_EOL; $positionElement = true; } if (!empty($cssAfter)) { $css = ''; $deg = ''; if (array_key_exists('gradient-direction', $cssAfter )) { $deg = $cssAfter['gradient-direction'] . 'deg,'; } if (array_key_exists('color-1-overlay', $cssAfter) && array_key_exists('color-2-overlay', $cssAfter)) { $css .= 'background: linear-gradient(' . $deg . $cssAfter['color-1-overlay'] . ', ' . $cssAfter['color-2-overlay'] . ') !important;' . PHP_EOL; } else if (array_key_exists('color-1-overlay', $cssAfter)) { if (array_key_exists('color-2-overlay', $cssAfterAll)) { $css .= 'background: linear-gradient(' . $deg . $cssAfter['color-1-overlay'] . ', ' . $cssAfterAll['color-2-overlay'] . ') !important;' . PHP_EOL; } else { $css .= 'background: ' . $cssAfter['color-1-overlay'] .' !important;' . PHP_EOL; } } else if (array_key_exists('color-2-overlay', $cssAfter)) { if (array_key_exists('color-1-overlay', $cssAfterAll)) { $css .= 'background: linear-gradient(' . $deg . $cssAfterAll['color-1-overlay'] . ', ' . $cssAfter['color-2-overlay'] . ') !important;' . PHP_EOL; } else { $css .= 'background: ' . $cssAfter['color-2-overlay'] .' !important;' . PHP_EOL; } } else { $css .= 'background: linear-gradient(' . $deg . $cssAfterAll['color-1-overlay'] . ', ' . $cssAfterAll['color-2-overlay'] . ') !important;' . PHP_EOL; } if (array_key_exists('opacity', $cssAfter)) { $css .= 'opacity: ' . $cssAfter['opacity'] .' !important;' . PHP_EOL; } if ( '' !== $css ) { // Important! if ( $this instanceof vc_row || $this instanceof vc_row_inner ) { $clearfixColumns = true; } //$tdcCssProcessed .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class' ) . $childElement . '::after{' . PHP_EOL . $cssAfterSettings . $css . '}' . PHP_EOL; $afterCssOutput .= PHP_EOL . '/* ' . $key . ' */' . PHP_EOL; $afterCssOutput .= '@media ' . $mediaQuery . PHP_EOL; $afterCssOutput .= '{'. PHP_EOL; $afterCssOutput .= PHP_EOL . '.' . $this->get_att( 'tdc_css_class_style' ) . '::after{' . PHP_EOL . $cssAfterSettings . $css . '}' . PHP_EOL; $afterCssOutput .= '}'. PHP_EOL; $positionElement = true; } } if ($positionElement) { $mediaCss .= 'position:relative;' . PHP_EOL; } if ($mediaCss !== '') { $tdcCssProcessed .= PHP_EOL . '/* ' . $key . ' */' . PHP_EOL; $tdcCssProcessed .= '@media ' . $mediaQuery . PHP_EOL; $tdcCssProcessed .= '{' . PHP_EOL; $tdcCssProcessed .= '.' . $this->get_att( 'tdc_css_class' ) . '{' . PHP_EOL . $mediaCss . '}' . PHP_EOL; $tdcCssProcessed .= '}' . PHP_EOL; } } } } if (!empty($tdcCssProcessed)) { $buffy .= PHP_EOL . '/* inline tdc_css att */' . PHP_EOL . $tdcCssProcessed; } } } return $buffy; } /** * This runs only on loop blocks! * @return array the $td_pull_down_items */ private function block_loop_get_pull_down_items() { $td_pull_down_items = array(); $td_ajax_filter_type = $this->get_att('td_ajax_filter_type'); $td_filter_default_txt = $this->get_att('td_filter_default_txt'); $td_ajax_filter_ids = $this->get_att('td_ajax_filter_ids'); // td_block_mega_menu has it's own pull down implementation! if (get_class($this) != 'td_block_mega_menu') { // prepare the array for the td_pull_down_items, we send this array to the block_template if (!empty($td_ajax_filter_type)) { // make the default current pull down item (the first one is the default) $td_pull_down_items[0] = array ( 'name' => $td_filter_default_txt, 'id' => '' ); switch($td_ajax_filter_type) { case 'td_category_ids_filter': // by category $td_categories = get_categories(array( 'include' => $td_ajax_filter_ids, 'exclude' => '1', 'number' => 100 //limit the number of categories shown in the drop down )); // check if there's any id in the list if (!empty($td_ajax_filter_ids)) { // break the categories string $td_ajax_filter_ids = explode(',', $td_ajax_filter_ids); // order the categories - match the order set in the block settings foreach ($td_ajax_filter_ids as $td_category_id) { $td_category_id = trim($td_category_id); foreach ($td_categories as $td_category) { // retrieve the category if ($td_category_id == $td_category->cat_ID) { $td_pull_down_items [] = array( 'name' => $td_category->name, 'id' => $td_category->cat_ID, ); break; } } } // if no category ids are added } else { foreach ($td_categories as $td_category) { $td_pull_down_items [] = array( 'name' => $td_category->name, 'id' => $td_category->cat_ID, ); } } break; case 'td_author_ids_filter': // by author $td_authors = get_users(array('who' => 'authors', 'include' => $td_ajax_filter_ids)); foreach ($td_authors as $td_author) { $td_pull_down_items []= array ( 'name' => $td_author->display_name, 'id' => $td_author->ID, ); } break; case 'td_tag_slug_filter': // by tag slug $tag_ids = explode(',', trim($td_ajax_filter_ids)); $td_tags = get_tags(array( 'include' => $tag_ids, 'orderby' => 'include' )); foreach ($td_tags as $td_tag) { $td_pull_down_items []= array ( 'name' => $td_tag->name, 'id' => $td_tag->term_id, ); } break; case 'td_popularity_filter_fa': // by popularity $td_pull_down_items []= array ( 'name' => __td('Featured', TD_THEME_NAME), 'id' => 'featured', ); $td_pull_down_items []= array ( 'name' => __td('All time popular', TD_THEME_NAME), 'id' => 'popular', ); break; } } } return $td_pull_down_items; } /** * this function adds the live filters atts when $atts['live_filter'] is set. The attributs are imidiatly available to all * after the render method is called * - $atts['live_filter_cur_post_id'] - the current post id * - $atts['live_filter_cur_post_author'] - the current post author * @since 21.2.2018 - leave the live_filter_cur_post_id & live_filter_cur_post_author alone if they are sent via the shortcode atts. * Why? We manually send them in tagDiv Template Builder * @param $atts * @return mixed */ private function add_live_filter_atts($atts) { if (!empty($atts['live_filter'])) { if (!isset($atts['live_filter_cur_post_id'])) { $atts['live_filter_cur_post_id'] = get_queried_object_id(); //add the current post id } if (!isset($atts['live_filter_cur_post_author'])) { $atts['live_filter_cur_post_author'] = get_post_field( 'post_author', $atts['live_filter_cur_post_id']); //get the current author } } return $atts; } /** * Used by blocks that need auto generated titles * @return string */ function get_block_title() { return $this->block_template()->get_block_title(); } /** * shows a pull down filter based on the $this->atts * @return string */ function get_pull_down_filter() { return $this->block_template()->get_pull_down_filter(); } /** * retrivs the block pagination * @return string */ function get_block_pagination($prev_icon = '', $nex_icon = '') { $offset = 0; if (isset($this->atts['offset'])) { $offset = (int)$this->atts['offset']; } $buffy = ''; $ajax_pagination = $this->get_att('ajax_pagination'); $limit = (int)$this->get_att('limit'); switch ($ajax_pagination) { case 'next_prev': if ( $prev_icon == '' ) { $prev_icon = 'td-icon-font td-icon-menu-left'; } if ( $nex_icon == '' ) { $nex_icon = 'td-icon-font td-icon-menu-right'; } $buffy .= '<div class="td-next-prev-wrap">'; $buffy .= '<a href="#" class="td-ajax-prev-page ajax-page-disabled" id="prev-page-' . $this->block_uid . '" data-td_block_id="' . $this->block_uid . '"><i class="' . $prev_icon . '"></i></a>'; //if ($this->td_query->found_posts <= $limit) { if ($this->td_query->found_posts - $offset <= $limit) { //hide next page because we don't have enough results $buffy .= '<a href="#" class="td-ajax-next-page ajax-page-disabled" id="next-page-' . $this->block_uid . '" data-td_block_id="' . $this->block_uid . '"><i class="' . $nex_icon . '"></i></a>'; } else { $buffy .= '<a href="#" class="td-ajax-next-page" id="next-page-' . $this->block_uid . '" data-td_block_id="' . $this->block_uid . '"><i class="' . $nex_icon . '"></i></a>'; } $buffy .= '</div>'; break; case 'load_more': if ( $nex_icon == '' ) { $nex_icon = 'td-icon-font td-icon-menu-down'; } //if ($this->td_query->found_posts > $limit) { if ($this->td_query->found_posts - $offset > $limit) { $buffy .= '<div class="td-load-more-wrap">'; $buffy .= '<a href="#" class="td_ajax_load_more td_ajax_load_more_js" id="next-page-' . $this->block_uid . '" data-td_block_id="' . $this->block_uid . '">' . __td('Load more', TD_THEME_NAME); $buffy .= '<i class="' . $nex_icon . '"></i>'; $buffy .= '</a>'; $buffy .= '</div>'; } break; case 'infinite': // show the infinite pagination only if we have more posts if ($this->td_query->found_posts - $offset > $limit) { $buffy .= '<div class="td_ajax_infinite" id="next-page-' . $this->block_uid . '" data-td_block_id="' . $this->block_uid . '">'; $buffy .= ' '; $buffy .= '</div>'; $buffy .= '<div class="td-load-more-wrap td-load-more-infinite-wrap" id="infinite-lm-' . $this->block_uid . '">'; $buffy .= '<a href="#" class="td_ajax_load_more td_ajax_load_more_js" id="next-page-' . $this->block_uid . '" data-td_block_id="' . $this->block_uid . '">' . __td('Load more', TD_THEME_NAME); $buffy .= '<i class="td-icon-font td-icon-menu-down"></i>'; $buffy .= '</a>'; $buffy .= '</div>'; } break; } return $buffy; } function get_block_js() { // td-composer PLUGIN uses this hook to call $this->js_callback_ajax // @see tdc_ajax.php -> on_ajax_render_shortcode in td-composer do_action('td_block__get_block_js', array(&$this)); // Allow the scripts of mega menu blocks if (!($this instanceof td_block_mega_menu) && td_util::tdc_is_live_editor_iframe()) { td_js_buffer::add_to_footer($this->js_tdc_get_composer_block()); return ''; } // do not run in ajax requests if (td_util::tdc_is_live_editor_ajax()) { return ''; } //get the js for this block - do not load it in inline mode in visual composer if (td_util::vc_is_inline()) { return ''; } // do not output the block js if it's not a loop block if ($this->is_loop_block() === false) { return ''; } // new tdBlock() item for ajax blocks / loop_blocks // we don't get here on blocks that are not loop blocks $block_item = 'block_' . $this->block_uid; $buffy = '<script>'; $atts = $this->atts; $buffy .= 'var ' . $block_item . ' = new tdBlock();' . "\n"; $buffy .= $block_item . '.id = "' . $this->block_uid . '";' . "\n"; $buffy .= $block_item . ".atts = '" . str_replace("'", "\u0027", json_encode($this->atts)) . "';" . "\n"; $buffy .= $block_item . '.td_column_number = "' . $atts['td_column_number'] . '";' . "\n"; $buffy .= $block_item . '.block_type = "' . get_class($this) . '";' . "\n"; //wordpress wp query parms $buffy .= $block_item . '.post_count = "' . $this->td_query->post_count . '";' . "\n"; $buffy .= $block_item . '.found_posts = "' . $this->td_query->found_posts . '";' . "\n"; $buffy .= $block_item . '.header_color = "' . $atts['header_color'] . '";' . "\n"; // the header_color is needed for the animated loader $buffy .= $block_item . '.ajax_pagination_infinite_stop = "' . $atts['ajax_pagination_infinite_stop'] . '";' . "\n"; // The max_num_pages is computed so it considers the offset and the limit atts settings // There were necessary these changes because on the user interface there are js scripts that use the max_num_pages js variable to show/hide some ui components if (!empty($this->atts['offset'])) { if ($this->atts['limit'] != 0) { $buffy .= $block_item . '.max_num_pages = "' . ceil( ( $this->td_query->found_posts - $this->atts['offset'] ) / $this->atts['limit'] ) . '";' . "\n"; } else if (get_option('posts_per_page') != 0) { $buffy .= $block_item . '.max_num_pages = "' . ceil( ( $this->td_query->found_posts - $this->atts['offset'] ) / get_option('posts_per_page') ) . '";' . "\n"; } } else { $buffy .= $block_item . '.max_num_pages = "' . $this->td_query->max_num_pages . '";' . "\n"; } $buffy .= 'tdBlocksArray.push(' . $block_item . ');' . "\n"; $buffy .= '</script>'; $td_column_number = $this->get_att('td_column_number'); if (empty($td_column_number)) { $td_column_number = td_global::vc_get_column_number(); // get the column width of the block so we can sent it to the server. If the shortcode already has a user defined column number, we use that } // ajax subcategories preloader // !!!! preloading "all" filter content should happen regardless of the setting if ( !empty($this->td_block_template_data['td_pull_down_items']) and !empty($this->atts['td_ajax_preloading']) ) { /* ------------------------------------------------------------------------------------- add 'ALL' item to the cache */ // pagination - we need to compute the pagination for each cache entry $td_hide_next = false; if (!empty($this->atts['offset']) && !empty($this->atts['limit']) && ($this->atts['limit'] != 0)) { if (1 >= ceil(($this->td_query->found_posts - $this->atts['offset']) / $this->atts['limit'])) { $td_hide_next = true; //hide link on last page } } else if (1 >= $this->td_query->max_num_pages) { $td_hide_next = true; //hide link on last page } // this will be send to JS bellow $buffyArray = array ( 'td_data' => $this->inner($this->td_query->posts, $td_column_number), 'td_block_id' => $this->block_uid, 'td_hide_prev' => true, // this is the first page 'td_hide_next' => $td_hide_next ); /* ------------------------------------------------------------------------------------- add the rest of the items to the local cache */ ob_start(); // we need to clone the object to set is_ajax_running to true // first we set an object for the all filter ?> <script> var tmpObj = JSON.parse(JSON.stringify(<?php printf( '%1$s', $block_item ) ?>)); tmpObj.is_ajax_running = true; var currentBlockObjSignature = JSON.stringify(tmpObj); tdLocalCache.set(currentBlockObjSignature, JSON.stringify(<?php echo json_encode($buffyArray) ?>)); <?php foreach ($this->td_block_template_data['td_pull_down_items'] as $count => $item) { //removes the offset on preloading for blocks pull down filter items excepting the "All" filter tab which will load posts with the offset if (!empty($this->atts['offset'])){ unset($this->atts['offset']); } if (empty($item['id'])) { continue; } // preload only 6 or 20 items depending on the setting if ($this->atts['td_ajax_preloading'] == 'preload_all' and $count > 20) { break; } else if ($this->atts['td_ajax_preloading'] == 'preload' and $count > 6) { break; } $ajax_parameters = array ( 'td_atts' => $this->atts, // original block atts 'td_column_number' => $td_column_number, // should not be 0 (1 - 2 - 3) 'td_current_page' => 1, // the current page of the block 'td_block_id' => $this->block_uid, // block uid 'block_type' => get_class($this), // the type of the block / block class 'td_filter_value' => $item['id'] // the id for this specific filter type. The filter type is in the td_atts ); ?> tmpObj = JSON.parse(JSON.stringify(<?php printf( '%1$s', $block_item ) ?>)); tmpObj.is_ajax_running = true; tmpObj.td_current_page = 1; tmpObj.td_filter_value = <?php echo json_encode($item['id']) ?>; var currentBlockObjSignature = JSON.stringify(tmpObj); tdLocalCache.set(currentBlockObjSignature, JSON.stringify(<?php echo td_ajax::on_ajax_block($ajax_parameters) ?>)); <?php } ?> </script> <?php //ob_clean(); $buffy.= ob_get_clean(); } // end preloader if return $buffy; } /** * tagDiv composer specific code: * This is a callback that is retrieve and injected into the iFrame by td-composer on Ajax operations * This js runs on the client after a drag and drop operation in td-composer * @return string JS code that is sent straight to an eval() on the client side */ function js_tdc_callback_ajax() { $buffy = ''; $buffy .= $this->js_tdc_get_composer_block(); // If this is not a loop block or if we don't have pull down ajax filters, do not run. This is just to fix the pulldown items on // content blocks if (($this->is_loop_block() === true && !empty($this->td_block_template_data['td_pull_down_items'])) ) { ob_start(); ?> <script> // block subcategory ajax filters! var jquery_object_container = jQuery('.<?php printf( '%1$s', $this->block_uid ) ?>'); if ( jquery_object_container.length) { var horizontal_jquery_obj = jquery_object_container.find('.td-subcat-list:first'); if ( horizontal_jquery_obj.length) { // make a new item var pulldown_item_obj = new tdPullDown.item(); pulldown_item_obj.blockUid = jquery_object_container.data('td-block-uid'); // get the block UID pulldown_item_obj.horizontal_jquery_obj = horizontal_jquery_obj; pulldown_item_obj.vertical_jquery_obj = jquery_object_container.find('.td-subcat-dropdown:first'); pulldown_item_obj.horizontal_element_css_class = 'td-subcat-item'; pulldown_item_obj.container_jquery_obj = horizontal_jquery_obj.closest('.td-block-title-wrap'); pulldown_item_obj.excluded_jquery_elements = [pulldown_item_obj.container_jquery_obj.find('.td-pulldown-size')]; tdPullDown.add_item(pulldown_item_obj); // add the item } } </script> <?php $buffy .= td_util::remove_script_tag(ob_get_clean()); } if ( 'tdb_single_post_share' === get_class($this) ) { ob_start(); ?> <script> // single cloud lib share block pulldown var jquery_object_container = jQuery('.<?php printf( '%1$s', $this->block_uid ) ?>'); if ( jquery_object_container.length) { var horizontal_jquery_obj = jquery_object_container.find( '.td-post-sharing-visible:first' ); if ( horizontal_jquery_obj.length ) { var pulldown_item_obj = new tdPullDown.item(); pulldown_item_obj.blockUid = jquery_object_container.data('td-block-uid'); // get the block UID pulldown_item_obj.horizontal_jquery_obj = horizontal_jquery_obj; pulldown_item_obj.vertical_jquery_obj = jquery_object_container.find('.td-social-sharing-hidden:first'); pulldown_item_obj.horizontal_element_css_class = 'td-social-sharing-button-js'; pulldown_item_obj.container_jquery_obj = horizontal_jquery_obj.parents('.wpb_wrapper:first'); tdPullDown.add_item(pulldown_item_obj); } } </script> <?php $buffy .= td_util::remove_script_tag(ob_get_clean()); } if ( 'tdb_category_sibling_categories' === get_class($this) ) { ob_start(); ?> <script> // block subcategory ajax filters! var jquery_object_container = jQuery('.<?php printf( '%1$s', $this->block_uid ) ?>'); if ( jquery_object_container.length) { if( jquery_object_container.hasClass('tdb-category-siblings-inline') ) { var horizontal_jquery_obj = jquery_object_container.find('.td-category:first'); if ( horizontal_jquery_obj.length ) { var pulldown_item_obj = new tdPullDown.item(); pulldown_item_obj.blockUid = jquery_object_container.data('td-block-uid'); // get the block UID pulldown_item_obj.horizontal_jquery_obj = horizontal_jquery_obj; pulldown_item_obj.vertical_jquery_obj = jquery_object_container.find('.td-subcat-dropdown:first'); pulldown_item_obj.horizontal_element_css_class = 'entry-category'; pulldown_item_obj.container_jquery_obj = horizontal_jquery_obj.parents('.tdb-category-siblings:first'); tdPullDown.add_item(pulldown_item_obj); } } } </script> <?php $buffy .= td_util::remove_script_tag(ob_get_clean()); } return $buffy; } /** * tagDiv composer specific code: * - it's added to the end of the iFrame when the live editor is active (when @see td_util::tdc_is_live_editor_iframe() === true) * - it is injected int he iFrame and evaluated there in the global scoupe when a new block is added to the page via AJAX! * @return string the JS without <script> tags */ function js_tdc_get_composer_block() { ob_start(); ?> <script> (function () { // js_tdc_get_composer_block code for "<?php echo get_class($this) ?>" var tdComposerBlockItem = new tdcComposerBlocksApi.item(); tdComposerBlockItem.blockUid = '<?php printf( '%1$s', $this->block_uid ) ?>'; tdComposerBlockItem.callbackDelete = function(blockUid) { if ( 'undefined' !== typeof window.tdPullDown ) { // delete the existing pulldown if it exists tdPullDown.deleteItem(blockUid); } if ( 'undefined' !== typeof window.tdAnimationSprite ) { // delete the animation sprite if it exits tdAnimationSprite.deleteItem(blockUid); } if ( 'undefined' !== typeof window.tdTrendingNow ) { // delete the animation sprite if it exits tdTrendingNow.deleteItem(blockUid); } if ( 'undefined' !== typeof window.tdHomepageFull ) { // delete the homepagefull if it exits tdHomepageFull.deleteItem( blockUid ); } if ( 'undefined' !== typeof window.tdbMenu ) { tdbMenu.deleteItem( blockUid ); } if ( 'undefined' !== typeof window.tdbSearch ) { tdbSearch.deleteItem( blockUid ); } // delete the weather item if available NOTE USED YET //tdWeather.deleteItem(blockUid); tdcDebug.log('td_block.php js_tdc_get_composer_block - callbackDelete(' + blockUid + ') - td_block base callback runned'); }; tdcComposerBlocksApi.addItem(tdComposerBlockItem); })(); </script> <?php return td_util::remove_script_tag(ob_get_clean()); } // get atts protected function get_block_html_atts() { return ' data-td-block-uid="' . $this->block_uid . '" '; } /** * Add only 'td_block_wrap' or 'td_block_wrap-composer' to the block. 'td_block_wrap-composer' is used to bypass blocks when * composer renders pages in menu * * @return string */ protected function get_wrapper_class() { $block_class = 'td_block_wrap'; if ( td_global::get_in_element() && ( tdc_state::is_live_editor_ajax() || tdc_state::is_live_editor_iframe() ) ) { $block_class .= '-composer'; } return $block_class; } /** * @param $additional_classes_array array - of classes to add to the block * @return string */ protected function get_block_classes($additional_classes_array = array() ) { $class = $this->get_att('class'); $el_class = $this->get_att('el_class'); $color_preset = $this->get_att('color_preset'); $ajax_pagination = $this->get_att('ajax_pagination'); $border_top = $this->get_att('border_top'); $css = $this->get_att('css'); $tdc_css = $this->get_att('tdc_css'); $block_template_id = $this->get_att('block_template_id'); $td_ajax_preloading = $this->get_att('td_ajax_preloading'); $block_class = 'td_block_wrap'; if ( td_global::get_in_element() && ( tdc_state::is_live_editor_ajax() || tdc_state::is_live_editor_iframe() ) ) { $block_class .= '-composer'; } //add the block wrap and block id class $block_classes = array( $block_class, get_class($this) ); // get the design tab css classes $css_classes_array = $this->parse_css_att($css); if ( $css_classes_array !== false ) { $block_classes = array_merge ( $block_classes, $css_classes_array ); } $css_classes_array = $this->parse_css_att($tdc_css); if ( $css_classes_array !== false ) { $block_classes = array_merge ( $block_classes, $css_classes_array ); } //add the classes that we receive via shortcode. @17 aug 2016 - this att may be used internally - by ra if (!empty($class)) { $class_array = explode(' ', $class); $block_classes = array_merge ( $block_classes, $class_array ); } //marge the additional classes received from blocks code if (!empty($additional_classes_array)) { $block_classes = array_merge ( $block_classes, $additional_classes_array ); } //add the full cell class + the color preset class if (!empty($color_preset)) { $block_classes[]= 'td-pb-full-cell'; $block_classes[]= $color_preset; } /** * - used to add td_block_loading css class on the blocks having pagination * - the class has a force css transform for lazy devices */ if (!empty($ajax_pagination)) { $block_classes[]= 'td_with_ajax_pagination'; } /** * add the border top class - this one comes from the atts */ if (empty($border_top)) { $block_classes[] = 'td-pb-border-top'; } // this is the field that all the shortcodes have (or at least should have) if (!empty($el_class)) { $el_class_array = explode(' ', $el_class); $block_classes = array_merge ( $block_classes, $el_class_array ); } /** * add block template id - comes from atts */ if (empty($block_template_id)) { $block_template_id = td_options::get('tds_global_block_template', 'td_block_template_1'); } $block_classes[] = $block_template_id; /** * Add 'tdc-no-posts' class that show info msg for blocks without any modules. Its style is in tagDiv composer */ if ( $this->is_loop_block() && empty( $this->td_query->posts ) ) { $block_classes[] = 'tdc-no-posts'; } /** * - used to add td_block_loading css class on the blocks having pagination * - the class has a force css transform for lazy devices */ if ( !empty( $td_ajax_preloading ) ) { $block_classes[]= 'td_ajax_preloading_' . $td_ajax_preloading; } //remove duplicates $block_classes = array_unique($block_classes); return implode(' ', $block_classes); } /** * adds a class to the current block's ats * @param $raw_class_name string the class name is not sanitized, so make sure you send a sanitized one */ private function add_class($raw_class_name) { if (!empty($this->atts['class'])) { $this->atts['class'] = $this->atts['class'] . ' ' . $raw_class_name; } else { $this->atts['class'] = $raw_class_name; } } /** * gets the current template instance, if no instance it's found throws error * @return mixed the template instance */ private function block_template() { if (isset($this->td_block_template_instance)) { return $this->td_block_template_instance; } else { td_util::error(__FILE__, "td_block: " . get_class($this) . " did not call render, no td_block_template_instance in td_block"); die; } } /** * set the initial atts when using blocks via ajax. * On ajax the blocks do not call render, just inner directly * @param $atts */ public function set_all_atts($atts) { $this->atts = $atts; } /** * - Get an attribute from the base class IF render was called * - OR - very importantly get's an attribute from the ajax request if the block has front end ajax stuff. Used by modules to maintain settings * between ajax requests * @updated in 25.1.2018 to use all the mapped attributes + the received atts from render() * @param $att_name * @return mixed */ protected function get_att($att_name) { // the td_block->render() was not called if (empty($this->atts)) { td_util::error(__FILE__, get_class($this) . '->get_att(' . $att_name . ') Internal error: The atts are not set yet(AKA: the render method of the block was not called yet and the system tried to read an att)'); die; } // the att does not exist if (!isset($this->atts[$att_name])) { td_util::error(__FILE__, 'Internal error: The system tried to use an att that does not exists! class_name: ' . get_class($this) . ' Att name: "' . $att_name . '" The list with available shorcode_att is computed at run time by each shortcode'); die; } return $this->atts[$att_name]; } /** * Reads a shortcode_att. AS of 25.1.2018 some shortcodes have a shortcode_atts property where they read the atts from the map * @param $att_name * * @return mixed */ protected function get_shortcode_att( $att_name ) { if ( empty($this->shortcode_atts ) ) { td_util::error(__FILE__, get_class($this) . '->get_shortcode_att(' . $att_name . ') Internal error: The atts are not set yet(AKA: the render method was not called yet and the system tried to read a shorcode_att)'); die; } if ( ! isset($this->shortcode_atts[ $att_name ] ) ) { var_dump( $this->shortcode_atts ); td_util::error(__FILE__, 'Internal error: The system tried to use a shorcode_att that does not exists! class_name: ' . get_class($this) . ' Att name: "' . $att_name . '" The list with available shorcode_att is computed at run time by each shortcode'); die; } return $this->shortcode_atts[ $att_name ]; } /** * parses a design panel generated css string and get's the classes and the * - It's not private because it's used by @see td_block_ad_box because that block uses special classes to avoid adblock * - it should be the same with @see tdc_composer_block::parse_css_att from the tdc plugin * @param $user_css_att * * @return array|bool - array of results or false if no classes are available */ protected function parse_css_att($user_css_att) { if (empty($user_css_att)) { return false; } $matches = array(); $preg_match_ret = preg_match_all ( '/\s*\.\s*([^\{]+)\s*\{\s*([^\}]+)\s*\}\s*/', $user_css_att, $matches); if ( $preg_match_ret === 0 || $preg_match_ret === false || empty($matches[1]) || empty($matches[2]) ) { return false; } // get only the selectors return $matches[1]; } /** * Disable loop block features. If this is disable, the block does not use a loop and it dosn't need to run a query. * - no query * - no pulldown items lis (ajax filters) * - no ajax JS ex: NO new tdBlock() */ protected function disable_loop_block_features() { $this->is_loop_block = false; } private function is_loop_block() { return $this->is_loop_block; } /** * used to send the atts to a new module instance that is used on shortcode * @return array */ protected function get_all_atts() { return $this->atts; } /** * @deprecated * @param $atts_map * @return array */ protected function map_atts_to_module($atts_map) { $module_atts = array(); foreach ($atts_map as $shortcode_att => $module_att) { $module_atts[$module_att] = $this->get_att($shortcode_att); } return $module_atts; } /** * Generate css compiled code * * @param $css_compiler * @param $shortcode_att_id * @param $color_id * @param $gradient_id * @param $instance - shortcode or style template */ static function load_color_settings( $instance, $css_compiler, $shortcode_att_id, $color_id = '', $gradient_id = '', $gradient_color = '', $gradient_params = '' ) { if ( $instance instanceof td_block ) { $shortcode_att = $instance->get_shortcode_att( $shortcode_att_id ); } else { $shortcode_att = $instance->get_style_att( $shortcode_att_id ); } if ( ! empty( $shortcode_att ) ) { $decoded_shortcode_att = false; if ( td_util::tdc_is_installed() ) { try { $decoded_shortcode_att = tdc_b64_decode( $shortcode_att, true ); } catch( Exception $ex ) { // } } if ( false !== $decoded_shortcode_att && $decoded_shortcode_att !== $shortcode_att ) { $att = json_decode( $decoded_shortcode_att, true ); if ( ! empty ( $gradient_id ) && ! empty ( $att['css'] ) ) { $css_compiler->load_setting_raw( $gradient_id, $att['css'] ); if ( ! empty ( $gradient_color ) && ! empty( $att['color1'] ) ) { $css_compiler->load_setting_raw( $gradient_color, $att['color1'] ); } if ( ! empty ( $gradient_params ) && ! empty( $att['cssParams'] ) ) { $css_compiler->load_setting_raw( $gradient_params, $att['cssParams'] ); } } } else { if ( ! empty ( $color_id ) ) { $css_compiler->load_setting_raw( $color_id, $shortcode_att ); } } } } }