File: /var/www/itself.kauko.lt/wp-content/plugins/oxygen/component-framework/includes/tree-shortcodes.php
<?php
/**
* Interface to transform Components Tree JSON object to
* WordPress shortcodes and vice versa.
*
*/
/**
* Transform JSON Components Tree to WordPress nested shortcodes
*
* @return string
* @since 0.1
*/
function components_json_to_shortcodes( $json, $reusable = false ) {
$components_tree = json_decode( $json, true );
if ( $reusable ) {
$components_tree['children'] = ct_update_ids( $components_tree['children'], 1, $components_tree );
};
if ( is_null ( $components_tree ) )
return false;
$output = parse_components_tree( $components_tree['children'] );
return $output;
}
/**
* Recursive function that actually transform an Object to WordPress shortcodes
*
* @since 0.1
*/
function parse_components_tree( $components_tree ) {
global $oxygen_signature;
if ( !is_array( $components_tree ) ) {
return false;
}
$output = "";
foreach( $components_tree as $id => $item ) {
$name = sanitize_text_field( $item['name'] );
$ct_options = null;
$shortcode_atts = array();
$ct_options_string = null;
$ct_content = '';
$nested = false;
$full_shortcode = false;
// go deeper into the tree if item has children and have no options
// if ( $item['children'] && $item['name'] == "ct_reusable" ) {
// $content = parse_components_tree( $item['children'] );
// // update view
// update_post_meta( $item['options']['view_id'], 'ct_builder_shortcodes', $content );
// $view_options = array (
// "view_id" => $item['options']['view_id'],
// "ct_id" => $item['options']['ct_id'],
// "ct_parent" => $item['options']['ct_parent'],
// );
// $view_json = json_encode( $view_options );
// // add to shortcodes
// $output .= "[{$item['name']} ct_options='$view_json']";
// // move to next component
// continue;
// }
// handle 'Shortcode' component
if ( $item['name'] == "ct_shortcode" ) {
// get 'original' options
$original = $item['options']['original'];
if ( $original['full_shortcode'] ) {
$full_shortcode = $original['full_shortcode'];
/*$executed_shortcode = do_shortcode( $full_shortcode );
// TODO: better check for broken shortcodes like "[gallery"
if ( $executed_shortcode == $full_shortcode ) {
$full_shortcode = "";
}*/
$original = array();
$item['options']['original']['full_shortcode'] = true;
}
// // start opening shortcode tag
// $output .= "[" . $item['name'];
// // add params
// $ct_options = array ( "ct_id", "ct_parent", "selector", "ct_shortcode", "original" );
// if ( is_array( $original ) ) {
// foreach ( $original as $key => $value ) {
// if ( in_array($key, $ct_options) ) {
// continue;
// }
// $output .= " $key='$value'";
// }
// }
}
// else {
// // start opening shortcode tag
// $output .= "[" . $item['name'];
// }
// check if nested column or section
if ( $item['depth'] > 1 && in_array( $item['name'], array( 'ct_link', 'ct_section', 'ct_container', 'ct_inner_content', 'ct_columns', 'ct_column', 'ct_new_columns', 'ct_div_block', 'ct_nestable_shortcode', 'oxy_superbox', 'oxy_toggle', 'oxy_tab', 'oxy_tabs', 'oxy_tab_content', 'oxy_tabs_contents', 'oxy_dynamic_list', 'oxy-product-builder', 'ct_modal', 'oxy_header', 'oxy_header_row', 'oxy_header_right', 'oxy_header_center', 'oxy_header_left' ) ) ) {
$nested = true;
}
// add depth suffix if needed
if ( $nested ) {
$name .= '_' . $item['depth'];
}
// add shortcode parameters
if ( is_array( $item['options'] ) ) {
foreach ( $item['options'] as $key => $value ) {
if ( $key == "url" && $item['name'] == "embed" ) {
unset( $item['options']['url'] );
}
if ( $key == "classes" ) {
continue;
}
if ( is_array( $value ) ) {
if ( ! empty( $value ) ) {
foreach ( $value as $array_key => $array_value ) {
// make sure widget parameters won't brake the shortcode with quotes
if ( $item['name'] == "ct_widget" && $array_key == "instance" ) {
$item['options'][$key][$array_key] = ct_encode_widget_instance($array_value);
$item['options'][$key]['paramsBase64'] = true;
}
if ( $array_key == "custom-css" ) {
$item['options'][$key][$array_key] = normalize_custom_css( $array_value );
}
$options_to_encode = ["code-php","code-css","code-js","alt",
"testimonial_text","testimonial_author","testimonial_author_info",
"icon_box_heading","icon_box_text",
"progress_bar_left_text","progress_bar_right_text",
'pricing_box_package_title','pricing_box_package_subtitle','pricing_box_content','pricing_box_package_regular'];
if ( in_array($array_key, $options_to_encode) ) {
$option_value = $item['options'][$key][$array_key];
// sign shortcodes before base64_encode, or later encoded shortcodes won't be signed
$option_value = preg_replace_callback('/\[oxygen ([^\]]*)\]/i', 'ct_sign_oxy_dynamic_shortcode', $option_value);
$item['options'][$key][$array_key] = base64_encode($option_value);
}
$options_to_encode_backward_compat = [
"paginate_prev_link_text","paginate_next_link_text"
];
$options_to_encode_backward_compat = apply_filters("oxy_base64_encode_options", $options_to_encode_backward_compat);
if ( in_array($array_key, $options_to_encode_backward_compat) ) {
$item['options'][$key][$array_key] = oxygen_vsb_base64_encode($item['options'][$key][$array_key]);
}
if ( $array_key == "url" ) {
$item['options'][$key][$array_key] = oxygen_vsb_quotes_encode($item['options'][$key][$array_key]);
$item['options'][$key]["url_encoded"] = "true";
}
if($array_key == 'globalconditions') {
foreach($item['options'][$key][$array_key] as $conditionKey => $condition) {
$item['options'][$key][$array_key][$conditionKey]['value'] = base64_encode($condition['value']);
if (isset($item['options'][$key][$array_key][$conditionKey]['searchValue'])) {
$item['options'][$key][$array_key][$conditionKey]['searchValue'] = base64_encode($condition['searchValue']);
}
}
}
}
}
else {
unset( $item['options'][$key] );
}
}
elseif ( $key == "ct_content" ) {
$ct_content = $item['options']['ct_content'];
unset($item['options'][$key]);// = htmlspecialchars( $value, ENT_QUOTES );
}
}
$value = json_encode( $item['options'], JSON_FORCE_OBJECT );
$value = ct_unicode_decode( $value );
$shortcode_atts['ct_options'] = $value;
$ct_options_string = "ct_options='{$value}'";
}
// // handle full shortcode
// if ( $full_shortcode ) {
// $output .= $full_shortcode;
// }
// handle embed URL
if ( isset( $item['options']['url'] ) && $item['name'] == "embed" ) {
$output .= $item['options']['url'];
}
$ct_content = oxygen_vsb_filter_shortcode_content_encode($ct_content);
if ( isset($item['children']) ) {
if ( !empty( $ct_content ) ) {
// if we have content and children at the same time
$temp_content = $ct_content;
$shortcodes = array();
// get shortcodes for each child
foreach( $item['children'] as $id => $child ) {
// check if placeholder is in the outer template
$placeholder_id = ($child['id']>=100000) ? $child['id']-100000 : $child['id'];
$shortcodes["<span id=\"ct-placeholder-{$placeholder_id}\"></span>"] = parse_components_tree( array( $id => $child ) );
}
// replace placeholders with shortcodes
foreach($shortcodes as $key => $val) {
$temp_content = str_replace($key, $val, $temp_content);
}
// output
$ct_content = $temp_content;
} else {
// go deeper into the tree if item has children and have no content
$ct_content .= parse_components_tree( $item['children'] );
}
}
// Component classes aren't coupled here, so leverage WordPress filters for validation
if ( false !== $component = apply_filters( "oxygen_vsb_filter_{$item['name']}", array( 'item' => $item, 'content' => $ct_content ) ) ) {
if ( $item['name'] == "ct_shortcode" && $full_shortcode) {
$component['content'] = $full_shortcode;
}
// sign oxy shortcodes inside the content
$component['content'] = preg_replace_callback('/\[oxygen ([^\]]*)\]/i', 'ct_sign_oxy_dynamic_shortcode', $component['content']);
// sign oxy shortcodes inside the properties
if(isset($shortcode_atts['ct_options'])) {
$shortcode_atts['ct_options'] = preg_replace_callback('/\[oxygen ([^\]]*)\]/i', 'ct_sign_oxy_dynamic_shortcode', $shortcode_atts['ct_options']);
$ct_options_string = "ct_options='".$shortcode_atts['ct_options']."'";
}
// Generate signature
$signature = $oxygen_signature->generate_signature_shortcode_string( $name, $shortcode_atts, $component['content'] );
// Generate output
$output .= "[{$name} {$signature} {$ct_options_string}]{$component['content']}[/{$name}]";
}
}
return $output;
}
function ct_sign_oxy_dynamic_shortcode($results) {
if ( !oxygen_vsb_current_user_can_access() ) {
return $results[0];
}
global $oxygen_signature;
$signature_arg = $oxygen_signature->get_shortcode_signature_arg();
$pattern = get_shortcode_regex( array('oxygen') );
$result = str_replace('\"', '"', $results[0]);
preg_match_all( "/$pattern/", $result, $m );
$tag = $m[2][0];
$attr = shortcode_parse_atts( $m[3][0] );
if(isset($attr[$signature_arg])) {
unset($attr[$signature_arg]);
}
$signature = $oxygen_signature->generate_signature_shortcode_string( $tag, $attr, null );
$options_string = "";
foreach($attr as $key => $val) {
$options_string .= "{$key}='{$val}' ";
}
return "[{$tag} {$signature} {$options_string}]";
}
/**
* Update IDs for Re-usable parts start from $counter
*
* @since 0.2.3
*/
function ct_update_ids( $components_tree, $count, &$parent ) {
global $counter;
$counter = $count;
foreach ( $components_tree as $key => $child ) {
// update placeholder id's
if(isset($parent['options']['ct_content'])) {
$parent['options']['ct_content'] = str_replace("ct-placeholder-" . $components_tree[$key]['options']['ct_id'],
"ct-placeholder-" . $counter,
$parent['options']['ct_content']);
}
$components_tree[$key]['id'] = $counter;
$components_tree[$key]['options']['ct_id'] = $counter;
$components_tree[$key]['options']['ct_parent'] = $parent['id'];
$counter++;
if ( $components_tree[$key]['children'] ) {
$components_tree[$key]['children'] = ct_update_ids( $components_tree[$key]['children'], $counter, $components_tree[$key] );
}
}
return $components_tree;
}
/**
* Transform WordPress post content to JSON Components Tree
*
* @return JSON or false
* @since 0.1
*/
function content_to_components_json( $content ) {
$shortcodes = parse_shortcodes( $content );
if ( $shortcodes['is_shortcode'] === false && $content != "" ) {
return json_encode( false );
}
$root = array (
"id" => 0,
"name" => "root",
"depth" => 0
);
$root['children'] = $shortcodes['content'];
$components_tree = json_encode( $root );
if ( is_null( $components_tree ) ) {
return false;
}
else {
return $components_tree;
}
}
/**
* Recursive function that actually transform WordPress shortcodes to Array
*
* @return Array
* @since 0.1
*/
function parse_shortcodes( $content, $is_first = true, $verify_signature = true ) {
$content = ct_obfuscate_shortcode($content);
$pattern = get_shortcode_regex();
preg_match_all( '/'. $pattern .'/s', $content, $matches );
$tags = $matches[0];
$names = $matches[2];
$args = $matches[3];
$inner_content = $matches[5];
if ( ! $args ) {
return array(
'is_shortcode' => false,
'content' => $content );
}
if ( $is_first ) {
// check if
$total_length = 0;
foreach ( $tags as $tag ) {
$total_length += strlen($tag);
}
if ( $total_length != strlen($content) ) {
return array(
'is_shortcode' => false,
'content' => $content );
}
}
$shortcodes = array();
foreach ( $args as $key => $value ) {
$shortcode = array();
$depth = false;
$options = shortcode_parse_atts( $value );
// skip shortcode if no shortcode params
if ( ! is_array( $options ) ) {
continue;
}
/*$options['ct_options'] = str_replace("\n", "\\n", $options['ct_options']);
$options['ct_options'] = str_replace("\r", "\\r", $options['ct_options']);
$options['ct_options'] = str_replace("\t", "\\t", $options['ct_options']);*/
$verfOptions = $options; // keep a copy to verify the signature later
$options = json_decode( $options['ct_options'], true );
$id = $options['ct_id'];
$shortcode['id'] = $id;
$shortcode['name'] = $names[$key];
if(is_array($options)) {
foreach($options as $optionKey => $option) {
if(in_array($optionKey, array('selector', 'activeselector', 'ct_id', 'ct_parent'))) {
continue;
}
if($optionKey === 'media') {
foreach($options['media'] as $bpKey => $breakpoint) {
foreach($breakpoint as $stateKey => $state) {
foreach(array('src', 'url', 'map_address', 'alt', 'background-image') as $param) {
if(isset($options['media'][$bpKey][$stateKey][$param])) {
$count = 0; // safety switch
while(strpos($options['media'][$bpKey][$stateKey][$param], '+oxygen') !== false && $count < 9) {
$count++;
$options['media'][$bpKey][$stateKey][$param] = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $options['media'][$bpKey][$stateKey][$param]);
}
}
}
}
}
continue;
}
foreach(array('src', 'url', 'map_address', 'alt', 'background-image') as $param) {
if(isset($options[$optionKey][$param])) {
$count = 0; // safety switch
while(strpos($options[$optionKey][$param], '+oxygen') !== false && $count < 9) {
$count++;
$options[$optionKey][$param] = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $options[$optionKey][$param]);
}
}
}
if($optionKey === 'original' && isset($options[$optionKey]['globalconditions'])) {
foreach($options[$optionKey]['globalconditions'] as $conditionKey => $condition) {
if(isset($condition['oxycode'])) {
$options[$optionKey]['globalconditions'][$conditionKey]['oxycode'] = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $options[$optionKey]['globalconditions'][$conditionKey]['oxycode']);
}
if(isset($condition['value']) && strpos($condition['value'], '+oxygen') !== false) {
$options[$optionKey]['globalconditions'][$conditionKey]['value'] = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $options[$optionKey]['globalconditions'][$conditionKey]['value']);
}
}
}
// convert "+oxygen" back to "[oxygen" im Custom Attributes
if($optionKey === 'original' && isset($options[$optionKey]['custom-attributes'])) {
foreach($options[$optionKey]['custom-attributes'] as $attr_key => $attribute) {
if(isset($attribute['name']) && strpos($attribute['name'], '+oxygen') !== false) {
$options[$optionKey]['custom-attributes'][$attr_key]['name'] = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $options[$optionKey]['custom-attributes'][$attr_key]['name']);
}
if(isset($attribute['value']) && strpos($attribute['value'], '+oxygen') !== false) {
$options[$optionKey]['custom-attributes'][$attr_key]['value'] = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $options[$optionKey]['custom-attributes'][$attr_key]['value']);
}
}
}
}
}
global $oxygen_signature;
$verfOptions['ct_options'] = json_encode( $options, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT );
$verfInnercontent = $inner_content[ $key ];
// the inner content being used in the oxygen signature verification should have deobfuscated oxy dynamic shortcode strings
if(strpos($verfInnercontent, '+oxygen') !== false) {
$verfInnercontent = preg_replace_callback('/\+oxygen(.+?)\+/i', 'ct_deobfuscate_oxy_url', $verfInnercontent);
}
// Skip shortcodes that are not properly signed, it has to be done here only after ct_deobfuscate_oxy_url has been applied on the options
if ( $verify_signature && ! $oxygen_signature->verify_signature( $names[ $key ], $verfOptions, $verfInnercontent ) ) {
continue;
}
$sanitized_options = array();
// sanitize option names
if ( $options ) {
foreach ( $options as $name => $value ) {
$array = $value;
if ( is_array( $array ) && ! empty( $array ) && $name != "classes" ) {
foreach ( $array as $array_key => $array_value) {
// make sure widget parameters won't brake the shortcode with quotes
if ( $names[$key] == "ct_widget" && $array_key == "instance" ) {
if(isset($array['paramsBase64'])) {
$array[$array_key] = ct_decode_widget_instance($array_value);
}
}
// TODO: add a filter here to add new options from Class
$options_to_decode = ["code-php","code-css","code-js","alt",
"testimonial_text","testimonial_author","testimonial_author_info",
"icon_box_heading","icon_box_text",
"progress_bar_left_text","progress_bar_right_text",
'pricing_box_package_title','pricing_box_package_subtitle','pricing_box_content','pricing_box_package_regular'];
if ( in_array($array_key, $options_to_decode) ) {
$array[$array_key] = base64_decode( $array_value );
}
$options_to_decode_backward_compat = [
"url",
"paginate_prev_link_text","paginate_next_link_text"
];
$options_to_decode_backward_compat = apply_filters("oxy_base64_encode_options", $options_to_decode_backward_compat);
if ( in_array($array_key, $options_to_decode_backward_compat) && strpos($array_value, "oxy_base64_encoded::") === 0) {
$array[$array_key] = oxygen_vsb_base64_decode( $array_value );
}
if ( $array_key == "url" && $array["url_encoded"] == "true") {
$array[$array_key] = oxygen_vsb_quotes_decode( $array_value );
}
if ( $array_key == "custom-css" ) {
$array[$array_key] = prettify_custom_css( $array[$array_key] );
}
if($array_key == 'globalconditions') {
foreach($array[$array_key] as $conditionKey => $condition) {
$array[$array_key][$conditionKey]['value'] = base64_decode($condition['value']);
if (!isset($array[$array_key][$conditionKey]['searchValue'])) {
// upgrade to 3.3
$array[$array_key][$conditionKey]['searchValue'] = base64_decode($condition['value']);
}
else {
$array[$array_key][$conditionKey]['searchValue'] = base64_decode($condition['searchValue']);
}
}
}
}
$value = $array;
}
$sanitized_options[$name] = $value;
}
}
$shortcode['options'] = $sanitized_options;
// handle 'Shortcode' component
if ( isset($shortcode['options']) && isset($shortcode['options']['ct_shortcode']) && $shortcode['options']['ct_shortcode'] == "true" ) {
if ( isset( $shortcode['options']['original']['full_shortcode'] ) ) {
$shortcode['options']['original']['full_shortcode'] = $inner_content[$key];
}
unset($inner_content[$key]);
}
// add depth 1
if ( $shortcode['name'] == "ct_column" ||
$shortcode['name'] == "ct_columns" ||
$shortcode['name'] == "ct_new_columns" ||
$shortcode['name'] == "ct_container" ||
$shortcode['name'] == "ct_section" ||
$shortcode['name'] == "ct_div_block" ||
$shortcode['name'] == "oxy_dynamic_list" ||
$shortcode['name'] == "ct_nestable_shortcode" ||
$shortcode['name'] == "ct_inner_content" ||
$shortcode['name'] == "ct_link" ||
$shortcode['name'] == 'oxy_superbox' ||
$shortcode['name'] == 'oxy_toggle' ||
$shortcode['name'] == 'oxy_tab' ||
$shortcode['name'] == 'oxy_tabs' ||
$shortcode['name'] == 'oxy_tab_content' ||
$shortcode['name'] == 'oxy_tabs_contents' ||
$shortcode['name'] == 'oxy-product-builder' ||
$shortcode['name'] == 'ct_modal' ||
$shortcode['name'] == 'oxy_header' ||
$shortcode['name'] == 'oxy_header_row' ||
$shortcode['name'] == 'oxy_header_left' ||
$shortcode['name'] == 'oxy_header_center' ||
$shortcode['name'] == 'oxy_header_right'
) {
$depth = 1;
}
// strip from depth postfix
if ( strpos( $shortcode['name'], "ct_section_" ) !== false ) {
$depth = substr( $shortcode['name'], 11 );
$shortcode['name'] = "ct_section";
}
if ( strpos( $shortcode['name'], "ct_columns_" ) !== false ) {
$depth = substr( $shortcode['name'], 11 );
$shortcode['name'] = "ct_columns";
}
if ( strpos( $shortcode['name'], "ct_new_columns_" ) !== false ) {
$depth = substr( $shortcode['name'], 15 );
$shortcode['name'] = "ct_new_columns";
}
if ( strpos( $shortcode['name'], "ct_column_" ) !== false ) {
$depth = substr( $shortcode['name'], 10 );
$shortcode['name'] = "ct_column";
}
if ( strpos( $shortcode['name'], "ct_div_block_" ) !== false ) {
$depth = substr( $shortcode['name'], 13 );
$shortcode['name'] = "ct_div_block";
}
if ( strpos( $shortcode['name'], "oxy_dynamic_list_" ) !== false ) {
$depth = substr( $shortcode['name'], 17 );
$shortcode['name'] = "oxy_dynamic_list";
}
if ( strpos( $shortcode['name'], "ct_nestable_shortcode_" ) !== false ) {
$depth = substr( $shortcode['name'], 22 );
$shortcode['name'] = "ct_nestable_shortcode";
}
if ( strpos( $shortcode['name'], "ct_inner_content_" ) !== false ) {
$depth = substr( $shortcode['name'], 17 );
$shortcode['name'] = "ct_inner_content";
}
if ( strpos( $shortcode['name'], "ct_link_" ) !== false && (strpos( $shortcode['name'], "ct_link_text" ) === false && strpos( $shortcode['name'], "ct_link_button" ) === false)) {
$depth = substr( $shortcode['name'], 8 );
$shortcode['name'] = "ct_link";
}
if ( strpos( $shortcode['name'], "ct_slider_" ) !== false ) {
$depth = substr( $shortcode['name'], 10 );
$shortcode['name'] = "ct_slider";
}
if ( strpos( $shortcode['name'], "ct_slide_" ) !== false ) {
$depth = substr( $shortcode['name'], 9 );
$shortcode['name'] = "ct_slide";
}
if ( strpos( $shortcode['name'], "oxy_superbox_" ) !== false ) {
$depth = substr( $shortcode['name'], 13 );
$shortcode['name'] = "oxy_superbox";
}
if ( strpos( $shortcode['name'], "oxy_toggle_" ) !== false ) {
$depth = substr( $shortcode['name'], 11 );
$shortcode['name'] = "oxy_toggle";
}
if ( strpos( $shortcode['name'], "oxy_tab_" ) !== false && strpos( $shortcode['name'], "oxy_tab_content" ) === false ) {
$depth = substr( $shortcode['name'], 8 );
$shortcode['name'] = "oxy_tab";
}
if ( strpos( $shortcode['name'], "oxy_tabs_" ) !== false && strpos( $shortcode['name'], "oxy_tabs_contents" ) === false ) {
$depth = substr( $shortcode['name'], 9 );
$shortcode['name'] = "oxy_tabs";
}
if ( strpos( $shortcode['name'], "oxy_tab_content_" ) !== false ) {
$depth = substr( $shortcode['name'], 16 );
$shortcode['name'] = "oxy_tab_content";
}
if ( strpos( $shortcode['name'], "oxy_tabs_contents_" ) !== false ) {
$depth = substr( $shortcode['name'], 18 );
$shortcode['name'] = "oxy_tabs_contents";
}
if ( strpos( $shortcode['name'], "oxy-product-builder_" ) !== false ) {
$depth = substr( $shortcode['name'], 20 );
$shortcode['name'] = "oxy-product-builder";
}
if ( strpos( $shortcode['name'], "ct_modal_" ) !== false ) {
$depth = substr( $shortcode['name'], 9 );
$shortcode['name'] = "ct_modal";
}
if ( strpos( $shortcode['name'], "oxy_header_row_" ) !== false ) {
$depth = substr( $shortcode['name'], 15 );
$shortcode['name'] = "oxy_header_row";
}
else if ( strpos( $shortcode['name'], "oxy_header_right_" ) !== false ) {
$depth = substr( $shortcode['name'], 17 );
$shortcode['name'] = "oxy_header_right";
}
else if ( strpos( $shortcode['name'], "oxy_header_center_" ) !== false ) {
$depth = substr( $shortcode['name'], 18 );
$shortcode['name'] = "oxy_header_center";
}
else if ( strpos( $shortcode['name'], "oxy_header_left_" ) !== false ) {
$depth = substr( $shortcode['name'], 16 );
$shortcode['name'] = "oxy_header_left";
}
else if ( strpos( $shortcode['name'], "oxy_header_" ) !== false &&
!in_array($shortcode['name'], array("oxy_header_row","oxy_header_right","oxy_header_center","oxy_header_left")) ) {
$depth = substr( $shortcode['name'], 11 );
$shortcode['name'] = "oxy_header";
}
// parse inner content shortcodes
if ( isset($inner_content[$key]) ) {
if(strpos($inner_content[$key], '[oxygen ') === 0) {
$nested_content['content'] = $inner_content[$key];
}
else {
$nested_content = parse_shortcodes( $inner_content[$key], false, $verify_signature );
}
if ( isset($nested_content['is_shortcode']) && $nested_content['is_shortcode']) {
$shortcode['children'] = $nested_content['content'];
// get shortcodes inside content
if ( $shortcode['name'] == "ct_paragraph" ||
$shortcode['name'] == "ct_text_block" ||
$shortcode['name'] == "ct_headline" ||
$shortcode['name'] == "ct_link_text" ||
$shortcode['name'] == "ct_link_button" ||
$shortcode['name'] == "ct_li") {
preg_match_all( '/'. $pattern .'/s', $inner_content[$key], $inner_matches );
$inner_shortcodes = $inner_matches[0];
$inner_shortcodes_atts = $inner_matches[3];
$inner_shortcodes_parsed = $inner_content[$key];
foreach ( $inner_shortcodes as $key => $inner_shortcode ) {
// parse "ct_options" parameter
$atts = shortcode_parse_atts( $inner_shortcodes_atts[$key] );
$atts = json_decode( $atts['ct_options'], true );
$inner_shortcodes_parsed = str_replace( $inner_shortcode, "<span id=\"ct-placeholder-{$atts['ct_id']}\"></span>", $inner_shortcodes_parsed );
}
if ($inner_shortcodes) {
$inner_shortcodes_parsed = oxygen_vsb_filter_shortcode_content_decode($inner_shortcodes_parsed);
$shortcode['options']['ct_content'] = $inner_shortcodes_parsed;
}
}
} else {
$nested_content['content'] = trim($nested_content['content']);
if(!($shortcode['name'] == 'ct_inner_content' && empty($nested_content['content']))) {
$nested_content['content'] = oxygen_vsb_filter_shortcode_content_decode($nested_content['content']);
$shortcode['options']['ct_content'] = $nested_content['content'];
}
}
}
if ( isset ( $depth ) )
$shortcode['depth'] = $depth;
$shortcodes[] = $shortcode;
}
return array(
'is_shortcode' => true,
'content' => $shortcodes );
}
/**
* Update custom css variable so it can be
* used in shortcode attribute
*
* @since 0.1.4
*/
function normalize_custom_css( $css ) {
if ( $css ) {
$css = str_replace("\n",'', $css);
$css = str_replace("\r",'', $css);
$css = str_replace("\t",'', $css);
}
return $css;
}
/**
* Prettify custom CSS code
*
* @since 0.1.8
*/
function prettify_custom_css( $css ) {
if ( $css ) {
$css = str_replace(";",";\n", $css);
}
return $css;
}
/**
* Helper function to decode Unicode to UTF-8 characters
*
* @since 0.1.7
*/
function ct_unicode_decode($str) {
return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', 'ct_replace_unicode_escape_sequence', $str);
}
function ct_replace_unicode_escape_sequence($match) {
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}
/**
* Encode/decode widget params to make sure these won't brake shortocdes with quotes or similar
*
* @author Ilya K.
* @since 2.0
*/
function ct_encode_widget_instance($array_value) {
return array_map(function($value) {
if ( is_array($value) ) {
return ct_encode_widget_instance($value);
}
elseif ( is_bool($value) ) {
return $value;
}
else {
return base64_encode($value);
}
}, $array_value );
}
function ct_decode_widget_instance($array_value) {
return array_map(function($value) {
if ( is_array($value) ) {
return ct_decode_widget_instance($value);
}
elseif ( is_bool($value) ) {
return $value;
}
else {
return base64_decode($value);
}
}, $array_value );
}
/**
* Encode [] brackets to special _OXY_..._BRACKET_ string
* so the shortcodes doesn't render inside text components
*
* @author Ilya K.
* @since 2.1
*/
function oxygen_vsb_filter_shortcode_content_encode($content) {
// exclude [oxygen data=""] shortcodes
preg_match_all('/\[oxygen[^\]]*\]/m', $content, $matches);
if (is_array($matches)) {
foreach ($matches as $key => $match) {
if (isset($match[0])){
$content = str_replace($match[0], "_OXYGEN_DATA_".$key."_", $content);
}
}
}
$content = str_replace("[", "_OXY_OPENING_BRACKET_", $content);
$content = str_replace("]", "_OXY_CLOSING_BRACKET_", $content);
// include [oxygen data=""] shortcodes back
if (is_array($matches)) {
foreach ($matches as $key => $match) {
if (isset($match[0])){
$content = str_replace("_OXYGEN_DATA_".$key."_", $match[0], $content);
}
}
}
return $content;
}
/**
* Decode special _OXY_..._BRACKET_ srtings back to []
* so the shortcodes doesn't render inside text components
*
* @author Ilya K.
* @since 2.1
*/
function oxygen_vsb_filter_shortcode_content_decode($content) {
$content = str_replace("_OXY_OPENING_BRACKET_", "[", $content);
$content = str_replace("_OXY_CLOSING_BRACKET_", "]", $content);
return $content;
}
/**
* Helpers for safe base64 encoding/decoding
*
* @author Ilya K.
* @since 3.3
*/
function oxygen_vsb_base64_encode($content) {
// sign shortcodes before base64_encode
$content = preg_replace_callback('/\[oxygen ([^\]]*)\]/i', 'ct_sign_oxy_dynamic_shortcode', $content);
$content = "oxy_base64_encoded::".base64_encode($content);
return $content;
}
function oxygen_vsb_base64_decode($content) {
if (is_array($content)) return $content;
if (strpos($content, "oxy_base64_encoded::") === 0) {
$base64 = str_replace("oxy_base64_encoded::", "", $content);
$content = base64_decode( $base64 );
}
return $content;
}
/**
* Helpers for htmlspecialchars alternative for decoding/encoding quotes
*
* @author Ilya K.
* @since 3.3.2
*/
function oxygen_vsb_quotes_encode($content) {
if ( stripos($content, '[oxygen' ) !== false ) {
return $content;
}
$content = str_replace("'", "'", $content);
$content = str_replace("\"", """, $content);
return $content;
}
function oxygen_vsb_quotes_decode($content) {
if ( stripos($content, '[oxygen' ) !== false ) {
return $content;
}
$content = str_replace("'", "'", $content);
$content = str_replace(""", "\"", $content);
return $content;
}