Completed
Branch CASC/batch-deletion (24fd65)
by
unknown
17:02 queued 09:01
created

PreviewEventDeletion::continue_job()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 5
nop 2
dl 0
loc 37
rs 8.7057
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspressoBatchRequest\JobHandlers;
4
5
use EEM_Event;
6
use EEM_Price;
7
use EEM_Ticket;
8
use EventEspresso\core\exceptions\InvalidClassException;
9
use EventEspresso\core\services\orm\tree_traversal\ModelObjNode;
10
use EventEspressoBatchRequest\Helpers\BatchRequestException;
11
use EventEspressoBatchRequest\Helpers\JobParameters;
12
use EventEspressoBatchRequest\Helpers\JobStepResponse;
13
use EventEspressoBatchRequest\JobHandlerBaseClasses\JobHandler;
14
15
/**
16
 * Class EventDeletion
17
 *
18
 * Given a list of event IDs, identified all the dependent model objects that would need to be deleted in order to not
19
 * leave any orphaned data.
20
 *
21
 * @package     Event Espresso
22
 * @author         Mike Nelson
23
 * @since         $VID:$
24
 *
25
 */
26
class PreviewEventDeletion extends JobHandler
27
{
28
29
30
    /**
31
     *
32
     * @param JobParameters $job_parameters
33
     * @throws BatchRequestException
34
     * @return JobStepResponse
35
     */
36
    public function create_job(JobParameters $job_parameters)
37
    {
38
        // Set the "root" model objects we will want to delete (record their ID and model)
39
        $event_ids = $job_parameters->request_datum('EVT_ID', array());
40
        // Find all the root nodes to delete (this isn't just events, because there's other data, like related tickets,
41
        // prices, message templates, etc, whose model definition doesn't make them dependent on events. But,
42
        // we have no UI to access them independent of events, so they may as well get deleted too.)
43
        $model_objects_to_delete = [];
44 View Code Duplication
        foreach ($event_ids as $event_id) {
0 ignored issues
show
Bug introduced by
The expression $event_ids of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
45
            $event = EEM_Event::instance()->get_one_by_ID($event_id);
46
//            $model_objects_to_delete[] = $event;
47
            // Also, we want to delete their related, non-global, tickets, prices and message templates
48
            $related_non_global_tickets = EEM_Ticket::instance()->get_all_deleted_and_undeleted(
49
                [
50
                    [
51
                        'TKT_is_default' => false,
52
                        'Datetime.EVT_ID' => $event_id
53
                    ]
54
                ]
55
            );
56
            $related_non_global_prices = EEM_Price::instance()->get_all_deleted_and_undeleted(
57
                [
58
                    [
59
                        'PRC_is_default' => false,
60
                        'Ticket.Datetime.EVT_ID' => $event_id
61
                    ]
62
                ]
63
            );
64
            $related_message_templates = $event->get_many_related(
65
                'Message_Template_Group',
66
                [
67
                    [
68
                        'MTP_is_global' => false
69
                    ]
70
                ]
71
            );
72
            $model_objects_to_delete = array_merge(
73
                $model_objects_to_delete,
74
                [$event],
75
                $related_non_global_tickets,
76
                $related_non_global_prices,
77
                $related_message_templates
78
            );
79
        }
80
        $roots = [];
81
        foreach($model_objects_to_delete as $model_object){
82
            $roots[] = new ModelObjNode($model_objects_to_delete);
83
        }
84
        $job_parameters->add_extra_data('roots', $roots);
85
        // Set an estimate of how long this will take (we're discovering as we go, so it seems impossible to give
86
        // an accurate count.)
87
        $estimated_work_per_model_obj = 100;
88
        $job_parameters->set_job_size(count($roots) * $estimated_work_per_model_obj);
89
        return new JobStepResponse(
90
            $job_parameters,
91
            esc_html__('Identified main items for deletion...', 'event_espresso')
92
        );
93
    }
94
95
    /**
96
     * Performs another step of the job
97
     * @param JobParameters $job_parameters
98
     * @param int $batch_size
99
     * @return JobStepResponse
100
     * @throws BatchRequestException
101
     */
102
    public function continue_job(JobParameters $job_parameters, $batch_size = 50)
103
    {
104
        $units_processed = 0;
105
        foreach($job_parameters->extra_datum('roots', array()) as $root_node){
0 ignored issues
show
Bug introduced by
The expression $job_parameters->extra_datum('roots', array()) of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
106
            if($units_processed >= $batch_size){
107
                break;
108
            }
109
            if(! $root_node instanceof ModelObjNode){
110
                throw new InvalidClassException('ModelObjNode');
111
            }
112
            if($root_node->isComplete()){
113
                continue;
114
            }
115
            $units_processed += $root_node->visit($batch_size);
116
        }
117
        $job_parameters->mark_processed($units_processed);
118
        // If the most-recently processed root node is complete, we must be all done!
119
        if($root_node->isComplete()){
0 ignored issues
show
Bug introduced by
The variable $root_node seems to be defined by a foreach iteration on line 105. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
120
            $deletion_job_code = wp_generate_password(8, false);
121
            add_option('EEBatchDeletion' . $deletion_job_code, $job_parameters->extra_datum('roots'));
122
            return new JobStepResponse(
123
                $job_parameters,
124
                esc_html__('Finished identifying items for deletion.', 'event_espresso'),
125
                [
126
                    'deletion_job_code' => $deletion_job_code
127
                ]
128
            );
129
        } else {
130
            return new JobStepResponse(
131
                $job_parameters,
132
                sprintf(
133
                    esc_html__('Identified %d items for deletions.', 'event_espresso'),
134
                    $units_processed
135
                )
136
            );
137
        }
138
    }
139
140
    /**
141
     * Performs any clean-up logic when we know the job is completed
142
     * @param JobParameters $job_parameters
143
     * @return JobStepResponse
144
     * @throws BatchRequestException
145
     */
146
    public function cleanup_job(JobParameters $job_parameters)
147
    {
148
        // Nothing much to do. We can't delete the option with the built tree because we may need it in a moment for the deletion
149
    }
150
}
151
// End of file EventDeletion.php
152
// Location: EventEspressoBatchRequest\JobHandlers/EventDeletion.php
153