Seditio Source
Root |
./othercms/b2evolution_7.2.3/inc/automations/automations.ctrl.php
<?php
/**
 * This file implements the UI controller for browsing the automations.
 *
 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}.
 *
 * @package admin
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );


load_funcs( 'automations/model/_automation.funcs.php' );
load_class( 'automations/model/_automation.class.php', 'Automation' );
load_class( 'automations/model/_automationstep.class.php', 'AutomationStep' );

// Check permission:
check_user_perm( 'admin', 'normal', true );
check_user_perm( 'options', 'view', true );

param_action( '', true );
param( 'display_mode', 'string', 'normal' );
param( 'tab', 'string', 'settings', true );

if(
param( 'autm_ID', 'integer', '', true ) )
{    
// Load Automation object:
   
$AutomationCache = & get_AutomationCache();
    if( (
$edited_Automation = & $AutomationCache->get_by_ID( $autm_ID, false ) ) === false )
    {    
// We could not find the automation to edit:
       
unset( $edited_Automation );
       
forget_param( 'autm_ID' );
       
$action = '';
       
$Messages->add( sprintf( TB_('Requested &laquo;%s&raquo; object does not exist any longer.'), TB_('Automation') ), 'error' );
    }
}

if(
param( 'step_ID', 'integer', '', true ) )
{    
// Load AutomationStep object:
   
$AutomationStepCache = & get_AutomationStepCache();
    if( (
$edited_AutomationStep = & $AutomationStepCache->get_by_ID( $step_ID, false ) ) === false )
    {    
// We could not find the automation step to edit:
       
unset( $edited_AutomationStep );
       
forget_param( 'autm_ID' );
       
$action = '';
       
$Messages->add( sprintf( TB_('Requested &laquo;%s&raquo; object does not exist any longer.'), TB_('Automation step') ), 'error' );
    }
}

switch(
$action )
{
    case
'new':
       
// New Automation form:

        // Check permission:
       
check_user_perm( 'options', 'edit', true );

       
// Create object of new Automation:
       
$edited_Automation = new Automation();
        break;

    case
'edit':
    case
'edit_step':
    case
'copy_step':
       
// Edit Automation/Step forms:

        // Check permission:
       
check_user_perm( 'options', 'edit', true );

        if(
$action == 'copy_step' )
        {    
// Clear an order of the duplicating step in order to set this automatically right below current one:
           
$edited_AutomationStep->set( 'order', '' );
        }

        if( (
$action == 'edit_step' || $action == 'copy_step' ) && ! $edited_AutomationStep->can_be_modified() )
        {    
// If step cannot be modified currently
           
$Messages->add( TB_('You must pause the automation before changing step.'), 'warning' );
        }
        break;

    case
'new_step':
       
// New Automation Step form:

        // Check permission:
       
check_user_perm( 'options', 'edit', true );

       
// Create object of new Automation:
       
$edited_AutomationStep = new AutomationStep();
       
$edited_AutomationStep->set( 'autm_ID', $autm_ID );

        if( !
$edited_AutomationStep->can_be_modified() )
        {    
// If step cannot be modified currently
           
$Messages->add( TB_('You must pause the automation before creating new step.'), 'warning' );
        }
        break;

    case
'create':
       
// Create new Automation:
       
$edited_Automation = new Automation();

       
// Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check that current user has permission to create automations:
       
check_user_perm( 'options', 'edit', true );

       
// load data from request
       
if( $edited_Automation->load_from_Request() )
        {    
// We could load data from form without errors:
            // Insert in DB:
           
if( $edited_Automation->dbinsert() )
            {
               
$Messages->add( TB_('New automation has been created.'), 'success' );

               
// Create default step automatically:
               
$default_AutomationStep = new AutomationStep();
               
$default_AutomationStep->set( 'autm_ID', $edited_Automation->ID );
               
$default_AutomationStep->set( 'order', '1' );
               
$default_AutomationStep->set( 'type', 'notify_owner' );
               
$default_AutomationStep->set( 'info', '$login$ has ENTERED automation $automation_name$ (ID: $automation_ID$)'."\n\n".'Step $step_number$ (ID: $step_ID$)' );
               
$default_AutomationStep->set( 'yes_next_step_ID', 0 ); // Continue
               
$default_AutomationStep->set( 'yes_next_step_delay', 86400 ); // 1 day
               
$default_AutomationStep->set( 'error_next_step_ID', 1 ); // Loop
               
$default_AutomationStep->set( 'error_next_step_delay', 14400 ); // 4 hours
               
$default_AutomationStep->set_label();
               
$default_AutomationStep->dbinsert( false/* Insert step even when automation is not paused */ );
            }

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
$action = 'new';
        break;

    case
'update':
       
// Update Automation:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check that current user has permission to edit automations:
       
check_user_perm( 'options', 'edit', true );

       
// Make sure we got an autm_ID:
       
param( 'autm_ID', 'integer', true );

       
// load data from request:
       
if( $edited_Automation->load_from_Request() )
        {    
// We could load data from form without errors:
            // Update automation in DB:
           
$edited_Automation->dbupdate();
           
$Messages->add( TB_('Automation has been updated.'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
$action = 'edit';
        break;

    case
'delete':
       
// Delete Automation:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
// Make sure we got an autm_ID:
       
param( 'autm_ID', 'integer', true );

        if(
param( 'confirm', 'integer', 0 ) )
        {    
// Delete from DB if confirmed:
           
$msg = sprintf( TB_('The automation "%s" has been deleted.'), $edited_Automation->dget( 'name' ) );
           
$edited_Automation->dbdelete();
            unset(
$edited_Automation );
           
forget_param( 'autm_ID' );
           
$Messages->add( $msg, 'success' );
           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations', 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
        else
        {    
// Check for restrictions if not confirmed yet:
           
if( ! $edited_Automation->check_delete( sprintf( TB_('Cannot delete automation "%s"'), $edited_Automation->dget( 'name' ) ) ) )
            {    
// There are restrictions:
               
$action = 'view';
            }
        }
        break;

    case
'status_paused':
    case
'status_active':
       
// Toggle Automation status:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check that current user has permission to edit automations:
       
check_user_perm( 'options', 'edit', true );

       
// Make sure we got an autm_ID:
       
param( 'autm_ID', 'integer', true );
       
param( 'enlt_ID', 'integer', NULL );

       
// Change automation status depending on action:
       
$edited_Automation->set( 'status', ( $action == 'status_paused' ? 'paused' : 'active' ) );

       
// Update automation in DB:
       
if( $edited_Automation->dbupdate() )
        {
               
$Messages->add( ( $action == 'status_paused'
                       
? TB_('Automation has been paused.')
                        :
TB_('Automation has been activated.')
                    ),
'success' );
           
// We want to highlight the moved Step on next list display:
           
$Session->set( 'fadeout_array', array( 'autm_ID' => array( $edited_Automation->ID ) ) );
        }

       
// Set a redirect to page back where the status has been changes:
       
if( $enlt_ID > 0 )
        {    
// A list of automations on the edited List page:
           
$redirect_to = $admin_url.'?ctrl=newsletters&tab=automations&action=edit&enlt_ID='.$enlt_ID;
        }
        elseif(
$tab == 'steps' || $tab == 'diagram' )
        {    
// Tab "Steps" of the edited Automation page:
           
$redirect_to = $admin_url.'?ctrl=automations&action=edit&tab='.$tab.'&autm_ID='.$edited_Automation->ID;
        }
        else
        {    
// A list of all automations:
           
$redirect_to = $admin_url.'?ctrl=automations';
        }

       
// Redirect so that a reload doesn't write to the DB twice:
       
header_redirect( $redirect_to, 303 ); // Will EXIT
        // We have EXITed already at this point!!
       
break;

    case
'requeue':
       
// Requeue Automation for finished steps:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check that current user has permission to edit automations:
       
check_user_perm( 'options', 'edit', true );

       
// Make sure we got IDs:
       
param( 'autm_ID', 'integer', true );
       
param( 'target_step_ID', 'integer', true );

       
// Additional options to requeue a specific step or user:
       
param( 'source_step_ID', 'integer', NULL );
       
param( 'source_user_ID', 'integer', NULL );
        if(
$source_user_ID > 0 )
        {    
// Requeue only one specific user:
           
$requeue_sql_where = 'aust_user_ID = '.$DB->quote( $source_user_ID );
        }
        elseif(
$source_step_ID > 0 )
        {    
// Requeue a specific step:
           
$requeue_sql_where = 'aust_next_step_ID = '.$DB->quote( $source_step_ID );
        }
        else
        {    
// Requeue all finished steps:
           
$requeue_sql_where = 'aust_next_step_ID IS NULL';
        }

       
$requeued_users_num = intval( $DB->query( 'UPDATE T_automation__user_state
              SET aust_next_step_ID = '
.$DB->quote( $target_step_ID ).',
                  aust_next_exec_ts = '
.$DB->quote( date2mysql( $servertimenow ) ).'
            WHERE aust_autm_ID = '
.$edited_Automation->ID.'
              AND '
.$requeue_sql_where ) );

        if(
$requeued_users_num )
        {
           
$Messages->add( sprintf( TB_('Automation has been requeued for %d users.'), $requeued_users_num ), 'success' );
           
// We want to highlight the reduced Step on list display:
           
$Session->set( 'fadeout_array', array( 'aust_user_ID' => array( $source_user_ID ) ) );
        }

       
// Redirect so that a reload doesn't write to the DB twice:
       
if( $source_step_ID > 0 && $source_user_ID > 0 )
        {    
// Redirect to an edit page of the requeued step:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit_step&step_ID='.$target_step_ID, 303 ); // Will EXIT
       
}
        elseif(
$source_user_ID > 0 )
        {    
// Redirect to a page of Automation users:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=users&autm_ID='.$edited_Automation->ID, 303 ); // Will EXIT
       
}
        else
        {    
// Redirect to a page of Automation steps:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=steps&autm_ID='.$edited_Automation->ID, 303 ); // Will EXIT
       
}
       
// We have EXITed already at this point!!
       
break;

    case
'move_step_up':
    case
'move_step_down':
       
// Move up/down Automation Step:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check that current user has permission to create automation steps:
       
check_user_perm( 'options', 'edit', true );

        if( !
$edited_AutomationStep->can_be_modified() )
        {    
// If step cannot be modified currently
           
$Messages->add( TB_('You must pause the automation before changing step.'), 'error' );
           
$action = 'edit'; // To keep same opened page
            // We want to highlight the Step:
           
$Session->set( 'fadeout_array', array( 'step_ID' => array( $edited_AutomationStep->ID ) ) );
            break;
        }

       
// Make sure we got an step_ID:
       
param( 'step_ID', 'integer', true );

        if(
$action == 'move_step_up' )
        {    
// Set variables for "move up" action
           
$order_condition = '<';
           
$order_direction = 'DESC';
        }
        else
        {    
// move down
           
$order_condition = '>';
           
$order_direction = 'ASC';
        }

       
$DB->begin( 'SERIALIZABLE' );

       
// Get near step, We should swap the order with this step:
       
$SQL = new SQL( 'Get near Step to reorder it with moved Step #'.$edited_AutomationStep->ID );
       
$SQL->SELECT( 'step_ID, step_order' );
       
$SQL->FROM( 'T_automation__step' );
       
$SQL->WHERE( 'step_autm_ID = '.$edited_AutomationStep->get( 'autm_ID' ) );
       
$SQL->WHERE_and( 'step_order '.$order_condition.' '.$edited_AutomationStep->get( 'order' ) );
       
$SQL->ORDER_BY( 'step_order '.$order_direction );
       
$SQL->LIMIT( 1 );
       
$swaped_step = $DB->get_row( $SQL );

        if( empty(
$swaped_step ) )
        {    
// Current step is first or last in group, no change ordering:
           
$DB->commit(); // This is required only to not leave open transaction
           
$action = 'edit'; // To keep same opened page
           
break;
        }

       
// Switch orders of the steps:
       
$result = true;
        for(
$i = 0; $i < 2; $i++ )
        {    
// We can swap orders only in two SQL queries to avoid error of duplicate entry because of step_order is unique index per Automation:
            // By first SQL query we update the step orders to reserved values which cannot be assigned on edit form by user:
           
$step_order_1 = ( $i == 0 ? -2147483647 : $swaped_step->step_order );
           
$step_order_2 = ( $i == 0 ? -2147483648 : $edited_AutomationStep->get( 'order' ) );
           
$result = ( $result !== false ) && $DB->query( 'UPDATE T_automation__step
                SET step_order = CASE
                    WHEN step_ID = '
.$edited_AutomationStep->ID.' THEN '.$step_order_1.'
                    WHEN step_ID = '
.$swaped_step->step_ID.'    THEN '.$step_order_2.'
                    ELSE step_order
                END
                WHERE step_ID IN ( '
.$edited_AutomationStep->ID.', '.$swaped_step->step_ID.' )' );
        }

        if(
$result !== false )
        {    
// Update was successful:
           
$DB->commit();
           
$Messages->add( TB_('Order has been changed.'), 'success' );
           
// We want to highlight the moved Step on next list display:
           
$Session->set( 'fadeout_array', array( 'step_ID' => array( $edited_AutomationStep->ID ) ) );
        }
        else
        {    
// Couldn't update successfully, probably because of concurrent modification
            // Note: In this case we may try again to execute the same queries.
           
$DB->rollback();
           
// The message is not localized because it may appear very rarely
           
$Messages->add( 'Order could not be changed. Please try again.', 'error' );
        }

       
$action = 'edit'; // To keep same opened page
       
break;

    case
'create_step':
       
// Create new Automation Step:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check that current user has permission to create automation steps:
       
check_user_perm( 'options', 'edit', true );

       
$edited_AutomationStep = new AutomationStep();

       
$entered_step_order = param( 'step_order', 'integer', NULL );

       
// load data from request
       
if( $edited_AutomationStep->load_from_Request() &&
           
$edited_AutomationStep->pause_automation() )
        {    
// We could load data from form without errors and automation can be paused:
            // Insert in DB:
           
$edited_AutomationStep->dbinsert();
           
$Messages->add( TB_('New automation step has been created.'), 'success' );
           
// We want to highlight the moved Step on next list display:
           
$Session->set( 'fadeout_array', array( 'step_ID' => array( $edited_AutomationStep->ID ) ) );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab='.$tab.'&autm_ID='.$edited_AutomationStep->get( 'autm_ID' ), 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
$action = 'new_step';
       
$edited_AutomationStep->set( 'order', $entered_step_order );
        break;

    case
'duplicate_step':
       
// Duplicate Automation Step:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check that current user has permission to create automation steps:
       
check_user_perm( 'options', 'edit', true );

       
$duplicated_step_ID = $edited_AutomationStep->ID;
       
$duplicated_step_order = $edited_AutomationStep->get( 'order' );

       
$edited_AutomationStep = new AutomationStep();

       
$entered_step_order = param( 'step_order', 'integer', NULL );

       
// Load data from request:
       
if( $edited_AutomationStep->load_from_Request() &&
           
$edited_AutomationStep->pause_automation() )
        {    
// We could load data from form without errors and automation can be paused:
            // Insert in DB:
           
$edited_AutomationStep->dbinsert();

            if( empty(
$entered_step_order ) )
            {    
// Move the new created step right after the duplicated step:
               
$SQL = new SQL( 'Get steps of automation #'.$edited_AutomationStep->get( 'autm_ID' ).' before insert new step right below duplicated one' );
               
$SQL->SELECT( 'step_order' );
               
$SQL->FROM( 'T_automation__step' );
               
$SQL->WHERE( 'step_autm_ID = '.$DB->quote( $edited_AutomationStep->get( 'autm_ID' ) ) );
               
$SQL->WHERE_and( 'step_order > '.$DB->quote( $duplicated_step_order ) );
               
$SQL->ORDER_BY( 'step_order' );
               
$steps = $DB->get_col( $SQL );
                if( ! empty(
$steps ) && $steps[0] == $duplicated_step_order + 1 )
                {    
// If the duplicated step is NOT last AND the next order number is NOT free
                    // then we should shift all next steps down and use next order for new created step:
                   
$DB->query( 'UPDATE T_automation__step
                          SET step_order = step_order + 1
                        WHERE step_autm_ID = '
.$DB->quote( $edited_AutomationStep->get( 'autm_ID' ) ).'
                          AND step_order > '
.$DB->quote( $duplicated_step_order ).'
                        ORDER BY step_order DESC'
);
                   
$DB->query( 'UPDATE T_automation__step
                          SET step_order = '
.( $duplicated_step_order + 1 ).'
                        WHERE step_ID = '
.$DB->quote( $edited_AutomationStep->ID ) );
                }
            }

           
$Messages->add( TB_('Automation step has been duplicated.'), 'success' );
           
// We want to highlight the moved Step on next list display:
           
$Session->set( 'fadeout_array', array( 'step_ID' => array( $edited_AutomationStep->ID ) ) );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=steps&autm_ID='.$edited_AutomationStep->get( 'autm_ID' ), 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
// If errors, Display the step form again to fix them:
       
$action = 'copy_step';
       
$edited_AutomationStep->ID = $duplicated_step_ID;
       
$edited_AutomationStep->set( 'order', $entered_step_order );
        break;

    case
'update_step':
       
// Update Automation Step:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check that current user has permission to edit automation steps:
       
check_user_perm( 'options', 'edit', true );

       
// Make sure we got an step_ID:
       
param( 'step_ID', 'integer', true );

       
// load data from request:
       
if( $edited_AutomationStep->load_from_Request() &&
           
$edited_AutomationStep->pause_automation() )
        {    
// We could load data from form without errors and automation can be paused:
            // Update automation step in DB:
           
$edited_AutomationStep->dbupdate();
           
$Messages->add( TB_('Automation step has been updated.'), 'success' );
            if(
$tab != 'diagram' )
            {    
// We want to highlight the moved Step on next list display:
               
$Session->set( 'fadeout_array', array( 'step_ID' => array( $edited_AutomationStep->ID ) ) );
            }

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab='.$tab.'&autm_ID='.$edited_AutomationStep->get( 'autm_ID' ), 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}
       
$action = 'edit_step';
        break;

    case
'update_step_position':
       
// Update step position on automation diagram:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
param( 'pos', 'array:integer' );

        if(
count( $pos ) != 2 )
        {    
// Position array must contains 2 values: row|x and column|y:
           
debug_die( 'Wrong step position!' );
        }

       
// Update step position:
       
$edited_AutomationStep->set( 'diagram', implode( ':', $pos ) );
       
$edited_AutomationStep->dbupdate();

       
// Exit here because we don't need UI for this AJAX action:
       
exit;

    case
'update_step_connection':
       
// Update steps connection on automation diagram:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
param( 'connection_type', 'string', true );

        if( !
in_array( $connection_type, array( 'yes', 'no', 'error' ) ) )
        {    
// Wrong connection type:
           
debug_die( 'Wrong step connection type!' );
        }

       
// Set correct ID for next/target Step:
       
param( 'target_step_ID', 'integer' );
        if(
$target_step_ID > 0 )
        {    
// If step has been connected with target Step:
           
$target_AutomationStep = & $AutomationStepCache->get_by_ID( $target_step_ID );
            if(
$edited_AutomationStep->get_next_ordered_step_ID() == $target_AutomationStep->ID )
            {    
// If target Step is the next ordered Step we should use an option "Continue":
               
$target_step_ID = 0;
            }
            else
            {    
// Some other next target Step:
               
$target_step_ID = $target_AutomationStep->ID;
            }
        }
        else
        {    
// if step has been disconnected:
           
$target_step_ID = -1;
        }

       
// Update step connection or disconnection between the requested Steps:
       
$edited_AutomationStep->set( $connection_type.'_next_step_ID', $target_step_ID, true );
       
$edited_AutomationStep->dbupdate();

       
// Exit here because we don't need UI for this AJAX action:
       
exit;

    case
'reset_diagram':
       
// Reset steps positions on automation diagram to default positions:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
// Reset positions of all steps of the edited Automation:
       
$DB->query( 'UPDATE T_automation__step
              SET step_diagram = NULL
            WHERE step_autm_ID = '
.$DB->quote( $edited_Automation->ID ) );

       
$Messages->add( TB_('Diagram layout has been reset.'), 'success' );

       
// Redirect so that a reload doesn't write to the DB twice:
       
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=diagram&autm_ID='.$edited_Automation->ID, 303 ); // Will EXIT
        // We have EXITed already at this point!!
       
break;

    case
'delete_step':
       
// Delete Automation Step:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automationstep' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
// Make sure we got an autm_ID:
       
param( 'autm_ID', 'integer', true );

        if( !
$edited_AutomationStep->can_be_modified() )
        {    
// If step cannot be modified currently
           
$Messages->add( TB_('You must pause the automation before deleting step.'), 'error' );
        }
        elseif(
$edited_AutomationStep->dbdelete() )
        {
           
$Messages->add( TB_('Automation step has been deleted.'), 'success' );

           
// Redirect so that a reload doesn't write to the DB twice:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=steps&autm_ID='.$edited_AutomationStep->get( 'autm_ID' ), 303 ); // Will EXIT
            // We have EXITed already at this point!!
       
}

       
// Display the same edit automation page with steps list because step cannot be deleted by some restriciton:
       
$action = 'edit';
       
// We want to highlight the Step which cannot be deleted on next list display:
       
$Session->set( 'fadeout_array', array( 'step_ID' => array( $edited_AutomationStep->ID ) ) );
        break;

    case
'reduce_step_delay':
       
// Reduce step delay for a specific user:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
param( 'user_ID', 'integer', true );
       
$UserCache = & get_UserCache();
       
$step_User = & $UserCache->get_by_ID( $user_ID );

       
// Change execution time to NOW:
       
$r = $DB->query( 'UPDATE T_automation__user_state
              SET aust_next_exec_ts = '
.$DB->quote( date2mysql( $servertimenow ) ).'
            WHERE aust_autm_ID = '
.$edited_Automation->ID.'
              AND aust_user_ID = '
.$step_User->ID.'
              AND aust_next_step_ID IS NOT NULL'
); // exclude finished steps

       
if( $r )
        {    
// Display a result message if user really has been affected:
           
$Messages->add( sprintf( TB_('Execution time has been changed to now for user %s.'), '"'.$step_User->dget( 'login' ).'"' ), 'success' );
           
// We want to highlight the reduced Step on list display:
           
$Session->set( 'fadeout_array', array( 'aust_user_ID' => array( $step_User->ID ) ) );
        }

       
// Redirect so that a reload doesn't write to the DB twice:
       
if( isset( $edited_AutomationStep ) )
        {    
// Redirect to a page of Step edit form:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit_step&step_ID='.$edited_AutomationStep->ID, 303 ); // Will EXIT
       
}
        else
        {    
// Redirect to a page of Automation users:
           
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=users&autm_ID='.$edited_Automation->ID, 303 ); // Will EXIT
       
}
       
// We have EXITed already at this point!!
       
break;

    case
'stop_user':
       
// Stop automation for a specific user:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
param( 'user_ID', 'integer', true );
       
$UserCache = & get_UserCache();
       
$step_User = & $UserCache->get_by_ID( $user_ID );

       
// Change execution time to NOW:
       
$r = $DB->query( 'UPDATE T_automation__user_state
              SET aust_next_step_ID = NULL,
                  aust_next_exec_ts = NULL
            WHERE aust_autm_ID = '
.$edited_Automation->ID.'
              AND aust_user_ID = '
.$step_User->ID );

        if(
$r )
        {    
// Display a result message if user really has been affected:
           
$Messages->add( sprintf( TB_('Automation has been stopped for user %s.'), '"'.$step_User->dget( 'login' ).'"' ), 'success' );
           
// We want to highlight the reduced Step on list display:
           
$Session->set( 'fadeout_array', array( 'aust_user_ID' => array( $step_User->ID ) ) );
        }

       
// Redirect so that a reload doesn't write to the DB twice:
       
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=users&autm_ID='.$edited_Automation->ID, 303 ); // Will EXIT
        // We have EXITed already at this point!!
       
break;

    case
'remove_user':
       
// Remove a specific user from automation:

        // Check that this action request is not a CSRF hacked request:
       
$Session->assert_received_crumb( 'automation' );

       
// Check permission:
       
check_user_perm( 'options', 'edit', true );

       
param( 'user_ID', 'integer', true );
       
$UserCache = & get_UserCache();
       
$step_User = & $UserCache->get_by_ID( $user_ID );

       
// Change execution time to NOW:
       
$r = $DB->query( 'DELETE FROM T_automation__user_state
            WHERE aust_autm_ID = '
.$edited_Automation->ID.'
              AND aust_user_ID = '
.$step_User->ID );

        if(
$r )
        {    
// Display a result message if user really has been affected:
           
$Messages->add( sprintf( TB_('User %s has been removed from this automation.'), '"'.$step_User->dget( 'login' ).'"' ), 'success' );
        }

       
// Redirect so that a reload doesn't write to the DB twice:
       
header_redirect( $admin_url.'?ctrl=automations&action=edit&tab=users&autm_ID='.$edited_Automation->ID, 303 ); // Will EXIT
        // We have EXITed already at this point!!
       
break;
}


$AdminUI->breadcrumbpath_init( false );
$AdminUI->breadcrumbpath_add( TB_('Emails'), $admin_url.'?ctrl=campaigns' );
$AdminUI->breadcrumbpath_add( TB_('Automations'), $admin_url.'?ctrl=automations' );

$AdminUI->display_breadcrumbpath_init();

$AdminUI->set_path( 'email', 'automations' );

// Set an url for manual page:
switch( $action )
{
    case
'new':
    case
'edit':
    case
'delete':
    case
'new_step':
    case
'edit_step':
    case
'copy_step':
       
$AdminUI->display_breadcrumbpath_add( TB_('Automations'), $admin_url.'?ctrl=automations' );
        if(
$action != 'new' )
        {    
// Add menu level 3 entries:
           
if( empty( $edited_Automation ) )
            {    
// Get Automation of the edited Step:
               
$edited_Automation = & $edited_AutomationStep->get_Automation();
               
set_param( 'tab', $display_mode == 'js' ? 'diagram' : 'steps' );
            }
           
$AdminUI->add_menu_entries( array( 'email', 'automations' ), array(
                   
'settings' => array(
                       
'text' => TB_('Settings'),
                       
'href' => $admin_url.'?ctrl=automations&amp;action=edit&amp;tab=settings&amp;autm_ID='.$edited_Automation->ID ),
                   
'steps' => array(
                       
'text' => TB_('Steps'),
                       
'href' => $admin_url.'?ctrl=automations&amp;action=edit&amp;tab=steps&amp;autm_ID='.$edited_Automation->ID ),
                   
'diagram' => array(
                       
'text' => TB_('Diagram view'),
                       
'href' => $admin_url.'?ctrl=automations&amp;action=edit&amp;tab=diagram&amp;autm_ID='.$edited_Automation->ID ),
                   
'users' => array(
                       
'text' => TB_('Users'),
                       
'href' => $admin_url.'?ctrl=automations&amp;action=edit&amp;tab=users&amp;autm_ID='.$edited_Automation->ID ),
                ) );
            if(
in_array( $action, array( 'edit', 'delete' ) ) )
            {
               
$AdminUI->display_breadcrumbpath_add( $edited_Automation->dget( 'name' ) );
            }
        }
        else
        {    
// Don't add level 3 entries for new creating automation, and force tab only for settings:
           
set_param( 'tab', 'settings' );
           
$AdminUI->display_breadcrumbpath_add( TB_('New automation') );
        }

        switch(
$tab )
        {
            case
'steps':
               
$AdminUI->set_page_manual_link( in_array( $action, array( 'new_step', 'edit_step', 'copy_step' ) ) ? 'automation-step-details' : 'automation-steps' );
               
$AdminUI->set_path( 'email', 'automations', 'steps' );
                break;

            case
'users':
               
$AdminUI->set_page_manual_link( 'automation-users-queued' );
               
$AdminUI->set_path( 'email', 'automations', 'users' );
                break;

            case
'diagram':
               
$AdminUI->set_page_manual_link( 'automation-diagram-view' );
               
$AdminUI->set_path( 'email', 'automations', 'diagram' );
               
// Load files to draw diagram by plugin jsPlumb:
               
require_js_defer( 'ext:jquery/jsplumb/js/jsplumb.min.js', 'rsc_url' );
               
require_css( 'ext:jquery/jsplumb/css/jsplumbtoolkit-defaults.css', 'rsc_url' );
               
require_css( 'ext:jquery/jsplumb/css/jsplumbtoolkit-b2evo.css', 'rsc_url' );
               
require_js_defer( 'ext:jquery/panzoom/js/jquery.panzoom.min.js', 'rsc_url' );
                break;

            default:
            case
'settings':
               
$AdminUI->set_page_manual_link( 'automation-form-settings' );
               
$AdminUI->set_path( 'email', 'automations', 'settings' );
               
// Init JS to autcomplete the user logins
               
init_autocomplete_login_js( 'rsc_url', $AdminUI->get_template( 'autocomplete_plugin' ) );
        }

        if(
$action == 'edit' )
        {    
// Initialize Hotkeys
           
init_hotkeys_js();
        }
        break;
    default:
       
$AdminUI->display_breadcrumbpath_add( TB_('Automations') );
       
$AdminUI->set_page_manual_link( 'automations-list' );
        break;
}

if(
in_array( $action, array( 'new_step', 'edit_step', 'copy_step' ) ) )
{    
// Load jQuery QueryBuilder plugin files:
   
$step_Automation = & $edited_AutomationStep->get_Automation();
   
init_querybuilder_js( 'rsc_url' );
   
// Initialize Hotkeys:
   
init_hotkeys_js();
   
$AdminUI->display_breadcrumbpath_add( $edited_Automation->dget( 'name' ), $admin_url.'?ctrl=automations&amp;action=edit&amp;autm_ID='.$step_Automation->ID );
    if(
$action == 'new_step' )
    {
       
$AdminUI->display_breadcrumbpath_add( TB_('New step') );
    }
    elseif(
$action == 'copy_step' )
    {
       
$AdminUI->display_breadcrumbpath_add( TB_('Duplicate step').' #'.get_param( 'step_ID' ) );
    }
    else
    {
       
$AdminUI->display_breadcrumbpath_add( TB_('Step').' #'.$edited_AutomationStep->dget( 'order' ) );
    }
}
if(
$tab == 'diagram' )
{    
// Load jQuery QueryBuilder plugin files for edit step form in modal window:
   
init_querybuilder_js( 'rsc_url' );
}

if(
$display_mode != 'js' )
{
   
// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
   
$AdminUI->disp_html_head();

   
// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
   
$AdminUI->disp_body_top();

   
// Begin payload block:
   
$AdminUI->disp_payload_begin();

   
evo_flush();
}

switch(
$action )
{
    case
'delete':
       
// We need to ask for confirmation:
       
$edited_Automation->confirm_delete(
               
sprintf( TB_('Delete automation "%s"?'), $edited_Automation->dget( 'name' ) ),
               
'automation', $action, get_memorized( 'action' ) );
       
/* no break */
   
case 'new':
    case
'edit':
       
// Display a form of automation:
       
switch( $tab )
        {
            case
'steps':
               
$AdminUI->disp_view( 'automations/views/_automation_steps.view.php' );
                break;

            case
'users':
               
$AdminUI->disp_view( 'automations/views/_automation_users.view.php' );
                break;

            case
'diagram':
               
$AdminUI->disp_view( 'automations/views/_automation_diagram.view.php' );
                break;

            case
'settings':
            default:
               
$AdminUI->disp_view( 'automations/views/_automation.form.php' );
        }
        break;

    case
'requeue_form':
       
// Display a form to requeue automation:
       
$AdminUI->disp_view( 'automations/views/_automation_requeue.form.php' );
       
// Do not append Debuglog & Debug JSlog to response!
       
$debug = false;
       
$debug_jslog = false;
        break;

    case
'new_step':
    case
'edit_step':
    case
'copy_step':
       
// Display a form of automation step:
       
$AdminUI->disp_view( 'automations/views/_automation_step.form.php' );
        break;

    default:
       
// Display a list of automations:
       
$AdminUI->disp_view( 'automations/views/_automations.view.php' );
        break;
}

if(
$display_mode != 'js' )
{
   
// End payload block:
   
$AdminUI->disp_payload_end();

   
// Display body bottom, debug info and close </html>:
   
$AdminUI->disp_global_footer();
}
?>