diff --git a/css/settings.css b/css/settings.css index f4a89a5d..62428c54 100644 --- a/css/settings.css +++ b/css/settings.css @@ -2971,3 +2971,7 @@ button.feedzy-action-button { font-size: 12px; padding: 4px 12px; } +.tagify__tag .feedzy-custom-tag { + cursor: auto; + line-height: 1.5; +} diff --git a/includes/admin/feedzy-rss-feeds-actions.php b/includes/admin/feedzy-rss-feeds-actions.php index e7bb7815..66b09aa3 100644 --- a/includes/admin/feedzy-rss-feeds-actions.php +++ b/includes/admin/feedzy-rss-feeds-actions.php @@ -315,6 +315,8 @@ public function action_process() { return $this->generate_image(); case 'modify_links': return $this->modify_links(); + case 'custom_html': + return $this->custom_html(); default: return $this->default_content(); } @@ -619,5 +621,14 @@ private function custom_field() { } return $this->default_value; } + + /** + * Get Custom HTML tag. + * + * @return string + */ + private function custom_html() { + return $this->current_job->tag; + } } } diff --git a/includes/admin/feedzy-rss-feeds-import.php b/includes/admin/feedzy-rss-feeds-import.php index 650315a6..c7de5e0a 100644 --- a/includes/admin/feedzy-rss-feeds-import.php +++ b/includes/admin/feedzy-rss-feeds-import.php @@ -643,6 +643,7 @@ public function save_feedzy_import_feed_meta( $post_id, $post ) { } } else { if ( 'import_post_content' === $key ) { + $val = escape_html_to_tag( $val ); $val = feedzy_custom_tag_escape( $val ); } elseif ( 'default_thumbnail_id' === $key && ! empty( $val ) ) { $val = explode( ',', $val ); diff --git a/includes/feedzy-rss-feeds-feed-tweaks.php b/includes/feedzy-rss-feeds-feed-tweaks.php index 48d8338e..953dd6bc 100644 --- a/includes/feedzy-rss-feeds-feed-tweaks.php +++ b/includes/feedzy-rss-feeds-feed-tweaks.php @@ -672,3 +672,72 @@ function feedzy_show_review_notice() { return $imported_posts->have_posts(); } + +/** + * Escape the HTML tag and convert it to the tagify tag value. + * + * @param string $content Content. + * @return string + */ +function escape_html_to_tag( $content ) { + + $protected_blocks = array(); + $placeholder_tpl = '__TAG_%d__'; + + $content = preg_replace_callback( + '/\[\[\{[\s\S]*?\}\]\]/', + function ( $value ) use ( &$protected_blocks, $placeholder_tpl ) { + $index = count( $protected_blocks ); + $protected_blocks[] = $value[0]; + return sprintf( $placeholder_tpl, $index ); + }, + $content + ); + + $base_content = $content; + $html_tags = array(); + $converted_value = ''; + + if ( preg_match_all( '/<[^>]+>[\s\S]*?<\/[^>]+>/', $content, $matches ) ) { + foreach ( $matches[0] as $match ) { + + $base_content = str_replace( $match, '', $base_content ); + $html_tags[] = array( + 'value' => rawurlencode( + wp_json_encode( + array( + array( + 'id' => 'custom_html', + 'tag' => $match, + ), + ) + ) + ), + ); + } + } + + foreach ( $protected_blocks as $i => $block ) { + $base_content = str_replace( + sprintf( $placeholder_tpl, $i ), + $block, + $base_content + ); + } + + foreach ( $html_tags as $tag ) { + $converted_value .= wp_json_encode( + array( + array( + $tag, + ), + ) + ); + } + + if ( ! empty( $converted_value ) ) { + $base_content .= $converted_value; + } + + return $base_content; +} diff --git a/includes/views/js/import-metabox-edit.js b/includes/views/js/import-metabox-edit.js index 352c7567..a1b3a7de 100644 --- a/includes/views/js/import-metabox-edit.js +++ b/includes/views/js/import-metabox-edit.js @@ -869,13 +869,23 @@ typeof tagData.value === 'string' && decodeTagData !== tagData.value; let tagLabel = tagData.value; + let isCustomHTML = false; if (isEncoded) { decodeTagData = JSON.parse(decodeTagData); decodeTagData = decodeTagData[0] || {}; tagLabel = decodeTagData.tag.replaceAll('_', ' '); + isCustomHTML = 'custom_html' === decodeTagData.id; tagData['data-actions'] = tagData.value; tagData['data-field_id'] = 'fz-content-action-tags'; } + if ( isCustomHTML ) { + tagLabel = escapeText(tagLabel); + return ` + + ${tagLabel} + `; + } + return ` @@ -1050,6 +1060,29 @@ url.searchParams.delete('imported'); history.replaceState(history.state, '', url.href); } + + const tagify = mixContent.focus().data('tagify'); + + $(document).on('input', '.feedzy-post-content span', function () { + const tagElms = $(this).find('tag'); + tagElms.each((i, ele) => { + if ( $(ele).find('.feedzy-custom-tag').length ) { + const newValue = ele.innerText; + const data = tagify.getSetTagData(ele); + + let decodeTagData = decodeURIComponent(data.value); + decodeTagData = JSON.parse(decodeTagData); + decodeTagData = decodeTagData[0] || {}; + decodeTagData.tag = newValue; + + let encodeTagData = [ decodeTagData ]; + encodeTagData = JSON.stringify(encodeTagData, null, 0) + data.value = encodeURIComponent(encodeTagData); + + tagify.updateValueByDOMTags(); + } + }); + }); } function initSummary() { @@ -1539,3 +1572,16 @@ function initNewPostActions() { postTitle.select(); } } + +/** + * Escape the text. + */ +function escapeText( label ) { + return label + .trim() + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') +} \ No newline at end of file diff --git a/tests/test-import.php b/tests/test-import.php index 00c2913b..fbbc4515 100644 --- a/tests/test-import.php +++ b/tests/test-import.php @@ -115,6 +115,9 @@ public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic $import_custom_fields = get_post_meta( $p->ID, 'imports_custom_fields', true ); $import_feed_limit = get_post_meta( $p->ID, 'import_feed_limit', true ); + // The import_post_content goes through escape_html_to_tag() which converts HTML tags to JSON format + $expected_content = escape_html_to_tag( $magic_tags ); + if ( $check_duplicate ) { $remove_duplicates = get_post_meta( $p->ID, 'import_remove_duplicates', true ); $mark_duplicate_tag = get_post_meta( $p->ID, 'mark_duplicate_tag', true ); @@ -128,7 +131,7 @@ public function test_feedzy_imports( $random_name1, $random_name2, $urls, $magic $this->assertEquals( '', $exc_key ); $this->assertEquals( '[#item_title]', $import_title ); $this->assertEquals( '[#item_date]', $import_date ); - $this->assertEquals( "{$magic_tags}", $import_content ); + $this->assertEquals( $expected_content, $import_content ); $this->assertEquals( '[#item_image]', $import_featured_img ); $this->assertEquals( '', $import_custom_fields ); $this->assertEquals( $num_items, $import_feed_limit );