Skip to content

Commit

Permalink
feat: allow title to use chained actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Soare-Robert-Daniel committed Mar 28, 2024
1 parent 7817bee commit fcad23c
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 54 deletions.
88 changes: 54 additions & 34 deletions includes/admin/feedzy-rss-feeds-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ class Feedzy_Rss_Feeds_Actions {
private static $instance;

/**
* Content actions.
* Serialized content actions. It can contain a mix of magic tags and simple text.
*
* @var string $actions Content actions.
* @var string $raw_serialized_actions Content actions.
*/
private $actions;
private $raw_serialized_actions;

/**
* Setting options.
Expand All @@ -39,7 +39,7 @@ class Feedzy_Rss_Feeds_Actions {
/**
* Extract tags.
*
* @var string $extract_tags Extract tags.
* @var array $extract_tags Extract tags.
*/
private $extract_tags;

Expand Down Expand Up @@ -72,11 +72,11 @@ class Feedzy_Rss_Feeds_Actions {
public $result = '';

/**
* Post content.
* The field content (title, description, post content, date, etc.)
*
* @var string $post_content
* @var string $field_content
*/
public $post_content = '';
public $field_content = '';

/**
* Default value.
Expand Down Expand Up @@ -129,13 +129,13 @@ public static function instance() {
/**
* Run actions.
*
* @param string $actions Item content actions.
* @return string
* @param string $raw_serialized_actions Item content actions.
* @return string|array
*/
public function set_actions( $actions = '' ) {
$this->actions = $actions;
if ( empty( $this->actions ) ) {
return $this->actions;
public function set_raw_serialized_actions( $raw_serialized_actions = '' ) {
$this->raw_serialized_actions = $raw_serialized_actions;
if ( empty( $this->raw_serialized_actions ) ) {
return $this->raw_serialized_actions;
}
$this->extract_tags = $this->extract_magic_tags();
return $this->extract_tags;
Expand All @@ -154,10 +154,23 @@ public function set_settings( $options ) {
/**
* Extract magic tags.
*
* @return string
* @return array|array[]
*/
public function extract_magic_tags() {
preg_match_all( '/\[\[\{(.*)\}\]\]/U', $this->actions, $item_magic_tags, PREG_PATTERN_ORDER );
/**
* Transform the serialized string of magic tags to array.
*
* Input(string): [[{"value":"[{"id":"chat_gpt_rewrite","tag":"item_title","data":{"ChatGPT":"Create a long description: {content}"}},{"id":"fz_summarize","tag":"item_title","data":{"fz_summarize":true}}]"}]] with a nice weather.
*
* Output:
* [
* [
* [replace_to] => [[{"value":"[{"id":"chat_gpt_rewrite","tag":"item_title","data":{"ChatGPT":"Create a long description: {content}"}},{"id":"fz_summarize","tag":"item_title","data":{"fz_summarize":true}}]"}]]
* [replace_with] => [{"id":"chat_gpt_rewrite","tag":"item_title","data":{"ChatGPT":"Create a long description: {content}"}},{"id":"fz_summarize","tag":"item_title","data":{"fz_summarize":true}}]
* ]
* ]
*/
preg_match_all( '/\[\[\{(.*)\}\]\]/U', $this->raw_serialized_actions, $item_magic_tags, PREG_PATTERN_ORDER );
$extract_tags = array();
if ( ! empty( $item_magic_tags[0] ) ) {
$extract_tags = array_map(
Expand All @@ -175,12 +188,14 @@ function( $tag ) {
}

/**
* Get magic tags.
* Get the extracted serialized actions from the Tagify tags. The actions can be a mix of Tagify tags and simple text.
*
* @return string The serialized actions.
*/
public function get_tags() {
public function get_serialized_actions() {
$replace_to = array_column( $this->get_extract_tags(), 'replace_to' );
$replace_with = array_column( $this->get_extract_tags(), 'replace_with' );
return str_replace( $replace_to, $replace_with, $this->actions );
return str_replace( $replace_to, $replace_with, $this->raw_serialized_actions );
}

/**
Expand All @@ -191,17 +206,21 @@ public function get_extract_tags() {
}

/**
* Get actions.
* Get actions. Return pairs of serialized actions and their deserialized versions.
*
* Deserialized version is used to run the action job. While serialized version is used to replace the job result in the input content.
*
* @return array
*/
public function get_actions() {
$replace_with = array_column( $this->get_extract_tags(), 'replace_with' );
$actions = array_map(
function( $action ) {
$replace_with = json_decode( $action );
if ( $replace_with ) {
function( $serialized_actions ) {
$job_actions = json_decode( $serialized_actions );
if ( $job_actions ) {
return array(
'replace_to' => wp_json_encode( $replace_with ),
'replace_with' => $replace_with,
'serialized_actions' => $serialized_actions,
'job_actions' => $job_actions,
);
}
return false;
Expand All @@ -214,46 +233,47 @@ function( $action ) {
/**
* Run action job.
*
* @param string $post_content Post content.
* @param string $field_content Field content. It can contain a mix of magic tags and simple text.
* @param string $import_translation_lang Translation language code.
* @param object $job Post object.
* @param string $language_code Feed language code.
* @param array $item Feed item.
* @param string $default_value Default value.
* @return string
*/
public function run_action_job( $post_content, $import_translation_lang, $job, $language_code, $item, $default_value = '' ) {
public function run_action_job( $field_content, $import_translation_lang, $job, $language_code, $item, $default_value = '' ) {
$this->item = $item;
$this->job = $job;
$this->language_code = $language_code;
$this->translation_lang = $import_translation_lang;
$this->post_content = $post_content;
$this->field_content = $field_content;
$this->default_value = $default_value;
$actions = $this->get_actions();

if ( ! empty( $actions ) ) {
foreach ( $actions as $key => $jobs ) {
if ( ! isset( $jobs['replace_with'] ) ) {
if ( ! isset( $jobs['job_actions'] ) ) {
continue;
}

$this->result = null;
$replace_with = isset( $jobs['replace_with'] ) ? $jobs['replace_with'] : array();
$replace_to = isset( $jobs['replace_to'] ) ? $jobs['replace_to'] : '';
foreach ( $replace_with as $job ) {
$jobs_actions = $jobs['job_actions'];
$replace_to = isset( $jobs['serialized_actions'] ) ? $jobs['serialized_action'] : '';
foreach ( $jobs_actions as $job ) {
$this->current_job = $job;
$this->result = $this->action_process();
}
if ( 'item_image' === $this->type ) {
$this->post_content = str_replace( $replace_to, $this->result, wp_json_encode( $replace_with ) );
$this->field_content = str_replace( $replace_to, $this->result, wp_json_encode( $jobs_actions ) );
} else {
$this->post_content = str_replace( $replace_to, $this->result, $this->post_content );
$this->field_content = str_replace( $replace_to, $this->result, $this->field_content );
}
}
}
if ( empty( $actions ) && 'item_image' === $this->type ) {
return $default_value;
}
return $this->post_content;
return $this->field_content;
}

/**
Expand Down
26 changes: 17 additions & 9 deletions includes/admin/feedzy-rss-feeds-import.php
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,10 @@ private function run_job( $job, $max ) {
$translated_title = apply_filters( 'feedzy_invoke_auto_translate_services', $item['item_title'], '[#translated_title]', $import_translation_lang, $job, $language_code, $item );
}

$import_title = rawurldecode( $import_title );
$import_title = str_replace( PHP_EOL, "\r\n", $import_title );
$import_title = trim( $import_title );

$post_title = str_replace(
array(
'[#item_title]',
Expand All @@ -1448,6 +1452,10 @@ private function run_job( $job, $max ) {
$post_title = apply_filters( 'feedzy_parse_custom_tags', $post_title, $item_obj );
}

$title_action = $this->get_actions_runner( $post_title, 'item_title' );
$post_title = $title_action->get_serialized_actions();
$post_title = $title_action->run_action_job( $post_title, $translated_title, $job, $language_code, $item );

$post_title = apply_filters( 'feedzy_invoke_services', $post_title, 'title', $item['item_title'], $job );

// Get translated item link text.
Expand Down Expand Up @@ -1543,8 +1551,8 @@ private function run_job( $job, $max ) {
$post_content = apply_filters( 'feedzy_invoke_services', $post_content, 'full_content', $full_content, $job );
}
// Item content action.
$content_action = $this->handle_content_actions( $post_content, 'item_content' );
$post_content = $content_action->get_tags();
$content_action = $this->get_actions_runner( $post_content, 'item_content' );
$post_content = $content_action->get_serialized_actions();
// Item content action process.
$post_content = $content_action->run_action_job( $post_content, $import_translation_lang, $job, $language_code, $item );
// Parse custom tags.
Expand Down Expand Up @@ -1829,7 +1837,7 @@ function( $term ) {
// Item image action.
$import_featured_img = rawurldecode( $import_featured_img );
$import_featured_img = trim( $import_featured_img );
$img_action = $this->handle_content_actions( $import_featured_img, 'item_image' );
$img_action = $this->get_actions_runner( $import_featured_img, 'item_image' );
// Item image action process.
$image_url = $img_action->run_action_job( $import_featured_img, $import_translation_lang, $job, $language_code, $item, $image_url );

Expand Down Expand Up @@ -2310,8 +2318,8 @@ public function render_magic_tags( $default, $tags, $type ) {
$disabled[ str_replace( ':disabled', '', $tag ) ] = $label;
continue;
}
if ( in_array( $type, array( 'import_post_content', 'import_post_featured_img' ), true ) ) {
if ( in_array( $tag, array( 'item_content', 'item_description', 'item_full_content', 'item_categories', 'item_image' ), true ) ) {
if ( in_array( $type, array( 'import_post_content', 'import_post_featured_img', 'import_post_title' ), true ) ) {
if ( in_array( $tag, array( 'item_content', 'item_description', 'item_full_content', 'item_categories', 'item_image', 'item_title' ), true ) ) {
$default .= '<a class="dropdown-item" href="#" data-field-name="' . $type . '" data-field-tag="' . $tag . '" data-action_popup="' . $tag . '">' . $label . ' <small>[#' . $tag . ']</small></a>';
continue;
}
Expand Down Expand Up @@ -2917,16 +2925,16 @@ private function wizard_import_feed() {
}

/**
* Handle item content actions.
* Get the content action runner used for processing the chained actions from the tags.
*
* @param string $actions Item content actions.
* @param string $type Action type.
* @return object `Feedzy_Rss_Feeds_Actions` class instance.
* @return Feedzy_Rss_Feeds_Actions The class instance.
*/
public function handle_content_actions( $actions = '', $type = '' ) {
public function get_actions_runner( $actions = '', $type = '' ) {
$action_instance = Feedzy_Rss_Feeds_Actions::instance();
$action_instance->type = $type;
$action_instance->set_actions( $actions );
$action_instance->set_raw_serialized_actions( $actions );
$action_instance->set_settings( $this->settings );
return $action_instance;
}
Expand Down
2 changes: 1 addition & 1 deletion includes/views/import-metabox-edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ class="dashicons dashicons-arrow-down-alt2"></span>
?>
</div>
</div>
<div class="fz-input-group-right">
<div class="fz-input-group-right fz-title-action-tags">
<div class="dropdown">
<button type="button" class="btn btn-outline-primary btn-add-fields dropdown-toggle" aria-haspopup="true" aria-expanded="false">
<?php esc_html_e( 'Insert Tag', 'feedzy-rss-feeds' ); ?> <span class="dashicons dashicons-plus-alt2"></span>
Expand Down
21 changes: 11 additions & 10 deletions js/ActionPopup/action-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,26 +150,27 @@ const ActionModal = () => {
window?.tiTrk?.with('feedzy').add( { feature: 'import_action', featureValue: item?.id, groupId: item?.tag ?? '' } );
});

// Serialize the action.
let _action = encodeURIComponent( JSON.stringify( action ) );
if ( action.length === 0 ) {
setAction([]);
_action = encodeURIComponent( JSON.stringify( [ { id: '', tag: shortCode, data: {} } ] ) );
}

let postContent = jQuery( 'import_post_content' === fieldName ? 'textarea.fz-textarea-tagify' : 'input.fz-tagify-image' ).data('tagify');
const inputField = jQuery( `[name="feedzy_meta_data[${fieldName}]"]:is(textarea, input)` ).data('tagify');

if ( 'import_post_featured_img' === fieldName ) {
postContent.removeAllTags();
postContent.addEmptyTag();
postContent.clearPersistedData();
inputField.removeAllTags();
inputField.addEmptyTag();
inputField.clearPersistedData();
}
if ( null === editModeTag || 'import_post_featured_img' === fieldName ) {
let tagElm = postContent.createTagElem({value: _action})
postContent.injectAtCaret(tagElm)
let elm = postContent.insertAfterTag(tagElm)
postContent.placeCaretAfterNode(elm)
let tagElm = inputField.createTagElem({value: _action})
inputField.injectAtCaret(tagElm)
let elm = inputField.insertAfterTag(tagElm)
inputField.placeCaretAfterNode(elm)
} else {
postContent.replaceTag(editModeTag.closest( '.fz-content-action' ), {value: _action});
inputField.replaceTag(editModeTag.closest( '.fz-content-action' ), {value: _action});
}
closeModal();
};
Expand Down

0 comments on commit fcad23c

Please sign in to comment.