function et_fb_process_to_shortcode($object, $options = array(), $library_item_type = '') { $output = ''; $_object = array(); // do not proceed if $object is empty if (empty($object)) { return ''; } $font_icon_fields = isset($options['post_type']) ? ET_Builder_Element::get_font_icon_fields($options['post_type']) : false; $structure_types = ET_Builder_Element::get_structure_module_slugs(); if (in_array($library_item_type, array('module', 'row'))) { $excluded_elements = array(); switch ($library_item_type) { case 'module': $excluded_elements = array('et_pb_section', 'et_pb_row', 'et_pb_column'); break; case 'row': $excluded_elements = array('et_pb_section'); break; } foreach ($object as $item) { // do not proceed if $item is empty if (empty($item)) { continue; } while (in_array($item['type'], $excluded_elements)) { $item = $item['content'][0]; } $_object[] = $item; } } else { $_object = $object; } foreach ($_object as $item) { // do not proceed if $item is empty if (empty($item)) { continue; } $attributes = ''; $content = ''; $type = sanitize_text_field($item['type']); $type = esc_attr($type); if (!empty($item['raw_child_content'])) { $content = stripslashes($item['raw_child_content']); } foreach ($item['attrs'] as $attribute => $value) { // ignore computed fields if ('__' == substr($attribute, 0, 2)) { continue; } // Sanitize attribute $attribute = sanitize_text_field($attribute); // Sanitize input properly if (isset($font_icon_fields[$item['type']][$attribute])) { $value = esc_attr($value); } else { // allow the use of '<', '>' characters within Custom CSS settings if (0 !== strpos($attribute, 'custom_css_')) { $replace_pairs = array('>' => '>', '<' => '<'); $value = strtr($value, $replace_pairs); } } // handle content if (in_array($attribute, array('content_new', 'raw_content'))) { // do not override the content if item has raw_child_content if (empty($item['raw_child_content'])) { $content = $value; if ('raw_content' == $attribute) { $content = esc_html($content); } $content = trim($content); if (!empty($content) && 'content_new' == $attribute) { $content = "\n\n" . $content . "\n\n"; } } } else { if ('' !== $value) { // TODO, should we check for and handle default here? probably done in FB alredy... // Make sure double quotes are encoded, before adding values to shortcode $value = str_ireplace('"', '%22', $value); // do not escape $value here - it breaks special characters. It was sanitized already $attributes .= ' ' . esc_attr($attribute) . '="' . $value . '"'; } } } // build shortcode // start the opening tag $output .= '[' . $type . $attributes; // close the opening tag, depending on self closing if (empty($content) && !isset($item['content']) && !in_array($type, $structure_types)) { $open_tag_only = true; $output .= ' /]'; } else { $open_tag_only = false; $output .= ']'; } // if applicable, add inner content and close tag if (!$open_tag_only) { if (isset($item['content']) && is_array($item['content'])) { $output .= et_fb_process_to_shortcode($item['content'], $options); } else { if (!empty($content)) { $output .= $content; } else { if (isset($item['content'])) { $_content = $item['content']; $_content = str_replace('\\', '\\\\', $_content); $output .= $_content; } else { $output .= ''; } } } // add the closing tag $output .= '[/' . $type . ']'; } } return $output; }