, Ruben Garcia * @since 1.0.0 */ // Exit if accessed directly if( !defined( 'ABSPATH' ) ) exit; /** * Render automation type dialog * * @since 1.3.0 */ function automatorwp_render_automation_type_dialog() { if( ! isset( $_GET['page'] ) ) { return; } $allowed_pages = array( 'automatorwp_automations', 'edit_automatorwp_automations', ); // Only render on allowed pages if( ! in_array( $_GET['page'], $allowed_pages ) ) { return; } $types = automatorwp_get_automation_types(); ?> name !== 'automatorwp_automations' ) { return $classes; } $primary_key = $ct_table->db->primary_key; if( ! isset( $_GET[$primary_key] ) ) { return $classes; } $automation_id = (int) $_GET[$primary_key]; $automation = $ct_table->db->get( $automation_id ); $classes .= ' edit-' . $automation->type . '-automation '; $classes = apply_filters( 'automatorwp_automation_ui_admin_body_class', $classes, $automation ); return $classes; } add_filter( 'admin_body_class', 'automatorwp_automation_ui_admin_body_class' ); /** * Automation UI meta boxes * * @since 1.0.0 */ function automatorwp_automation_ui_add_meta_boxes() { add_meta_box( 'automatorwp_triggers', __( 'Triggers', 'automatorwp' ), 'automatorwp_automation_ui_triggers_meta_box', 'automatorwp_automations', 'normal', 'default' ); add_meta_box( 'automatorwp_actions', __( 'Actions', 'automatorwp' ), 'automatorwp_automation_ui_actions_meta_box', 'automatorwp_automations', 'normal', 'default' ); } add_action( 'add_meta_boxes', 'automatorwp_automation_ui_add_meta_boxes' ); /** * Renders the triggers meta box * * @since 1.0.0 * * @param stdClass $automation The automation object * @param string $type Type to render form */ function automatorwp_automation_ui_triggers_meta_box( $automation, $type ) { global $automatorwp_triggers_current_position; $automatorwp_triggers_current_position = 0; $triggers = automatorwp_get_automation_triggers( $automation->id ); ?>
sequential, 1 ); ?> />
id ); ?>
true, ); if( $item_type === 'trigger' ) { $choices_filters['anonymous'] = (bool) ( $automation->type === 'anonymous' ); } // Sort integrations $integrations = AutomatorWP()->integrations; ksort( $integrations ); ?> type ); } else if( $item_type === 'action' ) { $type_args = automatorwp_get_action( $object->type ); } /** * Get the object type args * * @since 1.0.0 * * @param array $type_args The trigger/action args * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * * @return array */ return apply_filters( 'automatorwp_automation_item_type_args', $type_args, $object, $item_type ); } /** * Renders the trigger/action edit HTML * * @since 1.0.0 * * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param stdClass $automation The automation object */ function automatorwp_automation_item_edit_html( $object, $item_type, $automation ) { global $automatorwp_triggers_current_position; // Check item type if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) { return; } // Check type args $type_args = automatorwp_automation_item_type_args( $object, $item_type ); if( ! $type_args ) { automatorwp_automation_missing_integration_item_edit_html( $object, $item_type, $automation ); return; } // Check integration $integration = automatorwp_get_integration( $type_args['integration'] ); if( ! $integration ) { automatorwp_automation_missing_integration_item_edit_html( $object, $item_type, $automation ); return; } if( $item_type === 'action' && $object->type === 'automatorwp_anonymous_user' ) { $integration['icon'] = AUTOMATORWP_URL . 'assets/img/automatorwp-anonymous.svg'; } // Setup the item classes $classes = array( 'automatorwp-automation-item', 'automatorwp-' . $item_type, 'automatorwp-' . $item_type . '-' . str_replace( '_', '-', $object->type ), ); if( $object->type === 'filter' ) { $classes[] = 'automatorwp-automation-item-filter'; } // Setup the item actions $actions = array( 'move-up' => array( 'label' => __( 'Move up', 'automatorwp'), 'icon' => 'arrow-up-alt2' ), 'move-down' => array( 'label' => __( 'Move down', 'automatorwp'), 'icon' => 'arrow-down-alt2' ), 'delete' => array( 'label' => __( 'Delete', 'automatorwp'), 'icon' => 'trash' ), ); // Anonymous if( $automation->type === 'anonymous' ) { if( $item_type === 'trigger' ) { $classes[] = 'automatorwp-no-grab'; unset( $actions['move-up'] ); unset( $actions['move-down'] ); } else if( $object->type === 'automatorwp_anonymous_user' ) { $classes[] = 'automatorwp-no-grab'; unset( $actions['move-up'] ); unset( $actions['move-down'] ); unset( $actions['delete'] ); } } /** * Filter to modify the integration args of the trigger/action edit HTML * * @since 1.0.0 * * @param array $integration The integration args * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param stdClass $automation The automation object * * @return array */ $integration = apply_filters( 'automatorwp_automation_item_edit_html_integration', $integration, $object, $item_type, $automation ); /** * Filter to modify the CSS classes of the trigger/action edit HTML * * @since 1.3.0 * * @param array $classes The trigger/action CSS classes * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param stdClass $automation The automation object * * @return array */ $classes = apply_filters( 'automatorwp_automations_ui_item_edit_html_classes', $classes, $object, $item_type, $automation ); /** * Filter to modify the actions of the trigger/action edit HTML * * @since 1.3.0 * * @param array $actions The trigger/action actions * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param stdClass $automation The automation object * * @return array */ $actions = apply_filters( 'automatorwp_automations_ui_item_edit_html_actions', $actions, $object, $item_type, $automation ); ?>
<?php echo esc_attr( $integration['label'] ); ?>
$action_args ) : ?>
position + 1 ); if( $object->type !== 'filter' && is_int( $automatorwp_triggers_current_position ) ) { $automatorwp_triggers_current_position++; } ?>
.
$args ) : ?>
type === 'anonymous' ) { $create = false; // Check if the first action is the action required for anonymous automations if( ! isset( $actions[0] ) ) { $create = true; } if( isset( $actions[0] ) && $actions[0]->type !== 'automatorwp_anonymous_user' ) { $create = true; } if( $create ) { ct_setup_table( 'automatorwp_actions' ); $action_data = array( 'automation_id' => $automation->id, 'title' => sprintf( __( 'Actions will be run on %1$s', 'automatorwp' ), '{user}' ), 'type' => 'automatorwp_anonymous_user', 'status' => 'active', 'position' => '0', 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ), ); // Insert the new action $action_id = ct_insert_object( $action_data ); if( $action_id ) { $action_data['id'] = $action_id; $action_data = (object) $action_data; // Prepend the new action at start of the actions list array_unshift( $actions, $action_data ); } ct_reset_setup_table(); } } return apply_filters( 'automatorwp_check_automation_required_actions', $actions, $automation ); } /** * Renders the trigger/action missing integration edit HTML * * @since 1.1.2 * * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param stdClass $automation The automation object */ function automatorwp_automation_missing_integration_item_edit_html( $object, $item_type, $automation ) { if( $item_type === 'trigger' ) { $warning_message = __( 'Trigger disabled because plugin associated couldn\'t be found. Please, re-install the plugin associated or remove this trigger.', 'automatorwp' ); } else { $warning_message = __( 'Action disabled because plugin associated couldn\'t be found. Please, re-install the plugin associated or remove this action.', 'automatorwp' ); } ?>
position + 1; ?>.
title; ?>
$args ) { $replacements['{' . $option . '}'] = automatorwp_get_automation_item_option_replacement( $object, $item_type, $option, $context ); } /** * Trigger/action label replacements * * @since 1.0.0 * * @param array $replacements The replacements to apply * @param stdClass $object The trigger object * @param string $item_type The item type (trigger|action) * @param string $label The label to parse * @param string $context The context this function is executed * * @return array */ $replacements = apply_filters( 'automatorwp_parse_automation_item_label_replacements', $replacements, $object, $item_type, $label, $context ); $tags = array_keys( $replacements ); $label_parsed = str_replace( $tags, $replacements, $label ); /** * Trigger/action label parsed * * @since 1.0.0 * * @param string $label_parsed The label parsed * @param stdClass $object The trigger object * @param string $item_type The item type (trigger|action) * @param string $label The originallabel to parse * @param string $context The context this function is executed * @param array $tags The tags applied * @param array $replacements The replacements applied * * @return string */ return apply_filters( 'automatorwp_parse_automation_item_label', $label_parsed, $object, $item_type, $label, $context, $tags, $replacements ); } /** * Get the option replacement * * @since 1.0.0 * * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option The option name * @param string $context The context this function is executed * * @return string */ function automatorwp_get_automation_item_option_replacement( $object, $item_type, $option, $context = 'edit' ) { global $automatorwp_event; // Check item type if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) { return false; } // Check type args $type_args = automatorwp_automation_item_type_args( $object, $item_type ); if( ! $type_args ) { return ''; } // Bail if this type hasn't any option if( ! isset( $type_args['options'][$option] ) ) { return ''; } $option_args = $type_args['options'][$option]; $field_id = ( isset( $option_args['from'] ) ? $option_args['from'] : '' ); $value = ''; // If not isset the from field, try to get a default value if( ! isset( $option_args['fields'][$field_id] ) ) { if( isset( $option_args['default'] ) && ! empty( $option_args['default'] ) ) { $value = $option_args['default']; } } else { ct_setup_table( "automatorwp_{$item_type}s" ); $field = $option_args['fields'][$field_id]; $value = ct_get_object_meta( $object->id, $field_id, true ); if( ( $value === '' || is_null( $value ) ) && isset( $field['default'] ) ) { $value = $field['default']; } // Ensure the field value and escaped_value keys $field['object_id'] = $object->id; $field['value'] = $value; $field['escaped_value'] = $value; // Select field if( in_array( $field['type'], array( 'select', 'automatorwp_select', 'automatorwp_select_filter' ) ) ) { // Get the field options $field_options = automatorwp_get_field_options( $field ); // Try to get the displayed value $found = automatorwp_get_array_key_value( $value, $field_options ); if( $found ) { $value = $found; } } // Array values if( is_array( $value ) ) { // Get the field options $field_options = automatorwp_get_field_options( $field ); // Replace values by the options label if( count( $field_options ) ) { foreach( $value as $i => $v ) { // Try to get the displayed value $found = automatorwp_get_array_key_value( $v, $field_options ); if( isset( $found ) ) { $value[$i] = $found; } } } /* translators: The ampersand character who represents the word "and" */ $and = __( '&', 'automatorwp' ); $value = automatorwp_implode_array( ', ', " {$and} ", $value ); } // Fallback to default option if exists if( ( $value === '' || is_null( $value ) ) && isset( $option_args['default'] ) && ! empty( $option_args['default'] ) ) { $value = $option_args['default']; } ct_reset_setup_table(); } /** * Filters the option value for replacement on labels * * @since 1.0.0 * * @param string $value The option value * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option The option name * @param string $context The context this function is executed * * @return string */ $value = apply_filters( 'automatorwp_get_automation_item_option_replacement', $value, $object, $item_type, $option, $context ); if( $context === 'edit' ) { $option_class = 'button button-primary'; if( $object->type === 'filter' ) { $option_class = 'button'; } /** * Filters the option button class * * @since 1.2.4 * * @param string $option_class The option class, by default "button button-primary" * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option The option name * @param string $context The context this function is executed * * @return string */ $option_class = apply_filters( 'automatorwp_get_automation_item_option_button_class', $option_class, $object, $item_type, $option, $context ); $value = '' . $value . ''; } else if( $context === 'view' ) { $automation = automatorwp_get_trigger_automation( $object->id ); if( is_object( $automation ) ) { $user_id = ( isset( $automatorwp_event['user_id'] ) ? $automatorwp_event['user_id'] : 0 ); $value = automatorwp_parse_automation_tags( $automation->id, $user_id, $value ); } } return $value; } /** * Gets a CMB2 object from a trigger/action option * * @since 1.0.0 * * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option Option form to render * @param stdClass $automation The automation object * * @return CMB2|false */ function automatorwp_get_automation_item_option_form( $object, $item_type, $option, $automation ) { // Check item type if( ! in_array( $item_type, array( 'trigger', 'action' ) ) ) { return false; } // Check type args $type_args = automatorwp_automation_item_type_args( $object, $item_type ); if( ! $type_args ) { return false; } // Bail if this type hasn't any option if( ! isset( $type_args['options'][$option] ) ) { return false; } $args = $type_args['options'][$option]; /** * Filter to override the trigger/action option fields * * @since 1.0.0 * * @param array $fields The option fields * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option Option form to render * @param stdClass $automation The automation object * * @return array */ $fields = apply_filters( 'automatorwp_get_automation_item_option_form_fields', $args['fields'], $object, $item_type, $option, $automation ); ct_setup_table( "automatorwp_{$item_type}s" ); // Setup the CMB2 form $cmb2 = new CMB2( array( 'id' => $option .'_form', 'object_types' => array( 'automatorwp_triggers', 'automatorwp_actions' ), 'classes' => 'automatorwp-form automatorwp-option-form', 'hookup' => false, ), $object->id ); // Setup the options fields foreach ( $fields as $field_id => $field ) { $field['id'] = $field_id; if( $field['type'] === 'group' ) { // Group fields // Setup field arguments on each group field foreach ( $field['fields'] as $field_group_id => $field_group ) { $field_group['id'] = $field_group_id; $field['fields'][$field_group_id] = automatorwp_automation_item_option_field_args( $object, $item_type, $option, $automation, $field_id . '[' .$field_group_id . ']', $field_group ); } } else { // Single fields $field = automatorwp_automation_item_option_field_args( $object, $item_type, $option, $automation, $field_id, $field ); } // Add the field to the form $cmb2->add_field( $field ); } ct_reset_setup_table(); return $cmb2; } /** * Gets a CMB2 object from a trigger option * * @since 1.0.0 * * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option Option form to render * @param stdClass $automation The automation object * @param string $field_id The field ID * @param array $field The field parameters * * @return array */ function automatorwp_automation_item_option_field_args( $object, $item_type, $option, $automation, $field_id, $field ) { $repeatable = ( isset( $field['repeatable'] ) && $field['repeatable'] === true ); // Prevent to render field names to avoid conflicts on the main form $field['attributes']['name'] = ''; // Update id attribute to avoid id collisions $field['attributes']['id'] = $field_id . '-' . $object->id; $field['attributes']['data-option'] = $field_id . ( $repeatable ? '[]' : '' ); // Setup the fields tags selector // Set a specific sanitization callback for fields that support HTML and URLs if( in_array( $field['type'], array( 'textarea', 'wysiwyg', 'oembed', 'file' ) ) ) { $field['sanitization_cb'] = 'automatorwp_textarea_sanitization_cb'; } // Check if field type is compatible with tags selector if( in_array( $field['type'], array( 'text', 'textarea', 'wysiwyg', 'file' ) ) ) { $field['after_field'] = automatorwp_get_tags_selector_html( $automation, $object, $item_type ); } // If field is required, update its label with the required mark if( isset( $field['required'] ) && $field['required'] && isset( $field['name'] ) ) { $field['name'] .= '*'; } /** * Filter available to process custom field parameters * * @since 1.0.0 * * @param array $field The field parameters * @param stdClass $object The trigger/action object * @param string $item_type The item type (trigger|action) * @param string $option Option form to render * @param stdClass $automation The automation object * @param string $field_id The field ID * * @return array */ return apply_filters( 'automatorwp_automation_item_option_field_args', $field, $object, $item_type, $option, $automation, $field_id ); }