Completed
Branch fix/events-archive-config-rese... (0ef832)
by
unknown
12:05 queued 09:36
created
core/libraries/rest_api/RestException.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -15,55 +15,55 @@
 block discarded – undo
15 15
 class RestException extends \EE_Error
16 16
 {
17 17
 
18
-    /**
19
-     * @var array
20
-     */
21
-    protected $wp_error_data = array();
18
+	/**
19
+	 * @var array
20
+	 */
21
+	protected $wp_error_data = array();
22 22
 
23
-    protected $wp_error_code = '';
23
+	protected $wp_error_code = '';
24 24
 
25 25
 
26 26
 
27
-    public function __construct($string_code, $message, $wp_error_data = array(), $previous = null)
28
-    {
29
-        if (
30
-            is_array($wp_error_data)
31
-            && isset($wp_error_data['status'])
32
-        ) {
33
-            $http_status_number = $wp_error_data['status'];
34
-        } else {
35
-            $http_status_number = 500;
36
-        }
37
-        parent::__construct(
38
-            $message,
39
-            $http_status_number,
40
-            $previous
41
-        );
42
-        $this->wp_error_data = $wp_error_data;
43
-        $this->wp_error_code = $string_code;
44
-    }
27
+	public function __construct($string_code, $message, $wp_error_data = array(), $previous = null)
28
+	{
29
+		if (
30
+			is_array($wp_error_data)
31
+			&& isset($wp_error_data['status'])
32
+		) {
33
+			$http_status_number = $wp_error_data['status'];
34
+		} else {
35
+			$http_status_number = 500;
36
+		}
37
+		parent::__construct(
38
+			$message,
39
+			$http_status_number,
40
+			$previous
41
+		);
42
+		$this->wp_error_data = $wp_error_data;
43
+		$this->wp_error_code = $string_code;
44
+	}
45 45
 
46 46
 
47 47
 
48
-    /**
49
-     * Array of data that may have been set during the constructor, intended for WP_Error's data
50
-     *
51
-     * @return array
52
-     */
53
-    public function getData()
54
-    {
55
-        return $this->wp_error_data;
56
-    }
48
+	/**
49
+	 * Array of data that may have been set during the constructor, intended for WP_Error's data
50
+	 *
51
+	 * @return array
52
+	 */
53
+	public function getData()
54
+	{
55
+		return $this->wp_error_data;
56
+	}
57 57
 
58 58
 
59 59
 
60
-    /**
61
-     * Gets the error string
62
-     *
63
-     * @return string
64
-     */
65
-    public function getStringCode()
66
-    {
67
-        return $this->wp_error_code;
68
-    }
60
+	/**
61
+	 * Gets the error string
62
+	 *
63
+	 * @return string
64
+	 */
65
+	public function getStringCode()
66
+	{
67
+		return $this->wp_error_code;
68
+	}
69 69
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Registration.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -96,7 +96,7 @@
 block discarded – undo
96 96
                     $status_pretty = 'NEVER';
97 97
                     break;
98 98
             }
99
-            $checkin_stati[ $datetime_id ] = $status_pretty;
99
+            $checkin_stati[$datetime_id] = $status_pretty;
100 100
         }
101 101
         return $checkin_stati;
102 102
     }
Please login to merge, or discard this patch.
Indentation   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -24,109 +24,109 @@
 block discarded – undo
24 24
  */
25 25
 class Registration extends RegistrationCalculationBase
26 26
 {
27
-    /**
28
-     * @var EEM_Registration
29
-     */
30
-    protected $registration_model;
27
+	/**
28
+	 * @var EEM_Registration
29
+	 */
30
+	protected $registration_model;
31 31
 
32
-    /**
33
-     * Registration constructor.
34
-     * @param EEM_Registration $registration_model
35
-     */
36
-    public function __construct(EEM_Registration $registration_model)
37
-    {
38
-        $this->registration_model = $registration_model;
39
-    }
32
+	/**
33
+	 * Registration constructor.
34
+	 * @param EEM_Registration $registration_model
35
+	 */
36
+	public function __construct(EEM_Registration $registration_model)
37
+	{
38
+		$this->registration_model = $registration_model;
39
+	}
40 40
 
41
-    /**
42
-     * Calculates the checkin status for each datetime this registration has access to
43
-     *
44
-     * @param array            $wpdb_row
45
-     * @param WP_REST_Request $request
46
-     * @param RegistrationControllerBase $controller
47
-     * @return array
48
-     * @throws EE_Error
49
-     * @throws InvalidDataTypeException
50
-     * @throws InvalidInterfaceException
51
-     * @throws InvalidArgumentException
52
-     */
53
-    public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
-    {
55
-        if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
-            $reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
-        } else {
58
-            $reg = null;
59
-        }
60
-        if (
61
-            ! $reg instanceof EE_Registration
62
-        ) {
63
-            throw new EE_Error(
64
-                sprintf(
65
-                    esc_html__(
66
-                    // @codingStandardsIgnoreStart
67
-                        'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
68
-                        // @codingStandardsIgnoreEnd
69
-                        'event_espresso'
70
-                    ),
71
-                    $wpdb_row['Registration.REG_ID'],
72
-                    print_r($wpdb_row, true)
73
-                )
74
-            );
75
-        }
76
-        $datetime_ids = EEM_Datetime::instance()->get_col(
77
-            [
78
-                [
79
-                    'Ticket.TKT_ID' => $reg->ticket_ID(),
80
-                ],
81
-                'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
82
-            ]
83
-        );
84
-        $checkin_stati = array();
85
-        foreach ($datetime_ids as $datetime_id) {
86
-            $status = $reg->check_in_status_for_datetime($datetime_id);
87
-            switch ($status) {
88
-                case EE_Checkin::status_checked_out:
89
-                    $status_pretty = 'OUT';
90
-                    break;
91
-                case EE_Checkin::status_checked_in:
92
-                    $status_pretty = 'IN';
93
-                    break;
94
-                case EE_Checkin::status_checked_never:
95
-                default:
96
-                    $status_pretty = 'NEVER';
97
-                    break;
98
-            }
99
-            $checkin_stati[ $datetime_id ] = $status_pretty;
100
-        }
101
-        return $checkin_stati;
102
-    }
41
+	/**
42
+	 * Calculates the checkin status for each datetime this registration has access to
43
+	 *
44
+	 * @param array            $wpdb_row
45
+	 * @param WP_REST_Request $request
46
+	 * @param RegistrationControllerBase $controller
47
+	 * @return array
48
+	 * @throws EE_Error
49
+	 * @throws InvalidDataTypeException
50
+	 * @throws InvalidInterfaceException
51
+	 * @throws InvalidArgumentException
52
+	 */
53
+	public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
+	{
55
+		if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
+			$reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
+		} else {
58
+			$reg = null;
59
+		}
60
+		if (
61
+			! $reg instanceof EE_Registration
62
+		) {
63
+			throw new EE_Error(
64
+				sprintf(
65
+					esc_html__(
66
+					// @codingStandardsIgnoreStart
67
+						'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
68
+						// @codingStandardsIgnoreEnd
69
+						'event_espresso'
70
+					),
71
+					$wpdb_row['Registration.REG_ID'],
72
+					print_r($wpdb_row, true)
73
+				)
74
+			);
75
+		}
76
+		$datetime_ids = EEM_Datetime::instance()->get_col(
77
+			[
78
+				[
79
+					'Ticket.TKT_ID' => $reg->ticket_ID(),
80
+				],
81
+				'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
82
+			]
83
+		);
84
+		$checkin_stati = array();
85
+		foreach ($datetime_ids as $datetime_id) {
86
+			$status = $reg->check_in_status_for_datetime($datetime_id);
87
+			switch ($status) {
88
+				case EE_Checkin::status_checked_out:
89
+					$status_pretty = 'OUT';
90
+					break;
91
+				case EE_Checkin::status_checked_in:
92
+					$status_pretty = 'IN';
93
+					break;
94
+				case EE_Checkin::status_checked_never:
95
+				default:
96
+					$status_pretty = 'NEVER';
97
+					break;
98
+			}
99
+			$checkin_stati[ $datetime_id ] = $status_pretty;
100
+		}
101
+		return $checkin_stati;
102
+	}
103 103
 
104 104
 
105
-    /**
106
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
107
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
108
-     *
109
-     * @since 4.9.68.p
110
-     * @return array
111
-     */
112
-    public function schemaForCalculations()
113
-    {
114
-        return array(
115
-            'datetime_checkin_stati' => array(
116
-                'description' => esc_html__(
117
-                    'Returns the checkin status for each datetime this registration has access to.',
118
-                    'event_espresso'
119
-                ),
120
-                'type' => 'object',
121
-                'properties' => array(),
122
-                'additionalProperties' => array(
123
-                    'description' => esc_html__(
124
-                        'Keys are date-time ids and values are the check-in status',
125
-                        'event_espresso'
126
-                    ),
127
-                    'type' => 'string'
128
-                ),
129
-            ),
130
-        );
131
-    }
105
+	/**
106
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
107
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
108
+	 *
109
+	 * @since 4.9.68.p
110
+	 * @return array
111
+	 */
112
+	public function schemaForCalculations()
113
+	{
114
+		return array(
115
+			'datetime_checkin_stati' => array(
116
+				'description' => esc_html__(
117
+					'Returns the checkin status for each datetime this registration has access to.',
118
+					'event_espresso'
119
+				),
120
+				'type' => 'object',
121
+				'properties' => array(),
122
+				'additionalProperties' => array(
123
+					'description' => esc_html__(
124
+						'Keys are date-time ids and values are the check-in status',
125
+						'event_espresso'
126
+					),
127
+					'type' => 'string'
128
+				),
129
+			),
130
+		);
131
+	}
132 132
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/CalculatedModelFields.php 2 patches
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
      */
58 58
     public function mapping($refresh = false)
59 59
     {
60
-        if (! $this->mapping || $refresh) {
60
+        if ( ! $this->mapping || $refresh) {
61 61
             $this->mapping = $this->generateNewMapping();
62 62
         }
63 63
         return $this->mapping;
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
         foreach ($models_with_calculated_fields as $model_name) {
82 82
             $calculator = $this->factory->createFromModel($model_name);
83 83
             foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
-                $mapping[ $model_name ][ $field_name ] = get_class($calculator);
84
+                $mapping[$model_name][$field_name] = get_class($calculator);
85 85
             }
86 86
         }
87 87
         return apply_filters(
@@ -108,8 +108,8 @@  discard block
 block discarded – undo
108 108
             foreach ($map_for_model as $calculation_index => $calculations_class) {
109 109
                 $calculator = $this->factory->createFromClassname($calculations_class);
110 110
                 $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
-                if (! empty($schema)) {
112
-                    $schema_map[ $map_model ][ $calculation_index ] = $schema;
111
+                if ( ! empty($schema)) {
112
+                    $schema_map[$map_model][$calculation_index] = $schema;
113 113
                 }
114 114
             }
115 115
         }
@@ -126,8 +126,8 @@  discard block
 block discarded – undo
126 126
     public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127 127
     {
128 128
         $mapping = $this->mapping();
129
-        if (isset($mapping[ $model->get_this_model_name() ])) {
130
-            return array_keys($mapping[ $model->get_this_model_name() ]);
129
+        if (isset($mapping[$model->get_this_model_name()])) {
130
+            return array_keys($mapping[$model->get_this_model_name()]);
131 131
         }
132 132
         return array();
133 133
     }
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     public function getJsonSchemaForModel(EEM_Base $model)
142 142
     {
143
-        if (! $this->mapping_schema) {
143
+        if ( ! $this->mapping_schema) {
144 144
             $this->mapping_schema = $this->generateNewMappingSchema();
145 145
         }
146 146
         return array(
@@ -149,8 +149,8 @@  discard block
 block discarded – undo
149 149
                 'event_espresso'
150 150
             ),
151 151
             'type' => 'object',
152
-            'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
-                ? $this->mapping_schema[ $model->get_this_model_name() ]
152
+            'properties' => isset($this->mapping_schema[$model->get_this_model_name()])
153
+                ? $this->mapping_schema[$model->get_this_model_name()]
154 154
                 : array(),
155 155
             'additionalProperties' => false,
156 156
             'readonly' => true,
@@ -179,10 +179,10 @@  discard block
 block discarded – undo
179 179
     ) {
180 180
         $mapping = $this->mapping();
181 181
         if (
182
-            isset($mapping[ $model->get_this_model_name() ])
183
-            && isset($mapping[ $model->get_this_model_name() ][ $field_name ])
182
+            isset($mapping[$model->get_this_model_name()])
183
+            && isset($mapping[$model->get_this_model_name()][$field_name])
184 184
         ) {
185
-            $classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
185
+            $classname = $mapping[$model->get_this_model_name()][$field_name];
186 186
             $calculator = $this->factory->createFromClassname($classname);
187 187
             $class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188 188
             return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
Please login to merge, or discard this patch.
Indentation   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -22,178 +22,178 @@
 block discarded – undo
22 22
 class CalculatedModelFields
23 23
 {
24 24
 
25
-    /**
26
-     * @var array
27
-     */
28
-    protected $mapping;
29
-
30
-    /**
31
-     * @var array
32
-     */
33
-    protected $mapping_schema;
34
-
35
-    /**
36
-     * @var CalculatedModelFieldsFactory
37
-     */
38
-    private $factory;
39
-
40
-    /**
41
-     * CalculatedModelFields constructor.
42
-     * @param CalculatedModelFieldsFactory $factory
43
-     */
44
-    public function __construct(CalculatedModelFieldsFactory $factory)
45
-    {
46
-        $this->factory = $factory;
47
-    }
48
-    /**
49
-     * @param bool $refresh
50
-     * @return array top-level-keys are model names (eg "Event")
51
-     * next-level are the calculated field names AND method names on classes
52
-     * which perform calculations, values are the fully qualified classnames which do the calculations
53
-     * These callbacks should accept as arguments:
54
-     * the wpdb row results,
55
-     * the WP_Request object,
56
-     * the controller object
57
-     */
58
-    public function mapping($refresh = false)
59
-    {
60
-        if (! $this->mapping || $refresh) {
61
-            $this->mapping = $this->generateNewMapping();
62
-        }
63
-        return $this->mapping;
64
-    }
65
-
66
-
67
-    /**
68
-     * Generates a new mapping between model calculated fields and their callbacks
69
-     *
70
-     * @return array
71
-     */
72
-    protected function generateNewMapping()
73
-    {
74
-        $mapping = array();
75
-        $models_with_calculated_fields = array(
76
-            'Attendee',
77
-            'Datetime',
78
-            'Event',
79
-            'Registration'
80
-        );
81
-        foreach ($models_with_calculated_fields as $model_name) {
82
-            $calculator = $this->factory->createFromModel($model_name);
83
-            foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
-                $mapping[ $model_name ][ $field_name ] = get_class($calculator);
85
-            }
86
-        }
87
-        return apply_filters(
88
-            'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping',
89
-            $mapping
90
-        );
91
-    }
92
-
93
-
94
-    /**
95
-     * Generates the schema for each calculation index in the calculation map.
96
-     *
97
-     * @return array
98
-     * @throws UnexpectedEntityException
99
-     */
100
-    protected function generateNewMappingSchema()
101
-    {
102
-        $schema_map = array();
103
-        foreach ($this->mapping() as $map_model => $map_for_model) {
104
-            /**
105
-             * @var string $calculation_index
106
-             * @var string $calculations_class
107
-             */
108
-            foreach ($map_for_model as $calculation_index => $calculations_class) {
109
-                $calculator = $this->factory->createFromClassname($calculations_class);
110
-                $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
-                if (! empty($schema)) {
112
-                    $schema_map[ $map_model ][ $calculation_index ] = $schema;
113
-                }
114
-            }
115
-        }
116
-        return $schema_map;
117
-    }
118
-
119
-
120
-    /**
121
-     * Gets the known calculated fields for model
122
-     *
123
-     * @param EEM_Base $model
124
-     * @return array allowable values for this field
125
-     */
126
-    public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127
-    {
128
-        $mapping = $this->mapping();
129
-        if (isset($mapping[ $model->get_this_model_name() ])) {
130
-            return array_keys($mapping[ $model->get_this_model_name() ]);
131
-        }
132
-        return array();
133
-    }
134
-
135
-
136
-    /**
137
-     * Returns the JsonSchema for the calculated fields on the given model.
138
-     * @param EEM_Base $model
139
-     * @return array
140
-     */
141
-    public function getJsonSchemaForModel(EEM_Base $model)
142
-    {
143
-        if (! $this->mapping_schema) {
144
-            $this->mapping_schema = $this->generateNewMappingSchema();
145
-        }
146
-        return array(
147
-            'description' => esc_html__(
148
-                'Available calculated fields for this model.  Fields are only present in the response if explicitly requested',
149
-                'event_espresso'
150
-            ),
151
-            'type' => 'object',
152
-            'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
-                ? $this->mapping_schema[ $model->get_this_model_name() ]
154
-                : array(),
155
-            'additionalProperties' => false,
156
-            'readonly' => true,
157
-        );
158
-    }
159
-
160
-
161
-    /**
162
-     * Retrieves the value for this calculation
163
-     *
164
-     * @param EEM_Base $model
165
-     * @param string $field_name
166
-     * @param array $wpdb_row
167
-     * @param $rest_request
168
-     * @param BaseController $controller
169
-     * @return mixed|null
170
-     * @throws RestException
171
-     * @throws UnexpectedEntityException
172
-     */
173
-    public function retrieveCalculatedFieldValue(
174
-        EEM_Base $model,
175
-        $field_name,
176
-        $wpdb_row,
177
-        $rest_request,
178
-        Base $controller
179
-    ) {
180
-        $mapping = $this->mapping();
181
-        if (
182
-            isset($mapping[ $model->get_this_model_name() ])
183
-            && isset($mapping[ $model->get_this_model_name() ][ $field_name ])
184
-        ) {
185
-            $classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
186
-            $calculator = $this->factory->createFromClassname($classname);
187
-            $class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188
-            return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
189
-        }
190
-        throw new RestException(
191
-            'calculated_field_does_not_exist',
192
-            sprintf(
193
-                esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'),
194
-                $field_name,
195
-                $model->get_this_model_name()
196
-            )
197
-        );
198
-    }
25
+	/**
26
+	 * @var array
27
+	 */
28
+	protected $mapping;
29
+
30
+	/**
31
+	 * @var array
32
+	 */
33
+	protected $mapping_schema;
34
+
35
+	/**
36
+	 * @var CalculatedModelFieldsFactory
37
+	 */
38
+	private $factory;
39
+
40
+	/**
41
+	 * CalculatedModelFields constructor.
42
+	 * @param CalculatedModelFieldsFactory $factory
43
+	 */
44
+	public function __construct(CalculatedModelFieldsFactory $factory)
45
+	{
46
+		$this->factory = $factory;
47
+	}
48
+	/**
49
+	 * @param bool $refresh
50
+	 * @return array top-level-keys are model names (eg "Event")
51
+	 * next-level are the calculated field names AND method names on classes
52
+	 * which perform calculations, values are the fully qualified classnames which do the calculations
53
+	 * These callbacks should accept as arguments:
54
+	 * the wpdb row results,
55
+	 * the WP_Request object,
56
+	 * the controller object
57
+	 */
58
+	public function mapping($refresh = false)
59
+	{
60
+		if (! $this->mapping || $refresh) {
61
+			$this->mapping = $this->generateNewMapping();
62
+		}
63
+		return $this->mapping;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Generates a new mapping between model calculated fields and their callbacks
69
+	 *
70
+	 * @return array
71
+	 */
72
+	protected function generateNewMapping()
73
+	{
74
+		$mapping = array();
75
+		$models_with_calculated_fields = array(
76
+			'Attendee',
77
+			'Datetime',
78
+			'Event',
79
+			'Registration'
80
+		);
81
+		foreach ($models_with_calculated_fields as $model_name) {
82
+			$calculator = $this->factory->createFromModel($model_name);
83
+			foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
+				$mapping[ $model_name ][ $field_name ] = get_class($calculator);
85
+			}
86
+		}
87
+		return apply_filters(
88
+			'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping',
89
+			$mapping
90
+		);
91
+	}
92
+
93
+
94
+	/**
95
+	 * Generates the schema for each calculation index in the calculation map.
96
+	 *
97
+	 * @return array
98
+	 * @throws UnexpectedEntityException
99
+	 */
100
+	protected function generateNewMappingSchema()
101
+	{
102
+		$schema_map = array();
103
+		foreach ($this->mapping() as $map_model => $map_for_model) {
104
+			/**
105
+			 * @var string $calculation_index
106
+			 * @var string $calculations_class
107
+			 */
108
+			foreach ($map_for_model as $calculation_index => $calculations_class) {
109
+				$calculator = $this->factory->createFromClassname($calculations_class);
110
+				$schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
+				if (! empty($schema)) {
112
+					$schema_map[ $map_model ][ $calculation_index ] = $schema;
113
+				}
114
+			}
115
+		}
116
+		return $schema_map;
117
+	}
118
+
119
+
120
+	/**
121
+	 * Gets the known calculated fields for model
122
+	 *
123
+	 * @param EEM_Base $model
124
+	 * @return array allowable values for this field
125
+	 */
126
+	public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127
+	{
128
+		$mapping = $this->mapping();
129
+		if (isset($mapping[ $model->get_this_model_name() ])) {
130
+			return array_keys($mapping[ $model->get_this_model_name() ]);
131
+		}
132
+		return array();
133
+	}
134
+
135
+
136
+	/**
137
+	 * Returns the JsonSchema for the calculated fields on the given model.
138
+	 * @param EEM_Base $model
139
+	 * @return array
140
+	 */
141
+	public function getJsonSchemaForModel(EEM_Base $model)
142
+	{
143
+		if (! $this->mapping_schema) {
144
+			$this->mapping_schema = $this->generateNewMappingSchema();
145
+		}
146
+		return array(
147
+			'description' => esc_html__(
148
+				'Available calculated fields for this model.  Fields are only present in the response if explicitly requested',
149
+				'event_espresso'
150
+			),
151
+			'type' => 'object',
152
+			'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
+				? $this->mapping_schema[ $model->get_this_model_name() ]
154
+				: array(),
155
+			'additionalProperties' => false,
156
+			'readonly' => true,
157
+		);
158
+	}
159
+
160
+
161
+	/**
162
+	 * Retrieves the value for this calculation
163
+	 *
164
+	 * @param EEM_Base $model
165
+	 * @param string $field_name
166
+	 * @param array $wpdb_row
167
+	 * @param $rest_request
168
+	 * @param BaseController $controller
169
+	 * @return mixed|null
170
+	 * @throws RestException
171
+	 * @throws UnexpectedEntityException
172
+	 */
173
+	public function retrieveCalculatedFieldValue(
174
+		EEM_Base $model,
175
+		$field_name,
176
+		$wpdb_row,
177
+		$rest_request,
178
+		Base $controller
179
+	) {
180
+		$mapping = $this->mapping();
181
+		if (
182
+			isset($mapping[ $model->get_this_model_name() ])
183
+			&& isset($mapping[ $model->get_this_model_name() ][ $field_name ])
184
+		) {
185
+			$classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
186
+			$calculator = $this->factory->createFromClassname($classname);
187
+			$class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188
+			return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
189
+		}
190
+		throw new RestException(
191
+			'calculated_field_does_not_exist',
192
+			sprintf(
193
+				esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'),
194
+				$field_name,
195
+				$model->get_this_model_name()
196
+			)
197
+		);
198
+	}
199 199
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/ModelVersionInfo.php 2 patches
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -114,10 +114,10 @@  discard block
 block discarded – undo
114 114
         foreach ($this->resource_changes as $version => $model_classnames) {
115 115
             foreach ($model_classnames as $model_classname => $extra_fields) {
116 116
                 foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
117
+                    $this->resource_changes[$model_classname][$fieldname]['name'] = $fieldname;
118 118
                     foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
119
+                        if ( ! isset($this->resource_changes[$model_classname][$fieldname][$attribute])) {
120
+                            $this->resource_changes[$model_classname][$fieldname][$attribute] = $default_value;
121 121
                         }
122 122
                     }
123 123
                 }
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
             $model_changes = array();
140 140
             foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141 141
                 if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
142
+                    $model_changes[$version] = $models_changed_in_version;
143 143
                 }
144 144
             }
145 145
             $this->cached_model_changes_between_requested_version_and_current = $model_changes;
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
             $resource_changes = array();
162 162
             foreach ($this->resourceChanges() as $version => $model_classnames) {
163 163
                 if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
164
+                    $resource_changes[$version] = $model_classnames;
165 165
                 }
166 166
             }
167 167
             $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
             foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213 213
                 foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214 214
                     if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
215
+                        unset($all_models_in_current_version[$model_name]);
216 216
                     }
217 217
                 }
218 218
             }
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
     public function isModelNameInThisVersion($model_name)
238 238
     {
239 239
         $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
240
+        if (isset($model_names[$model_name])) {
241 241
             return true;
242 242
         } else {
243 243
             return false;
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
      */
281 281
     public function fieldsOnModelInThisVersion($model)
282 282
     {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
283
+        if ( ! isset($this->cached_fields_on_models[$model->get_this_model_name()])) {
284 284
             // get all model changes between the requested version and current core version
285 285
             $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286 286
             // fetch all fields currently on this model
@@ -288,12 +288,12 @@  discard block
 block discarded – undo
288 288
             // remove all fields that have been added since
289 289
             foreach ($changes as $version => $changes_in_version) {
290 290
                 if (
291
-                    isset($changes_in_version[ $model->get_this_model_name() ])
292
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
291
+                    isset($changes_in_version[$model->get_this_model_name()])
292
+                    && $changes_in_version[$model->get_this_model_name()] !== ModelVersionInfo::MODEL_ADDED
293 293
                 ) {
294 294
                     $current_fields = array_diff_key(
295 295
                         $current_fields,
296
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
296
+                        array_flip($changes_in_version[$model->get_this_model_name()])
297 297
                     );
298 298
                 }
299 299
             }
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
         $relations = array();
449 449
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450 450
             if ($this->isModelNameInThisVersion($relation_name)) {
451
-                $relations[ $relation_name ] = $relation_obj;
451
+                $relations[$relation_name] = $relation_obj;
452 452
             }
453 453
         }
454 454
         // filter the results, but use the old filter name
Please login to merge, or discard this patch.
Indentation   +437 added lines, -437 removed lines patch added patch discarded remove patch
@@ -21,441 +21,441 @@
 block discarded – undo
21 21
 class ModelVersionInfo
22 22
 {
23 23
 
24
-    /**
25
-     * Constant used in the $_model_changes array to indicate that a model
26
-     * was completely new in this version
27
-     */
28
-    const MODEL_ADDED = 'model_added_in_this_version';
29
-
30
-    /**
31
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
-     * next-level keys are model names (eg "Event") that underwent some change in that version
33
-     * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
-     * or it's an array where the values are model field names,
35
-     * or API resource properties (ie, non-model fields that appear in REST API results)
36
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
-     *
38
-     * @var array
39
-     */
40
-    protected $model_changes = array();
41
-
42
-    /**
43
-     * top-level keys are version numbers,
44
-     * next-level keys are model CLASSNAMES (even parent classnames),
45
-     * and next-level keys are extra resource properties to attach to those models' resources,
46
-     * and next-level key-value pairs, where the keys are:
47
-     * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
-     *
49
-     * @var array
50
-     */
51
-    protected $resource_changes = array();
52
-
53
-    /**
54
-     * @var string indicating what version of the API was requested
55
-     * (eg although core might be at version 4.8.11, they may have sent a request
56
-     * for 4.6)
57
-     */
58
-    protected $requested_version = null;
59
-
60
-    /**
61
-     * Keys are model names, values are their classnames.
62
-     * We cache this so we only need to calculate this once per request
63
-     *
64
-     * @var array
65
-     */
66
-    protected $cached_models_for_requested_version = null;
67
-
68
-    /**
69
-     * @var array
70
-     */
71
-    protected $cached_model_changes_between_requested_version_and_current = null;
72
-
73
-    /**
74
-     * @var array
75
-     */
76
-    protected $cached_resource_changes_between_requested_version_and_current = null;
77
-
78
-    /**
79
-     * 2d array where top-level keys are model names, 2nd-level keys are field names
80
-     * and values are the actual field objects
81
-     *
82
-     * @var array
83
-     */
84
-    protected $cached_fields_on_models = array();
85
-
86
-
87
-    /**
88
-     * Model_Version_Info constructor.
89
-     *
90
-     * @param string $requested_version
91
-     */
92
-    public function __construct($requested_version)
93
-    {
94
-        $this->requested_version = (string) $requested_version;
95
-        $this->model_changes = array(
96
-            '4.8.29' => array(
97
-                // first version where the REST API is in EE core, so no need
98
-                // to specify how its different from the previous
99
-            ),
100
-        );
101
-        // setup data for "extra" fields added onto resources which don't actually exist on models
102
-        $this->resource_changes = apply_filters(
103
-            'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
-            array()
105
-        );
106
-        $defaults = array(
107
-            'raw'              => false,
108
-            'type'             => 'N/A',
109
-            'nullable'         => true,
110
-            'table_alias'      => 'N/A',
111
-            'table_column'     => 'N/A',
112
-            'always_available' => true,
113
-        );
114
-        foreach ($this->resource_changes as $version => $model_classnames) {
115
-            foreach ($model_classnames as $model_classname => $extra_fields) {
116
-                foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
-                    foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
-                        }
122
-                    }
123
-                }
124
-            }
125
-        }
126
-    }
127
-
128
-
129
-    /**
130
-     * Returns a slice of Model_Version_Info::model_changes()'s array
131
-     * indicating exactly what changes happened between the current core version,
132
-     * and the version requested
133
-     *
134
-     * @return array
135
-     */
136
-    public function modelChangesBetweenRequestedVersionAndCurrent()
137
-    {
138
-        if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
-            $model_changes = array();
140
-            foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
143
-                }
144
-            }
145
-            $this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
-        }
147
-        return $this->cached_model_changes_between_requested_version_and_current;
148
-    }
149
-
150
-
151
-    /**
152
-     * Returns a slice of Model_Version_Info::model_changes()'s array
153
-     * indicating exactly what changes happened between the current core version,
154
-     * and the version requested
155
-     *
156
-     * @return array
157
-     */
158
-    public function resourceChangesBetweenRequestedVersionAndCurrent()
159
-    {
160
-        if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
-            $resource_changes = array();
162
-            foreach ($this->resourceChanges() as $version => $model_classnames) {
163
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
165
-                }
166
-            }
167
-            $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
-        }
169
-        return $this->cached_resource_changes_between_requested_version_and_current;
170
-    }
171
-
172
-
173
-    /**
174
-     * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
-     *
176
-     * @return string like '4.6'
177
-     */
178
-    public function requestedVersion()
179
-    {
180
-        return $this->requested_version;
181
-    }
182
-
183
-
184
-    /**
185
-     * Returns an array describing how the models have changed in each version of core
186
-     * that supports the API (starting at 4.6)
187
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
-     * next-level keys are model names (eg "Event") that underwent some change in that version
189
-     * and the value is either NULL (indicating the model is completely NEW in this version),
190
-     * or it's an array where fields are value names.
191
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
-     *
193
-     * @return array
194
-     */
195
-    public function modelChanges()
196
-    {
197
-        return $this->model_changes;
198
-    }
199
-
200
-
201
-    /**
202
-     * Takes into account the requested version, and the current version, and
203
-     * what changed between the two, and tries to return.
204
-     * Analogous to EE_Registry::instance()->non_abstract_db_models
205
-     *
206
-     * @return array keys are model names, values are their classname
207
-     */
208
-    public function modelsForRequestedVersion()
209
-    {
210
-        if ($this->cached_models_for_requested_version === null) {
211
-            $all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
-            foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
-                foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
-                    if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
216
-                    }
217
-                }
218
-            }
219
-            $this->cached_models_for_requested_version = apply_filters(
220
-                'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
-                $all_models_in_current_version,
222
-                $this
223
-            );
224
-        }
225
-        return $this->cached_models_for_requested_version;
226
-    }
227
-
228
-
229
-    /**
230
-     * Determines if this is a valid model name in the requested version.
231
-     * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
-     * version's models into account
233
-     *
234
-     * @param string $model_name eg 'Event'
235
-     * @return boolean
236
-     */
237
-    public function isModelNameInThisVersion($model_name)
238
-    {
239
-        $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
241
-            return true;
242
-        } else {
243
-            return false;
244
-        }
245
-    }
246
-
247
-
248
-    /**
249
-     * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
-     * version's models into account
251
-     *
252
-     * @param string $model_name
253
-     * @return \EEM_Base
254
-     * @throws \EE_Error
255
-     */
256
-    public function loadModel($model_name)
257
-    {
258
-        if ($this->isModelNameInThisVersion($model_name)) {
259
-            return EE_Registry::instance()->load_model($model_name);
260
-        } else {
261
-            throw new \EE_Error(
262
-                sprintf(
263
-                    esc_html__(
264
-                        'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
-                        'event_espresso'
266
-                    ),
267
-                    $model_name,
268
-                    $this->requestedVersion()
269
-                )
270
-            );
271
-        }
272
-    }
273
-
274
-
275
-    /**
276
-     * Gets all the fields that should exist on this model right now
277
-     *
278
-     * @param \EEM_Base $model
279
-     * @return array|\EE_Model_Field_Base[]
280
-     */
281
-    public function fieldsOnModelInThisVersion($model)
282
-    {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
-            // get all model changes between the requested version and current core version
285
-            $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
-            // fetch all fields currently on this model
287
-            $current_fields = $model->field_settings();
288
-            // remove all fields that have been added since
289
-            foreach ($changes as $version => $changes_in_version) {
290
-                if (
291
-                    isset($changes_in_version[ $model->get_this_model_name() ])
292
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
293
-                ) {
294
-                    $current_fields = array_diff_key(
295
-                        $current_fields,
296
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
297
-                    );
298
-                }
299
-            }
300
-            $this->cached_fields_on_models = $current_fields;
301
-        }
302
-        return $this->cached_fields_on_models;
303
-    }
304
-
305
-
306
-    /**
307
-     * Determines if $object is of one of the classes of $classes. Similar to
308
-     * in_array(), except this checks if $object is a subclass of the classnames provided
309
-     * in $classnames
310
-     *
311
-     * @param object $object
312
-     * @param array  $classnames
313
-     * @return boolean
314
-     */
315
-    public function isSubclassOfOne($object, $classnames)
316
-    {
317
-        foreach ($classnames as $classname) {
318
-            if (is_a($object, $classname)) {
319
-                return true;
320
-            }
321
-        }
322
-        return false;
323
-    }
324
-
325
-
326
-    /**
327
-     * Returns the list of model field classes that that the API basically ignores
328
-     *
329
-     * @return array
330
-     */
331
-    public function fieldsIgnored()
332
-    {
333
-        return apply_filters(
334
-            'FHEE__Controller_Model_Read_fields_ignored',
335
-            array()
336
-        );
337
-    }
338
-
339
-
340
-    /**
341
-     * If this field one that should be ignored by the API?
342
-     *
343
-     * @param EE_Model_Field_Base
344
-     * @return boolean
345
-     */
346
-    public function fieldIsIgnored($field_obj)
347
-    {
348
-        return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
349
-    }
350
-
351
-
352
-    /**
353
-     * Returns the list of model field classes that have a "raw" and non-raw formats.
354
-     * Normally the "raw" versions are only accessible to those who can edit them.
355
-     *
356
-     * @return array an array of EE_Model_Field_Base child classnames
357
-     */
358
-    public function fieldsThatHaveRenderedFormat()
359
-    {
360
-        return apply_filters(
361
-            'FHEE__Controller_Model_Read__fields_raw',
362
-            array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
363
-        );
364
-    }
365
-
366
-
367
-    /**
368
-     * If this field one that has a raw format
369
-     *
370
-     * @param EE_Model_Field_Base
371
-     * @return boolean
372
-     */
373
-    public function fieldHasRenderedFormat($field_obj)
374
-    {
375
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
376
-    }
377
-
378
-
379
-    /**
380
-     * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
381
-     * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
382
-     * to view
383
-     *
384
-     * @return array an array of EE_Model_Field_Base child classnames
385
-     */
386
-    public function fieldsThatHavePrettyFormat()
387
-    {
388
-        return apply_filters(
389
-            'FHEE__Controller_Model_Read__fields_pretty',
390
-            array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
391
-        );
392
-    }
393
-
394
-
395
-    /**
396
-     * If this field one that has a pretty equivalent
397
-     *
398
-     * @param EE_Model_Field_Base
399
-     * @return boolean
400
-     */
401
-    public function fieldHasPrettyFormat($field_obj)
402
-    {
403
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
404
-    }
405
-
406
-
407
-    /**
408
-     * Returns an array describing what extra API resource properties have been added through the versions
409
-     *
410
-     * @return array @see $this->_extra_resource_properties_for_models
411
-     */
412
-    public function resourceChanges()
413
-    {
414
-        return $this->resource_changes;
415
-    }
416
-
417
-
418
-    /**
419
-     * Returns an array where keys are extra resource properties in this version of the API,
420
-     * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
421
-     *
422
-     * @param \EEM_Base $model
423
-     * @return array
424
-     */
425
-    public function extraResourcePropertiesForModel($model)
426
-    {
427
-        $extra_properties = array();
428
-        foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
429
-            foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
430
-                if (is_subclass_of($model, $model_classname)) {
431
-                    $extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
432
-                }
433
-            }
434
-        }
435
-        return $extra_properties;
436
-    }
437
-
438
-
439
-    /**
440
-     * Gets all the related models for the specified model. It's good to use this
441
-     * in case this model didn't exist for this version or something
442
-     *
443
-     * @param \EEM_Base $model
444
-     * @return \EE_Model_Relation_Base[]
445
-     */
446
-    public function relationSettings(\EEM_Base $model)
447
-    {
448
-        $relations = array();
449
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450
-            if ($this->isModelNameInThisVersion($relation_name)) {
451
-                $relations[ $relation_name ] = $relation_obj;
452
-            }
453
-        }
454
-        // filter the results, but use the old filter name
455
-        return apply_filters(
456
-            'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
457
-            $relations,
458
-            $model
459
-        );
460
-    }
24
+	/**
25
+	 * Constant used in the $_model_changes array to indicate that a model
26
+	 * was completely new in this version
27
+	 */
28
+	const MODEL_ADDED = 'model_added_in_this_version';
29
+
30
+	/**
31
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
33
+	 * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
+	 * or it's an array where the values are model field names,
35
+	 * or API resource properties (ie, non-model fields that appear in REST API results)
36
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
+	 *
38
+	 * @var array
39
+	 */
40
+	protected $model_changes = array();
41
+
42
+	/**
43
+	 * top-level keys are version numbers,
44
+	 * next-level keys are model CLASSNAMES (even parent classnames),
45
+	 * and next-level keys are extra resource properties to attach to those models' resources,
46
+	 * and next-level key-value pairs, where the keys are:
47
+	 * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $resource_changes = array();
52
+
53
+	/**
54
+	 * @var string indicating what version of the API was requested
55
+	 * (eg although core might be at version 4.8.11, they may have sent a request
56
+	 * for 4.6)
57
+	 */
58
+	protected $requested_version = null;
59
+
60
+	/**
61
+	 * Keys are model names, values are their classnames.
62
+	 * We cache this so we only need to calculate this once per request
63
+	 *
64
+	 * @var array
65
+	 */
66
+	protected $cached_models_for_requested_version = null;
67
+
68
+	/**
69
+	 * @var array
70
+	 */
71
+	protected $cached_model_changes_between_requested_version_and_current = null;
72
+
73
+	/**
74
+	 * @var array
75
+	 */
76
+	protected $cached_resource_changes_between_requested_version_and_current = null;
77
+
78
+	/**
79
+	 * 2d array where top-level keys are model names, 2nd-level keys are field names
80
+	 * and values are the actual field objects
81
+	 *
82
+	 * @var array
83
+	 */
84
+	protected $cached_fields_on_models = array();
85
+
86
+
87
+	/**
88
+	 * Model_Version_Info constructor.
89
+	 *
90
+	 * @param string $requested_version
91
+	 */
92
+	public function __construct($requested_version)
93
+	{
94
+		$this->requested_version = (string) $requested_version;
95
+		$this->model_changes = array(
96
+			'4.8.29' => array(
97
+				// first version where the REST API is in EE core, so no need
98
+				// to specify how its different from the previous
99
+			),
100
+		);
101
+		// setup data for "extra" fields added onto resources which don't actually exist on models
102
+		$this->resource_changes = apply_filters(
103
+			'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
+			array()
105
+		);
106
+		$defaults = array(
107
+			'raw'              => false,
108
+			'type'             => 'N/A',
109
+			'nullable'         => true,
110
+			'table_alias'      => 'N/A',
111
+			'table_column'     => 'N/A',
112
+			'always_available' => true,
113
+		);
114
+		foreach ($this->resource_changes as $version => $model_classnames) {
115
+			foreach ($model_classnames as $model_classname => $extra_fields) {
116
+				foreach ($extra_fields as $fieldname => $field_data) {
117
+					$this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
+					foreach ($defaults as $attribute => $default_value) {
119
+						if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
+							$this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
+						}
122
+					}
123
+				}
124
+			}
125
+		}
126
+	}
127
+
128
+
129
+	/**
130
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
131
+	 * indicating exactly what changes happened between the current core version,
132
+	 * and the version requested
133
+	 *
134
+	 * @return array
135
+	 */
136
+	public function modelChangesBetweenRequestedVersionAndCurrent()
137
+	{
138
+		if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
+			$model_changes = array();
140
+			foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
+					$model_changes[ $version ] = $models_changed_in_version;
143
+				}
144
+			}
145
+			$this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
+		}
147
+		return $this->cached_model_changes_between_requested_version_and_current;
148
+	}
149
+
150
+
151
+	/**
152
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
153
+	 * indicating exactly what changes happened between the current core version,
154
+	 * and the version requested
155
+	 *
156
+	 * @return array
157
+	 */
158
+	public function resourceChangesBetweenRequestedVersionAndCurrent()
159
+	{
160
+		if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
+			$resource_changes = array();
162
+			foreach ($this->resourceChanges() as $version => $model_classnames) {
163
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
+					$resource_changes[ $version ] = $model_classnames;
165
+				}
166
+			}
167
+			$this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
+		}
169
+		return $this->cached_resource_changes_between_requested_version_and_current;
170
+	}
171
+
172
+
173
+	/**
174
+	 * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
+	 *
176
+	 * @return string like '4.6'
177
+	 */
178
+	public function requestedVersion()
179
+	{
180
+		return $this->requested_version;
181
+	}
182
+
183
+
184
+	/**
185
+	 * Returns an array describing how the models have changed in each version of core
186
+	 * that supports the API (starting at 4.6)
187
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
189
+	 * and the value is either NULL (indicating the model is completely NEW in this version),
190
+	 * or it's an array where fields are value names.
191
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
+	 *
193
+	 * @return array
194
+	 */
195
+	public function modelChanges()
196
+	{
197
+		return $this->model_changes;
198
+	}
199
+
200
+
201
+	/**
202
+	 * Takes into account the requested version, and the current version, and
203
+	 * what changed between the two, and tries to return.
204
+	 * Analogous to EE_Registry::instance()->non_abstract_db_models
205
+	 *
206
+	 * @return array keys are model names, values are their classname
207
+	 */
208
+	public function modelsForRequestedVersion()
209
+	{
210
+		if ($this->cached_models_for_requested_version === null) {
211
+			$all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
+			foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
+				foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
+					if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
+						unset($all_models_in_current_version[ $model_name ]);
216
+					}
217
+				}
218
+			}
219
+			$this->cached_models_for_requested_version = apply_filters(
220
+				'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
+				$all_models_in_current_version,
222
+				$this
223
+			);
224
+		}
225
+		return $this->cached_models_for_requested_version;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Determines if this is a valid model name in the requested version.
231
+	 * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
+	 * version's models into account
233
+	 *
234
+	 * @param string $model_name eg 'Event'
235
+	 * @return boolean
236
+	 */
237
+	public function isModelNameInThisVersion($model_name)
238
+	{
239
+		$model_names = $this->modelsForRequestedVersion();
240
+		if (isset($model_names[ $model_name ])) {
241
+			return true;
242
+		} else {
243
+			return false;
244
+		}
245
+	}
246
+
247
+
248
+	/**
249
+	 * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
+	 * version's models into account
251
+	 *
252
+	 * @param string $model_name
253
+	 * @return \EEM_Base
254
+	 * @throws \EE_Error
255
+	 */
256
+	public function loadModel($model_name)
257
+	{
258
+		if ($this->isModelNameInThisVersion($model_name)) {
259
+			return EE_Registry::instance()->load_model($model_name);
260
+		} else {
261
+			throw new \EE_Error(
262
+				sprintf(
263
+					esc_html__(
264
+						'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
+						'event_espresso'
266
+					),
267
+					$model_name,
268
+					$this->requestedVersion()
269
+				)
270
+			);
271
+		}
272
+	}
273
+
274
+
275
+	/**
276
+	 * Gets all the fields that should exist on this model right now
277
+	 *
278
+	 * @param \EEM_Base $model
279
+	 * @return array|\EE_Model_Field_Base[]
280
+	 */
281
+	public function fieldsOnModelInThisVersion($model)
282
+	{
283
+		if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
+			// get all model changes between the requested version and current core version
285
+			$changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
+			// fetch all fields currently on this model
287
+			$current_fields = $model->field_settings();
288
+			// remove all fields that have been added since
289
+			foreach ($changes as $version => $changes_in_version) {
290
+				if (
291
+					isset($changes_in_version[ $model->get_this_model_name() ])
292
+					&& $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
293
+				) {
294
+					$current_fields = array_diff_key(
295
+						$current_fields,
296
+						array_flip($changes_in_version[ $model->get_this_model_name() ])
297
+					);
298
+				}
299
+			}
300
+			$this->cached_fields_on_models = $current_fields;
301
+		}
302
+		return $this->cached_fields_on_models;
303
+	}
304
+
305
+
306
+	/**
307
+	 * Determines if $object is of one of the classes of $classes. Similar to
308
+	 * in_array(), except this checks if $object is a subclass of the classnames provided
309
+	 * in $classnames
310
+	 *
311
+	 * @param object $object
312
+	 * @param array  $classnames
313
+	 * @return boolean
314
+	 */
315
+	public function isSubclassOfOne($object, $classnames)
316
+	{
317
+		foreach ($classnames as $classname) {
318
+			if (is_a($object, $classname)) {
319
+				return true;
320
+			}
321
+		}
322
+		return false;
323
+	}
324
+
325
+
326
+	/**
327
+	 * Returns the list of model field classes that that the API basically ignores
328
+	 *
329
+	 * @return array
330
+	 */
331
+	public function fieldsIgnored()
332
+	{
333
+		return apply_filters(
334
+			'FHEE__Controller_Model_Read_fields_ignored',
335
+			array()
336
+		);
337
+	}
338
+
339
+
340
+	/**
341
+	 * If this field one that should be ignored by the API?
342
+	 *
343
+	 * @param EE_Model_Field_Base
344
+	 * @return boolean
345
+	 */
346
+	public function fieldIsIgnored($field_obj)
347
+	{
348
+		return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
349
+	}
350
+
351
+
352
+	/**
353
+	 * Returns the list of model field classes that have a "raw" and non-raw formats.
354
+	 * Normally the "raw" versions are only accessible to those who can edit them.
355
+	 *
356
+	 * @return array an array of EE_Model_Field_Base child classnames
357
+	 */
358
+	public function fieldsThatHaveRenderedFormat()
359
+	{
360
+		return apply_filters(
361
+			'FHEE__Controller_Model_Read__fields_raw',
362
+			array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
363
+		);
364
+	}
365
+
366
+
367
+	/**
368
+	 * If this field one that has a raw format
369
+	 *
370
+	 * @param EE_Model_Field_Base
371
+	 * @return boolean
372
+	 */
373
+	public function fieldHasRenderedFormat($field_obj)
374
+	{
375
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
376
+	}
377
+
378
+
379
+	/**
380
+	 * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
381
+	 * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
382
+	 * to view
383
+	 *
384
+	 * @return array an array of EE_Model_Field_Base child classnames
385
+	 */
386
+	public function fieldsThatHavePrettyFormat()
387
+	{
388
+		return apply_filters(
389
+			'FHEE__Controller_Model_Read__fields_pretty',
390
+			array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
391
+		);
392
+	}
393
+
394
+
395
+	/**
396
+	 * If this field one that has a pretty equivalent
397
+	 *
398
+	 * @param EE_Model_Field_Base
399
+	 * @return boolean
400
+	 */
401
+	public function fieldHasPrettyFormat($field_obj)
402
+	{
403
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
404
+	}
405
+
406
+
407
+	/**
408
+	 * Returns an array describing what extra API resource properties have been added through the versions
409
+	 *
410
+	 * @return array @see $this->_extra_resource_properties_for_models
411
+	 */
412
+	public function resourceChanges()
413
+	{
414
+		return $this->resource_changes;
415
+	}
416
+
417
+
418
+	/**
419
+	 * Returns an array where keys are extra resource properties in this version of the API,
420
+	 * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
421
+	 *
422
+	 * @param \EEM_Base $model
423
+	 * @return array
424
+	 */
425
+	public function extraResourcePropertiesForModel($model)
426
+	{
427
+		$extra_properties = array();
428
+		foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
429
+			foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
430
+				if (is_subclass_of($model, $model_classname)) {
431
+					$extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
432
+				}
433
+			}
434
+		}
435
+		return $extra_properties;
436
+	}
437
+
438
+
439
+	/**
440
+	 * Gets all the related models for the specified model. It's good to use this
441
+	 * in case this model didn't exist for this version or something
442
+	 *
443
+	 * @param \EEM_Base $model
444
+	 * @return \EE_Model_Relation_Base[]
445
+	 */
446
+	public function relationSettings(\EEM_Base $model)
447
+	{
448
+		$relations = array();
449
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450
+			if ($this->isModelNameInThisVersion($relation_name)) {
451
+				$relations[ $relation_name ] = $relation_obj;
452
+			}
453
+		}
454
+		// filter the results, but use the old filter name
455
+		return apply_filters(
456
+			'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
457
+			$relations,
458
+			$model
459
+		);
460
+	}
461 461
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Base.lib.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -196,11 +196,11 @@  discard block
 block discarded – undo
196 196
             ! empty($messenger)
197 197
             && $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198 198
         ) {
199
-            $settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
199
+            $settings_to_use = $active_messengers[$messenger]['settings'][$messenger.'-message_types'];
200 200
         }
201 201
 
202
-        $this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
-            ? $settings_to_use[ $this->name ]['settings']
202
+        $this->_existing_admin_settings = isset($settings_to_use[$this->name]['settings'])
203
+            ? $settings_to_use[$this->name]['settings']
204 204
             : null;
205 205
     }
206 206
 
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
     public function get_valid_shortcodes()
241 241
     {
242 242
         $valid_shortcodes = apply_filters(
243
-            'FHEE__' . get_class($this) . '__get_valid_shortcodes',
243
+            'FHEE__'.get_class($this).'__get_valid_shortcodes',
244 244
             $this->_valid_shortcodes,
245 245
             $this
246 246
         );
@@ -283,19 +283,19 @@  discard block
 block discarded – undo
283 283
     protected function _get_admin_page_content($page, $action, $extra, $actives)
284 284
     {
285 285
         // we can also further refine the context by action (if present).
286
-        if (!empty($action)) {
287
-            $page = $page . '_' . $action;
286
+        if ( ! empty($action)) {
287
+            $page = $page.'_'.$action;
288 288
         }
289 289
 
290
-        if (!isset($this->admin_registered_pages[ $page ])) {
290
+        if ( ! isset($this->admin_registered_pages[$page])) {
291 291
             // todo: a place to throw an exception?
292 292
             // We need to indicate there is no registered page so this function is not being called correctly.
293 293
             return false;
294 294
         }
295 295
         // k made it here so let's call the method
296 296
         $content = call_user_func_array(
297
-            array( $this, '_get_admin_content_' . $page ),
298
-            array( $actives, $extra )
297
+            array($this, '_get_admin_content_'.$page),
298
+            array($actives, $extra)
299 299
         );
300 300
         if ($content === false) {
301 301
             // todo this needs to be an exception once we've got exceptions in place.
Please login to merge, or discard this patch.
Indentation   +265 added lines, -265 removed lines patch added patch discarded remove patch
@@ -14,44 +14,44 @@  discard block
 block discarded – undo
14 14
 abstract class EE_Messages_Base extends EE_Base
15 15
 {
16 16
 
17
-    /** DETAILS PROPERTIES **/
18
-    /**
19
-     * The following are used to hold details on the type for reference (i.e. on admin screens)
20
-     * and also used by the EE_message_type object to figure out where to get template data.
21
-     */
22
-    public $name;
23
-    public $description;
24
-    protected $_messages_item_type; // messenger OR message_type?
25
-
26
-
27
-    /**
28
-     * This is an array describing the ui facing labels
29
-     * that will be used whenever the messenger is referenced in the ui
30
-     *
31
-     * array(
32
-     *  'singular' => esc_html__('something'),
33
-     *  'plural' => esc_html__('somethings')
34
-     * )
35
-     *
36
-     * @var array
37
-     */
38
-    public $label;
39
-
40
-
41
-
42
-
43
-    /**
44
-     * This property when set will hold the slugs of all EE admin pages that we will need to retrieve fields for
45
-     * (and used to determine which callback method to call from the child class)
46
-     *
47
-     * structure should be
48
-     * array(
49
-     * 'page_action' => true
50
-     * )
51
-     *
17
+	/** DETAILS PROPERTIES **/
18
+	/**
19
+	 * The following are used to hold details on the type for reference (i.e. on admin screens)
20
+	 * and also used by the EE_message_type object to figure out where to get template data.
21
+	 */
22
+	public $name;
23
+	public $description;
24
+	protected $_messages_item_type; // messenger OR message_type?
25
+
26
+
27
+	/**
28
+	 * This is an array describing the ui facing labels
29
+	 * that will be used whenever the messenger is referenced in the ui
30
+	 *
31
+	 * array(
32
+	 *  'singular' => esc_html__('something'),
33
+	 *  'plural' => esc_html__('somethings')
34
+	 * )
35
+	 *
36
+	 * @var array
37
+	 */
38
+	public $label;
39
+
40
+
41
+
42
+
43
+	/**
44
+	 * This property when set will hold the slugs of all EE admin pages that we will need to retrieve fields for
45
+	 * (and used to determine which callback method to call from the child class)
46
+	 *
47
+	 * structure should be
48
+	 * array(
49
+	 * 'page_action' => true
50
+	 * )
51
+	 *
52 52
 *@var array
53
-     */
54
-    public $admin_registered_pages = array();
53
+	 */
54
+	public $admin_registered_pages = array();
55 55
 
56 56
 
57 57
 
@@ -60,265 +60,265 @@  discard block
 block discarded – undo
60 60
 
61 61
 
62 62
 
63
-    /**
64
-     * this property holds any specific fields for holding any settings related to a messenger (if any needed)
65
-     * @var array
66
-     */
67
-    protected $_admin_settings_fields = array();
63
+	/**
64
+	 * this property holds any specific fields for holding any settings related to a messenger (if any needed)
65
+	 * @var array
66
+	 */
67
+	protected $_admin_settings_fields = array();
68 68
 
69 69
 
70 70
 
71 71
 
72 72
 
73
-    /**
74
-     * this property will hold any existing settings that may have been set in the admin.
75
-     * @var array
76
-     */
77
-    protected $_existing_admin_settings = array();
73
+	/**
74
+	 * this property will hold any existing settings that may have been set in the admin.
75
+	 * @var array
76
+	 */
77
+	protected $_existing_admin_settings = array();
78 78
 
79 79
 
80 80
 
81 81
 
82 82
 
83
-    /**
84
-     * this property will hold an array of valid shortcodes for this message type and messengers.
85
-     * #For Message Types:
86
-     * This is an array of strings that correspond to defined EE_Shortcode libraries and per context.
87
-     * For example:
88
-     * array( 'admin' => array('transaction', 'event', 'attendee') )
89
-     * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
90
-     * for the admin context;
91
-     *
92
-     *
93
-     * #For Messengers:
94
-     * For example:
95
-     * array('subject' => array('transaction', 'event', 'attendee'))
96
-     * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
97
-     * for the 'subject' field;
98
-     * NOTE:  by default, with messengers, if the valid shortcodes for a field is left blank,
99
-     * that field will inherit whatever are set as valid shortcodes by message_type.
100
-     * This is so messenger can set specific valid codes for fields and leave other
101
-     * valid shortcodes up to the message type matched with the messenger.
102
-     *
103
-     * @access protected
104
-     * @var array
105
-     */
106
-    protected $_valid_shortcodes = array();
83
+	/**
84
+	 * this property will hold an array of valid shortcodes for this message type and messengers.
85
+	 * #For Message Types:
86
+	 * This is an array of strings that correspond to defined EE_Shortcode libraries and per context.
87
+	 * For example:
88
+	 * array( 'admin' => array('transaction', 'event', 'attendee') )
89
+	 * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
90
+	 * for the admin context;
91
+	 *
92
+	 *
93
+	 * #For Messengers:
94
+	 * For example:
95
+	 * array('subject' => array('transaction', 'event', 'attendee'))
96
+	 * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
97
+	 * for the 'subject' field;
98
+	 * NOTE:  by default, with messengers, if the valid shortcodes for a field is left blank,
99
+	 * that field will inherit whatever are set as valid shortcodes by message_type.
100
+	 * This is so messenger can set specific valid codes for fields and leave other
101
+	 * valid shortcodes up to the message type matched with the messenger.
102
+	 *
103
+	 * @access protected
104
+	 * @var array
105
+	 */
106
+	protected $_valid_shortcodes = array();
107 107
 
108 108
 
109 109
 
110 110
 
111 111
 
112
-    public function __construct()
113
-    {
114
-        $this->_set_admin_settings_fields();
115
-        $this->_set_valid_shortcodes();
116
-        $this->_set_admin_pages();
117
-    }
112
+	public function __construct()
113
+	{
114
+		$this->_set_admin_settings_fields();
115
+		$this->_set_valid_shortcodes();
116
+		$this->_set_admin_pages();
117
+	}
118 118
 
119 119
 
120 120
 
121 121
 
122 122
 
123
-    /**
124
-     * sets the _admin_settings_fields property which needs to be defined by child classes.
125
-     * You will want to set the _admin_settings_fields properties as a multi-dimensional array with the following format
126
-     * array(
127
-     *      {field_name - also used for setting index} => array(
128
-     *          'field_type' => {type of field: 'text', 'textarea', 'checkbox'},
129
-     *          'value_type' => {type of value: 'string', 'int', 'array', 'bool'},
130
-     *          'required' => {bool, required or not},
131
-     *          'validation' => {bool, true if we want validation, false if not},
132
-     *          'format' => {%d, or %s},
133
-     *          'label' => {label for the field, make sure it's localized},
134
-     *          'default' => {default value for the setting}
135
-     *      ),
136
-     * );
137
-     *
138
-     * @abstract
139
-     * @access protected
140
-     * @return void
141
-     */
142
-    abstract protected function _set_admin_settings_fields();
123
+	/**
124
+	 * sets the _admin_settings_fields property which needs to be defined by child classes.
125
+	 * You will want to set the _admin_settings_fields properties as a multi-dimensional array with the following format
126
+	 * array(
127
+	 *      {field_name - also used for setting index} => array(
128
+	 *          'field_type' => {type of field: 'text', 'textarea', 'checkbox'},
129
+	 *          'value_type' => {type of value: 'string', 'int', 'array', 'bool'},
130
+	 *          'required' => {bool, required or not},
131
+	 *          'validation' => {bool, true if we want validation, false if not},
132
+	 *          'format' => {%d, or %s},
133
+	 *          'label' => {label for the field, make sure it's localized},
134
+	 *          'default' => {default value for the setting}
135
+	 *      ),
136
+	 * );
137
+	 *
138
+	 * @abstract
139
+	 * @access protected
140
+	 * @return void
141
+	 */
142
+	abstract protected function _set_admin_settings_fields();
143 143
 
144 144
 
145 145
 
146 146
 
147 147
 
148
-    /**
149
-     * sets any properties on whether a message type or messenger interface shows up on a ee administration page.
150
-     * Child classes have to define this method but don't necessarily have to set the flags
151
-     * as they will be set to false by default.
152
-     *
153
-     * Child classes use this method to set the `_admin_registered_page` property.
154
-     * That property is to indicate what EE admin pages we have a corresponding callback for in the child class
155
-     * so Message Type/messenger fields/content is included on that admin page.
156
-     *
157
-     * @abstract
158
-     * @access protected
159
-     * @return void
160
-     */
161
-    abstract protected function _set_admin_pages();
148
+	/**
149
+	 * sets any properties on whether a message type or messenger interface shows up on a ee administration page.
150
+	 * Child classes have to define this method but don't necessarily have to set the flags
151
+	 * as they will be set to false by default.
152
+	 *
153
+	 * Child classes use this method to set the `_admin_registered_page` property.
154
+	 * That property is to indicate what EE admin pages we have a corresponding callback for in the child class
155
+	 * so Message Type/messenger fields/content is included on that admin page.
156
+	 *
157
+	 * @abstract
158
+	 * @access protected
159
+	 * @return void
160
+	 */
161
+	abstract protected function _set_admin_pages();
162 162
 
163 163
 
164 164
 
165 165
 
166 166
 
167
-    /**
168
-     * Child classes must declare the $_valid_shortcodes property using this method.
169
-     * See comments for $_valid_shortcodes property for details on what it is used for.
170
-     *
171
-     * @access protected
172
-     * @return void
173
-     */
174
-    abstract protected function _set_valid_shortcodes();
167
+	/**
168
+	 * Child classes must declare the $_valid_shortcodes property using this method.
169
+	 * See comments for $_valid_shortcodes property for details on what it is used for.
170
+	 *
171
+	 * @access protected
172
+	 * @return void
173
+	 */
174
+	abstract protected function _set_valid_shortcodes();
175 175
 
176 176
 
177 177
 
178
-    /**
179
-     * sets the _existing_admin_settings property can be overridden by child classes.
180
-     * We do this so we only do database calls if needed.
181
-     *
182
-     * @access protected
183
-     * @param string $messenger
184
-     */
185
-    protected function _set_existing_admin_settings($messenger = '')
186
-    {
187
-        /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
188
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
189
-        $active_messengers = $Message_Resource_Manager->get_active_messengers_option();
190
-        $settings_to_use = $active_messengers;
191
-
192
-        /**
193
-         * This determines what will be used for the getting the settings.
194
-         */
195
-        if (
196
-            ! empty($messenger)
197
-            && $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198
-        ) {
199
-            $settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
200
-        }
201
-
202
-        $this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
-            ? $settings_to_use[ $this->name ]['settings']
204
-            : null;
205
-    }
206
-
207
-
208
-
209
-
210
-
211
-
212
-    /**
213
-     * get_existing_admin_settings
214
-     * (if needed) sets and returns the _existing_admin_settings property.
215
-     *
216
-     * @access public
217
-     * @param string $messenger
218
-     * @return array          settings
219
-     */
220
-    public function get_existing_admin_settings($messenger = '')
221
-    {
222
-        // if admin_settings property empty lets try setting it.
223
-        if (method_exists($this, '_set_existing_admin_settings') && empty($this->_existing_admin_settings)) {
224
-            $this->_set_existing_admin_settings($messenger);
225
-        }
226
-        return property_exists($this, '_existing_admin_settings')
227
-            ? $this->_existing_admin_settings
228
-            : null;
229
-    }
230
-
231
-
232
-
233
-
234
-
235
-
236
-    /**
237
-     * This returns the array of valid shortcodes for a message type or messenger as set by the child in the $_valid_shortcode property.
238
-     * @return array   an array of valid shortcodes.
239
-     */
240
-    public function get_valid_shortcodes()
241
-    {
242
-        $valid_shortcodes = apply_filters(
243
-            'FHEE__' . get_class($this) . '__get_valid_shortcodes',
244
-            $this->_valid_shortcodes,
245
-            $this
246
-        );
247
-        // The below filter applies to ALL messengers and message types so use with care!
248
-        $valid_shortcodes = apply_filters('FHEE__EE_Messages_Base__get_valid_shortcodes', $valid_shortcodes, $this);
249
-        return $valid_shortcodes;
250
-    }
251
-
252
-
253
-
254
-
255
-    /**
256
-     * getter that returns the protected admin_settings_fields property
257
-     *
258
-     * @access public
259
-     * @return array admin settings fields
260
-     */
261
-    public function get_admin_settings_fields()
262
-    {
263
-        return $this->_admin_settings_fields;
264
-    }
265
-
266
-
267
-
268
-
269
-
270
-    /**
271
-     * this public method accepts a page slug (for an EE_admin page)
272
-     * and will return the response from the child class callback function
273
-     * if that page is registered via the `_admin_registered_page` property set by the child class.
274
-     *
275
-     * @param string $page the slug of the EE admin page
276
-     * @param array $actives an array of active message type (or messenger) objects.
277
-     * @param string $action the page action (to allow for more specific handling - i.e. edit vs. add pages)
278
-     * @param array $extra This is just an extra argument that can be used
279
-     *                     to pass additional data for setting up page content.
280
-     * @access protected
281
-     * @return string $content for page.
282
-     */
283
-    protected function _get_admin_page_content($page, $action, $extra, $actives)
284
-    {
285
-        // we can also further refine the context by action (if present).
286
-        if (!empty($action)) {
287
-            $page = $page . '_' . $action;
288
-        }
289
-
290
-        if (!isset($this->admin_registered_pages[ $page ])) {
291
-            // todo: a place to throw an exception?
292
-            // We need to indicate there is no registered page so this function is not being called correctly.
293
-            return false;
294
-        }
295
-        // k made it here so let's call the method
296
-        $content = call_user_func_array(
297
-            array( $this, '_get_admin_content_' . $page ),
298
-            array( $actives, $extra )
299
-        );
300
-        if ($content === false) {
301
-            // todo this needs to be an exception once we've got exceptions in place.
302
-            return false;
303
-        }
304
-        return $content;
305
-    }
306
-
307
-
308
-    /**
309
-     * Allows a message type to specifically exclude template fields for the provided messenger.
310
-     * Filtered so this can be programmatically altered as well.
311
-     * @param string $messenger_name name of messenger
312
-     * @return array
313
-     */
314
-    public function excludedFieldsForMessenger($messenger_name)
315
-    {
316
-        return apply_filters(
317
-            'FHEE__EE_Messages_Base__excludedFieldForMessenger',
318
-            array(),
319
-            $messenger_name,
320
-            $this->name,
321
-            $this
322
-        );
323
-    }
178
+	/**
179
+	 * sets the _existing_admin_settings property can be overridden by child classes.
180
+	 * We do this so we only do database calls if needed.
181
+	 *
182
+	 * @access protected
183
+	 * @param string $messenger
184
+	 */
185
+	protected function _set_existing_admin_settings($messenger = '')
186
+	{
187
+		/** @var EE_Message_Resource_Manager $Message_Resource_Manager */
188
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
189
+		$active_messengers = $Message_Resource_Manager->get_active_messengers_option();
190
+		$settings_to_use = $active_messengers;
191
+
192
+		/**
193
+		 * This determines what will be used for the getting the settings.
194
+		 */
195
+		if (
196
+			! empty($messenger)
197
+			&& $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198
+		) {
199
+			$settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
200
+		}
201
+
202
+		$this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
+			? $settings_to_use[ $this->name ]['settings']
204
+			: null;
205
+	}
206
+
207
+
208
+
209
+
210
+
211
+
212
+	/**
213
+	 * get_existing_admin_settings
214
+	 * (if needed) sets and returns the _existing_admin_settings property.
215
+	 *
216
+	 * @access public
217
+	 * @param string $messenger
218
+	 * @return array          settings
219
+	 */
220
+	public function get_existing_admin_settings($messenger = '')
221
+	{
222
+		// if admin_settings property empty lets try setting it.
223
+		if (method_exists($this, '_set_existing_admin_settings') && empty($this->_existing_admin_settings)) {
224
+			$this->_set_existing_admin_settings($messenger);
225
+		}
226
+		return property_exists($this, '_existing_admin_settings')
227
+			? $this->_existing_admin_settings
228
+			: null;
229
+	}
230
+
231
+
232
+
233
+
234
+
235
+
236
+	/**
237
+	 * This returns the array of valid shortcodes for a message type or messenger as set by the child in the $_valid_shortcode property.
238
+	 * @return array   an array of valid shortcodes.
239
+	 */
240
+	public function get_valid_shortcodes()
241
+	{
242
+		$valid_shortcodes = apply_filters(
243
+			'FHEE__' . get_class($this) . '__get_valid_shortcodes',
244
+			$this->_valid_shortcodes,
245
+			$this
246
+		);
247
+		// The below filter applies to ALL messengers and message types so use with care!
248
+		$valid_shortcodes = apply_filters('FHEE__EE_Messages_Base__get_valid_shortcodes', $valid_shortcodes, $this);
249
+		return $valid_shortcodes;
250
+	}
251
+
252
+
253
+
254
+
255
+	/**
256
+	 * getter that returns the protected admin_settings_fields property
257
+	 *
258
+	 * @access public
259
+	 * @return array admin settings fields
260
+	 */
261
+	public function get_admin_settings_fields()
262
+	{
263
+		return $this->_admin_settings_fields;
264
+	}
265
+
266
+
267
+
268
+
269
+
270
+	/**
271
+	 * this public method accepts a page slug (for an EE_admin page)
272
+	 * and will return the response from the child class callback function
273
+	 * if that page is registered via the `_admin_registered_page` property set by the child class.
274
+	 *
275
+	 * @param string $page the slug of the EE admin page
276
+	 * @param array $actives an array of active message type (or messenger) objects.
277
+	 * @param string $action the page action (to allow for more specific handling - i.e. edit vs. add pages)
278
+	 * @param array $extra This is just an extra argument that can be used
279
+	 *                     to pass additional data for setting up page content.
280
+	 * @access protected
281
+	 * @return string $content for page.
282
+	 */
283
+	protected function _get_admin_page_content($page, $action, $extra, $actives)
284
+	{
285
+		// we can also further refine the context by action (if present).
286
+		if (!empty($action)) {
287
+			$page = $page . '_' . $action;
288
+		}
289
+
290
+		if (!isset($this->admin_registered_pages[ $page ])) {
291
+			// todo: a place to throw an exception?
292
+			// We need to indicate there is no registered page so this function is not being called correctly.
293
+			return false;
294
+		}
295
+		// k made it here so let's call the method
296
+		$content = call_user_func_array(
297
+			array( $this, '_get_admin_content_' . $page ),
298
+			array( $actives, $extra )
299
+		);
300
+		if ($content === false) {
301
+			// todo this needs to be an exception once we've got exceptions in place.
302
+			return false;
303
+		}
304
+		return $content;
305
+	}
306
+
307
+
308
+	/**
309
+	 * Allows a message type to specifically exclude template fields for the provided messenger.
310
+	 * Filtered so this can be programmatically altered as well.
311
+	 * @param string $messenger_name name of messenger
312
+	 * @return array
313
+	 */
314
+	public function excludedFieldsForMessenger($messenger_name)
315
+	{
316
+		return apply_filters(
317
+			'FHEE__EE_Messages_Base__excludedFieldForMessenger',
318
+			array(),
319
+			$messenger_name,
320
+			$this->name,
321
+			$this
322
+		);
323
+	}
324 324
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Scheduler.lib.php 2 patches
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
     public function __construct()
27 27
     {
28 28
         // register tasks (and make sure only registered once).
29
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
29
+        if ( ! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
30 30
             add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
31 31
         }
32 32
 
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
         EE_Registry::instance()->load_helper('DTT_Helper');
78 78
         $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
79 79
         $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
80
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
80
+        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array(EEH_DTT_Helper::tomorrow(), 'daily');
81 81
         return $tasks;
82 82
     }
83 83
 
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
                 true
97 97
             )
98 98
         ) {
99
-            $request_url  = add_query_arg(
99
+            $request_url = add_query_arg(
100 100
                 array_merge(
101 101
                     array('ee' => 'msg_cron_trigger'),
102 102
                     EE_Messages_Scheduler::get_request_params($task)
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
                 'sslverify'   => false,
110 110
                 'redirection' => 10,
111 111
             );
112
-            $response     = wp_remote_get($request_url, $request_args);
112
+            $response = wp_remote_get($request_url, $request_args);
113 113
             if (is_wp_error($response)) {
114 114
                 trigger_error($response->get_error_message());
115 115
             }
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
     public static function get_request_params($task)
130 130
     {
131 131
         // transient is used for flood control on msg_cron_trigger requests
132
-        $transient_key = 'ee_trans_' . uniqid($task);
132
+        $transient_key = 'ee_trans_'.uniqid($task);
133 133
         set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
134 134
         return array(
135 135
             'type' => $task,
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
             'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
203 203
         );
204 204
         foreach ($message_crons_to_check as $hook_name => $frequency) {
205
-            if (! wp_next_scheduled($hook_name)) {
205
+            if ( ! wp_next_scheduled($hook_name)) {
206 206
                 wp_schedule_event(time(), $frequency, $hook_name);
207 207
             }
208 208
         }
Please login to merge, or discard this patch.
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -14,225 +14,225 @@
 block discarded – undo
14 14
 class EE_Messages_Scheduler extends EE_Base
15 15
 {
16 16
 
17
-    /**
18
-     * Number of seconds between batch sends/generates on the cron job.
19
-     * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
20
-     * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
21
-     *
22
-     * @type int
23
-     */
24
-    const message_cron_schedule = 300;
25
-
26
-    /**
27
-     * Constructor
28
-     */
29
-    public function __construct()
30
-    {
31
-        // register tasks (and make sure only registered once).
32
-        if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
33
-            add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
34
-        }
35
-
36
-        // register callbacks for scheduled events (but make sure they are set only once).
37
-        if (
38
-            ! has_action(
39
-                'AHEE__EE_Messages_Scheduler__generation',
40
-                array('EE_Messages_Scheduler', 'batch_generation')
41
-            )
42
-        ) {
43
-            add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
44
-            add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
45
-            add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
46
-        }
47
-
48
-        // add custom schedules
49
-        add_filter('cron_schedules', array($this, 'custom_schedules'));
50
-    }
51
-
52
-
53
-    /**
54
-     * Add custom schedules for wp_cron
55
-     *
56
-     * @param $schedules
57
-     */
58
-    public function custom_schedules($schedules)
59
-    {
60
-        $schedules['ee_message_cron'] = array(
61
-            'interval' => self::message_cron_schedule,
62
-            'display'  => esc_html__(
63
-                'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
64
-                'event_espresso'
65
-            ),
66
-        );
67
-        return $schedules;
68
-    }
69
-
70
-
71
-    /**
72
-     * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
73
-     * remove.
74
-     *
75
-     * @param array $tasks already existing scheduled tasks
76
-     * @return array
77
-     * @throws EE_Error
78
-     * @throws ReflectionException
79
-     */
80
-    public function register_scheduled_tasks($tasks)
81
-    {
82
-        EE_Registry::instance()->load_helper('DTT_Helper');
83
-        $tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
84
-        $tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
85
-        $tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
86
-        return $tasks;
87
-    }
88
-
89
-
90
-    /**
91
-     * This initiates a non-blocking separate request to execute on a scheduled task.
92
-     * Note: The EED_Messages module has the handlers for these requests.
93
-     *
94
-     * @param string $task The task the request is being generated for.
95
-     */
96
-    public static function initiate_scheduled_non_blocking_request($task)
97
-    {
98
-        if (
99
-            apply_filters(
100
-                'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
101
-                true
102
-            )
103
-        ) {
104
-            $request_url  = add_query_arg(
105
-                array_merge(
106
-                    array('ee' => 'msg_cron_trigger'),
107
-                    EE_Messages_Scheduler::get_request_params($task)
108
-                ),
109
-                site_url()
110
-            );
111
-            $request_args = array(
112
-                'timeout'     => 300,
113
-                'blocking'    => (defined('DOING_CRON') && DOING_CRON)
114
-                                 || (defined('DOING_AJAX') && DOING_AJAX),
115
-                'sslverify'   => false,
116
-                'redirection' => 10,
117
-            );
118
-            $response     = wp_remote_get($request_url, $request_args);
119
-            if (is_wp_error($response)) {
120
-                trigger_error($response->get_error_message());
121
-            }
122
-        } else {
123
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
124
-        }
125
-    }
126
-
127
-
128
-    /**
129
-     * This returns
130
-     * the request params used for a scheduled message task request.
131
-     *
132
-     * @param string $task The task the request is for.
133
-     * @return array
134
-     */
135
-    public static function get_request_params($task)
136
-    {
137
-        // transient is used for flood control on msg_cron_trigger requests
138
-        $transient_key = 'ee_trans_' . uniqid($task);
139
-        set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
140
-        return array(
141
-            'type' => $task,
142
-            'key'  => $transient_key,
143
-        );
144
-    }
145
-
146
-
147
-    /**
148
-     * This is used to execute an immediate call to the run_cron task performed by EED_Messages
149
-     *
150
-     * @param string $task The task the request is being generated for.
151
-     */
152
-    public static function initiate_immediate_request_on_cron($task)
153
-    {
154
-        /** @var RequestInterface $request */
155
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
156
-        $request_args = EE_Messages_Scheduler::get_request_params($task);
157
-        // set those request args in the request so it gets picked up
158
-        foreach ($request_args as $request_key => $request_value) {
159
-            $request->setRequestParam($request_key, $request_value);
160
-        }
161
-        EED_Messages::instance()->run_cron();
162
-    }
163
-
164
-
165
-    /**
166
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
167
-     */
168
-    public static function batch_generation()
169
-    {
170
-        /**
171
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
172
-         */
173
-        if (
174
-            ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
175
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
176
-        ) {
177
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
178
-        }
179
-    }
180
-
181
-
182
-    /**
183
-     * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
184
-     */
185
-    public static function batch_sending()
186
-    {
187
-        /**
188
-         * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
189
-         */
190
-        if (
191
-            ! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
192
-            || ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
193
-        ) {
194
-            EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
195
-        }
196
-    }
197
-
198
-
199
-    /**
200
-     * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
201
-     * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete
202
-     * permanently from the database messages that have a MSG_modified date older than 30 days.
203
-     *
204
-     * @throws EE_Error
205
-     * @throws EE_Error
206
-     */
207
-    public static function cleanup()
208
-    {
209
-        // First, confirm that the generation and sending EE_Messages_Scheduler crons are
210
-        // set and reschedule them if they are not.
211
-        $message_crons_to_check = array(
212
-            'AHEE__EE_Messages_Scheduler__generation' => 'ee_message_cron',
213
-            'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
214
-        );
215
-        foreach ($message_crons_to_check as $hook_name => $frequency) {
216
-            if (! wp_next_scheduled($hook_name)) {
217
-                wp_schedule_event(time(), $frequency, $hook_name);
218
-            }
219
-        }
220
-
221
-        // check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
222
-        // until the next scheduled event.
223
-        if (
224
-            ! EE_Registry::instance()->CFG->messages->delete_threshold
225
-            || ! EE_Maintenance_Mode::instance()->models_can_query()
226
-        ) {
227
-            return;
228
-        }
229
-
230
-        /**
231
-         * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
232
-         * of deleting messages.
233
-         */
234
-        if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
235
-            EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
236
-        }
237
-    }
17
+	/**
18
+	 * Number of seconds between batch sends/generates on the cron job.
19
+	 * Defaults to 5 minutes in seconds.  If you want to change this interval, you can use the native WordPress
20
+	 * `cron_schedules` filter and modify the existing custom `ee_message_cron` schedule interval added.
21
+	 *
22
+	 * @type int
23
+	 */
24
+	const message_cron_schedule = 300;
25
+
26
+	/**
27
+	 * Constructor
28
+	 */
29
+	public function __construct()
30
+	{
31
+		// register tasks (and make sure only registered once).
32
+		if (! has_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'))) {
33
+			add_action('FHEE__EEH_Activation__get_cron_tasks', array($this, 'register_scheduled_tasks'), 10);
34
+		}
35
+
36
+		// register callbacks for scheduled events (but make sure they are set only once).
37
+		if (
38
+			! has_action(
39
+				'AHEE__EE_Messages_Scheduler__generation',
40
+				array('EE_Messages_Scheduler', 'batch_generation')
41
+			)
42
+		) {
43
+			add_action('AHEE__EE_Messages_Scheduler__generation', array('EE_Messages_Scheduler', 'batch_generation'));
44
+			add_action('AHEE__EE_Messages_Scheduler__sending', array('EE_Messages_Scheduler', 'batch_sending'));
45
+			add_action('AHEE__EE_Messages_Scheduler__cleanup', array('EE_Messages_Scheduler', 'cleanup'));
46
+		}
47
+
48
+		// add custom schedules
49
+		add_filter('cron_schedules', array($this, 'custom_schedules'));
50
+	}
51
+
52
+
53
+	/**
54
+	 * Add custom schedules for wp_cron
55
+	 *
56
+	 * @param $schedules
57
+	 */
58
+	public function custom_schedules($schedules)
59
+	{
60
+		$schedules['ee_message_cron'] = array(
61
+			'interval' => self::message_cron_schedule,
62
+			'display'  => esc_html__(
63
+				'This is the cron time interval for EE Message schedules (defaults to once every 5 minutes)',
64
+				'event_espresso'
65
+			),
66
+		);
67
+		return $schedules;
68
+	}
69
+
70
+
71
+	/**
72
+	 * Callback for FHEE__EEH_Activation__get_cron_tasks that is used to retrieve scheduled Cron events to add and
73
+	 * remove.
74
+	 *
75
+	 * @param array $tasks already existing scheduled tasks
76
+	 * @return array
77
+	 * @throws EE_Error
78
+	 * @throws ReflectionException
79
+	 */
80
+	public function register_scheduled_tasks($tasks)
81
+	{
82
+		EE_Registry::instance()->load_helper('DTT_Helper');
83
+		$tasks['AHEE__EE_Messages_Scheduler__generation'] = 'ee_message_cron';
84
+		$tasks['AHEE__EE_Messages_Scheduler__sending']    = 'ee_message_cron';
85
+		$tasks['AHEE__EE_Messages_Scheduler__cleanup'] = array( EEH_DTT_Helper::tomorrow(), 'daily');
86
+		return $tasks;
87
+	}
88
+
89
+
90
+	/**
91
+	 * This initiates a non-blocking separate request to execute on a scheduled task.
92
+	 * Note: The EED_Messages module has the handlers for these requests.
93
+	 *
94
+	 * @param string $task The task the request is being generated for.
95
+	 */
96
+	public static function initiate_scheduled_non_blocking_request($task)
97
+	{
98
+		if (
99
+			apply_filters(
100
+				'EE_Messages_Scheduler__initiate_scheduled_non_blocking_request__do_separate_request',
101
+				true
102
+			)
103
+		) {
104
+			$request_url  = add_query_arg(
105
+				array_merge(
106
+					array('ee' => 'msg_cron_trigger'),
107
+					EE_Messages_Scheduler::get_request_params($task)
108
+				),
109
+				site_url()
110
+			);
111
+			$request_args = array(
112
+				'timeout'     => 300,
113
+				'blocking'    => (defined('DOING_CRON') && DOING_CRON)
114
+								 || (defined('DOING_AJAX') && DOING_AJAX),
115
+				'sslverify'   => false,
116
+				'redirection' => 10,
117
+			);
118
+			$response     = wp_remote_get($request_url, $request_args);
119
+			if (is_wp_error($response)) {
120
+				trigger_error($response->get_error_message());
121
+			}
122
+		} else {
123
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron($task);
124
+		}
125
+	}
126
+
127
+
128
+	/**
129
+	 * This returns
130
+	 * the request params used for a scheduled message task request.
131
+	 *
132
+	 * @param string $task The task the request is for.
133
+	 * @return array
134
+	 */
135
+	public static function get_request_params($task)
136
+	{
137
+		// transient is used for flood control on msg_cron_trigger requests
138
+		$transient_key = 'ee_trans_' . uniqid($task);
139
+		set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
140
+		return array(
141
+			'type' => $task,
142
+			'key'  => $transient_key,
143
+		);
144
+	}
145
+
146
+
147
+	/**
148
+	 * This is used to execute an immediate call to the run_cron task performed by EED_Messages
149
+	 *
150
+	 * @param string $task The task the request is being generated for.
151
+	 */
152
+	public static function initiate_immediate_request_on_cron($task)
153
+	{
154
+		/** @var RequestInterface $request */
155
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
156
+		$request_args = EE_Messages_Scheduler::get_request_params($task);
157
+		// set those request args in the request so it gets picked up
158
+		foreach ($request_args as $request_key => $request_value) {
159
+			$request->setRequestParam($request_key, $request_value);
160
+		}
161
+		EED_Messages::instance()->run_cron();
162
+	}
163
+
164
+
165
+	/**
166
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__generation wp cron event
167
+	 */
168
+	public static function batch_generation()
169
+	{
170
+		/**
171
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
172
+		 */
173
+		if (
174
+			! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
175
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
176
+		) {
177
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('generate');
178
+		}
179
+	}
180
+
181
+
182
+	/**
183
+	 * Callback for scheduled AHEE__EE_Messages_Scheduler__sending
184
+	 */
185
+	public static function batch_sending()
186
+	{
187
+		/**
188
+		 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority()
189
+		 */
190
+		if (
191
+			! apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', false)
192
+			|| ! EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
193
+		) {
194
+			EE_Messages_Scheduler::initiate_immediate_request_on_cron('send');
195
+		}
196
+	}
197
+
198
+
199
+	/**
200
+	 * This is the callback for the `AHEE__EE_Messages_Scheduler__cleanup` scheduled event action.
201
+	 * This runs once a day and if cleanup is active (set via messages settings), it will (by default) delete
202
+	 * permanently from the database messages that have a MSG_modified date older than 30 days.
203
+	 *
204
+	 * @throws EE_Error
205
+	 * @throws EE_Error
206
+	 */
207
+	public static function cleanup()
208
+	{
209
+		// First, confirm that the generation and sending EE_Messages_Scheduler crons are
210
+		// set and reschedule them if they are not.
211
+		$message_crons_to_check = array(
212
+			'AHEE__EE_Messages_Scheduler__generation' => 'ee_message_cron',
213
+			'AHEE__EE_Messages_Scheduler__sending'    => 'ee_message_cron',
214
+		);
215
+		foreach ($message_crons_to_check as $hook_name => $frequency) {
216
+			if (! wp_next_scheduled($hook_name)) {
217
+				wp_schedule_event(time(), $frequency, $hook_name);
218
+			}
219
+		}
220
+
221
+		// check if user has cleanup turned on or if we're in maintenance mode.  If in maintenance mode we'll wait
222
+		// until the next scheduled event.
223
+		if (
224
+			! EE_Registry::instance()->CFG->messages->delete_threshold
225
+			|| ! EE_Maintenance_Mode::instance()->models_can_query()
226
+		) {
227
+			return;
228
+		}
229
+
230
+		/**
231
+		 * This filter switch allows other code (such as the EE_Worker_Queue add-on) to replace this with its own handling
232
+		 * of deleting messages.
233
+		 */
234
+		if (apply_filters('FHEE__EE_Messages_Scheduler__cleanup__handle_cleanup_on_cron', true)) {
235
+			EEM_Message::instance()->delete_old_messages(EE_Registry::instance()->CFG->messages->delete_threshold);
236
+		}
237
+	}
238 238
 }
Please login to merge, or discard this patch.
core/libraries/messages/data_class/EE_Messages_incoming_data.core.php 2 patches
Indentation   +518 added lines, -518 removed lines patch added patch discarded remove patch
@@ -18,522 +18,522 @@
 block discarded – undo
18 18
 {
19 19
 
20 20
 
21
-    /**
22
-     * user id for logged in user when data collected
23
-     *
24
-     * @var string $user_id
25
-     */
26
-    public $user_id;
27
-
28
-    /**
29
-     * IP Address of browser used
30
-     *
31
-     * @var string $ip_address
32
-     */
33
-    public $ip_address;
34
-
35
-    /**
36
-     * browser
37
-     *
38
-     * @var string $user_agent
39
-     */
40
-    public $user_agent;
41
-
42
-    /**
43
-     * Unix timestamp
44
-     *
45
-     * @var string $init_access
46
-     */
47
-    public $init_access;
48
-
49
-    /**
50
-     * Unix timestamp
51
-     *
52
-     * @var string $last_access
53
-     */
54
-    public $last_access;
55
-
56
-    /**
57
-     * The registrations details from the cart
58
-     *
59
-     * @var array $reg_info
60
-     */
61
-    public $reg_info;
62
-
63
-    /**
64
-     * Some data handlers can set what reg status all the registrations are filtered by.
65
-     * The status should match a EEM_Registration status constant.
66
-     *
67
-     * @var string $filtered_reg_status
68
-     */
69
-    public $filtered_reg_status;
70
-
71
-    /**
72
-     * will hold an array of events assembled from $reg_info
73
-     *
74
-     * @var EE_Event[] $events
75
-     */
76
-    public $events;
77
-
78
-    /**
79
-     * holds an array of datetimes assembled from the incoming data.
80
-     *
81
-     * @var EE_Datetime[] $datetimes
82
-     */
83
-    public $datetimes;
84
-
85
-    /**
86
-     * holds an array of tickets assembled from the incoming data.
87
-     *
88
-     * @var EE_Ticket[] $tickets
89
-     */
90
-    public $tickets;
91
-
92
-    /**
93
-     * holds an array with a key of parent line item and values are an array of children of that line item.
94
-     *
95
-     * @since 4.5.0
96
-     * @var EE_Line_Item[] $line_items_with_children
97
-     */
98
-    public $line_items_with_children;
99
-
100
-    /**
101
-     * will hold an array of attendees assembled from the $reg_info
102
-     *
103
-     * @var EE_Attendee[] $attendees
104
-     */
105
-    public $attendees;
106
-
107
-    /**
108
-     * will hold an array of cached registration objects and info assembled from reg_info
109
-     *
110
-     * @var array $registrations
111
-     */
112
-    public $registrations;
113
-
114
-    /**
115
-     * will hold an array of answers assembled from the $reg_info
116
-     *
117
-     * @var EE_Answer[] $answers
118
-     */
119
-    public $answers;
120
-
121
-    /**
122
-     * will hold an array of questions assembled from the $reg_info (indexed by Answer ID);
123
-     *
124
-     * @var EE_Question[] $questions
125
-     */
126
-    public $questions;
127
-
128
-    /**
129
-     * Will hold billing data assembled from $billing_info (if present)
130
-     *
131
-     * @var mixed (array|null) $billing
132
-     */
133
-    public $billing;
134
-
135
-    /**
136
-     * The total amount of tax for the transaction
137
-     *
138
-     * @var float $taxes
139
-     */
140
-    public $taxes;
141
-
142
-    /**
143
-     * Holds the line items related to taxes
144
-     *
145
-     * @since 4.5.0
146
-     * @var EE_Line_Item[] $tax_line_items
147
-     */
148
-    public $tax_line_items;
149
-
150
-    /**
151
-     * Hold the line items which aren't taxes and don't relate
152
-     * to tickets. So: promotions and miscellaneous charges
153
-     *
154
-     * @since 4.5
155
-     * @var EE_Line_Item[] $additional_line_items
156
-     */
157
-    public $additional_line_items;
158
-
159
-    /**
160
-     * Holds the grand total EE_Line_Item
161
-     *
162
-     * @var EE_Line_Item $grand_total_line_item
163
-     */
164
-    public $grand_total_line_item;
165
-
166
-    /**
167
-     * holds the grand total price object
168
-     * currently not used.
169
-     *
170
-     * @var null $grand_total_price_object
171
-     */
172
-    public $grand_total_price_object;
173
-
174
-    /**
175
-     * total number of tickets
176
-     *
177
-     * @var int $total_ticket_count
178
-     */
179
-    public $total_ticket_count;
180
-
181
-    /**
182
-     * Will hold the final transaction object (EE_Transaction)
183
-     *
184
-     * @var EE_Transaction $txn
185
-     */
186
-    public $txn;
187
-
188
-    /**
189
-     * Holds the payments related to a transaction
190
-     *
191
-     * @since 4.5.0
192
-     * @var EE_Payment[] $payments
193
-     */
194
-    public $payments;
195
-
196
-    /**
197
-     * Holds the first related payment related for a transaction
198
-     *
199
-     * @since 4.5.0
200
-     * @var EE_Payment $payment
201
-     */
202
-    public $payment;
203
-
204
-    /**
205
-     * Will hold the label for the txn status
206
-     *
207
-     * @var string $txn_status
208
-     */
209
-    public $txn_status;
210
-
211
-    /**
212
-     * Will hold the final registration object (EE_Registration)
213
-     *
214
-     * @var EE_Registration[] $reg_objs
215
-     */
216
-    public $reg_objs;
217
-
218
-    /**
219
-     * Will hold an array of primary attendee data (if present)
220
-     *
221
-     * @var array $primary_attendee_data
222
-     */
223
-    public $primary_attendee_data;
224
-
225
-    /**
226
-     * This is just an internal object used for passing around the incoming data.
227
-     *
228
-     * @var mixed $_data
229
-     */
230
-    protected $_data;
231
-
232
-    /**
233
-     * This is just an internal object used for passing around the incoming data.
234
-     *
235
-     * @var mixed $incoming_data
236
-     */
237
-    public $incoming_data;
238
-
239
-    /**
240
-     * hold objects that might be created
241
-     *
242
-     * @type EE_Registration $reg_obj
243
-     */
244
-    public $reg_obj;
245
-
246
-
247
-    /**
248
-     * constructor
249
-     *
250
-     * @param mixed $data incoming data object|array.  Suggested that child classes use type hinting for expected
251
-     *                    data object.  But here parent will be generic because we don't know what's coming in.
252
-     */
253
-    public function __construct($data)
254
-    {
255
-        $this->_data = $data;
256
-        $this->_setup_data();
257
-    }
258
-
259
-
260
-    /**
261
-     * Every child class has to setup the data object !
262
-     *
263
-     * @return void
264
-     */
265
-    abstract protected function _setup_data();
266
-
267
-
268
-    /**
269
-     * Returns database safe representation of the data later used to when instantiating this object.
270
-     *
271
-     * @param mixed $data The incoming data to be prepped.
272
-     * @return mixed   The prepped data for db
273
-     */
274
-    public static function convert_data_for_persistent_storage($data)
275
-    {
276
-        return $data;
277
-    }
278
-
279
-
280
-    /**
281
-     * Data that has been stored in persistent storage that was prepped by _convert_data_for_persistent_storage
282
-     * can be sent into this method and converted back into the format used for instantiating with this data handler.
283
-     *
284
-     * @param $data
285
-     * @return mixed
286
-     */
287
-    public static function convert_data_from_persistent_storage($data)
288
-    {
289
-        return $data;
290
-    }
291
-
292
-
293
-    /**
294
-     * only purpose is to return the data
295
-     *
296
-     * @access public
297
-     * @return mixed the formatted data object!
298
-     */
299
-    public function data()
300
-    {
301
-        return $this->_data;
302
-    }
303
-
304
-
305
-    /**
306
-     * This helper method can be used by any incoming data handlers to setup the data correctly.  All that is required
307
-     * is that $this->reg_objs be set.
308
-     *
309
-     * @throws EE_Error
310
-     * @throws InvalidDataTypeException
311
-     * @throws InvalidInterfaceException
312
-     * @throws InvalidArgumentException
313
-     * @throws EntityNotFoundException
314
-     */
315
-    protected function _assemble_data()
316
-    {
317
-        // verify that reg_objs is set
318
-        if (
319
-            ! is_array($this->reg_objs)
320
-            && ! reset($this->reg_objs) instanceof EE_Registration
321
-        ) {
322
-            throw new EE_Error(
323
-                esc_html__(
324
-                    'In order to assemble the data correctly, the "reg_objs" property must be an array of EE_Registration objects',
325
-                    'event_espresso'
326
-                )
327
-            );
328
-        }
329
-
330
-        // get all attendee and events associated with the registrations in this transaction
331
-        $events             = $event_setup = $evtcache = $tickets = $datetimes = array();
332
-        $answers            = $questions = $attendees = $line_items = $registrations = array();
333
-        $total_ticket_count = 0;
334
-
335
-        if (! empty($this->reg_objs)) {
336
-            $event_attendee_count = array();
337
-            /** @var EE_Registration $reg */
338
-            foreach ($this->reg_objs as $reg) {
339
-                if (
340
-                    $this->_skip_registration_for_processing($reg)
341
-                ) {
342
-                    continue;
343
-                }
344
-
345
-                $evt_id = $reg->event_ID();
346
-                /** @type EE_Ticket $ticket */
347
-                $ticket          = $reg->get_first_related('Ticket');
348
-                $attendee = $reg->attendee();
349
-                $event = $reg->event();
350
-                // if none of the following entities are available, then we can't setup other data reliably,
351
-                // so let's just skip.
352
-                if (
353
-                    ! $ticket instanceof EE_Ticket
354
-                    || ! $attendee instanceof EE_Attendee
355
-                    || ! $event instanceof EE_Event
356
-                ) {
357
-                    continue;
358
-                }
359
-                $relateddatetime = $ticket->datetimes();
360
-                $total_ticket_count++;
361
-                $tickets[ $ticket->ID() ]['ticket']                        = $ticket;
362
-                $tickets[ $ticket->ID() ]['count']                         = is_array($tickets[ $ticket->ID() ])
363
-                                                                           && isset($tickets[ $ticket->ID() ]['count'])
364
-                    ? $tickets[ $ticket->ID() ]['count'] + 1
365
-                    : 1;
366
-                $tickets[ $ticket->ID() ]['att_objs'][ $attendee->ID() ] = $attendee;
367
-                $tickets[ $ticket->ID() ]['dtt_objs']                      = $relateddatetime;
368
-                $tickets[ $ticket->ID() ]['reg_objs'][ $reg->ID() ]          = $reg;
369
-                $tickets[ $ticket->ID() ]['EE_Event']                      = $event;
370
-                $evtcache[ $evt_id ]                                       = $event;
371
-                $eventsetup[ $evt_id ]['reg_objs'][ $reg->ID() ]             = $reg;
372
-                $eventsetup[ $evt_id ]['tkt_objs'][ $ticket->ID() ]          = $ticket;
373
-                $eventsetup[ $evt_id ]['att_objs'][ $attendee->ID() ]    = $attendee;
374
-                $event_attendee_count[ $evt_id ]                           = isset($event_attendee_count[ $evt_id ])
375
-                    ? $event_attendee_count[ $evt_id ] + 1
376
-                    : 0;
377
-                $attendees[ $reg->attendee_ID() ]['line_ref'][]            = $evt_id;
378
-                $attendees[ $reg->attendee_ID() ]['att_obj']               = $attendee;
379
-                $attendees[ $reg->attendee_ID() ]['reg_objs'][ $reg->ID() ]  = $reg;
380
-                // $attendees[ $reg->attendee_ID() ]['registration_id'] = $reg->ID();
381
-                $attendees[ $reg->attendee_ID() ]['attendee_email']          = $attendee->email();
382
-                $attendees[ $reg->attendee_ID() ]['tkt_objs'][ $ticket->ID() ] = $ticket;
383
-                $attendees[ $reg->attendee_ID() ]['evt_objs'][ $evt_id ]       = $event;
384
-
385
-                // registrations
386
-                $registrations[ $reg->ID() ]['tkt_obj'] = $ticket;
387
-                $registrations[ $reg->ID() ]['evt_obj'] = $event;
388
-                $registrations[ $reg->ID() ]['reg_obj'] = $reg;
389
-                $registrations[ $reg->ID() ]['att_obj'] = $attendee;
390
-
391
-                // set up answer objects
392
-                $rel_ans = $reg->get_many_related('Answer');
393
-                foreach ($rel_ans as $ansid => $answer) {
394
-                    if (! isset($questions[ $ansid ])) {
395
-                        $questions[ $ansid ] = $answer->get_first_related('Question');
396
-                    }
397
-                    $answers[ $ansid ]                               = $answer;
398
-                    $registrations[ $reg->ID() ]['ans_objs'][ $ansid ] = $answer;
399
-                }
400
-                /**
401
-                 * @var int $dtt_id
402
-                 * @var EE_Datetime $datetime
403
-                 */
404
-                foreach ($relateddatetime as $dtt_id => $datetime) {
405
-                    $eventsetup[ $evt_id ]['dtt_objs'][ $dtt_id ]       = $datetime;
406
-                    $registrations[ $reg->ID() ]['dtt_objs'][ $dtt_id ] = $datetime;
407
-
408
-                    if (isset($datetimes[ $dtt_id ])) {
409
-                        continue; // already have this info in the datetimes array.
410
-                    }
411
-
412
-                    $datetimes[ $dtt_id ]['tkt_objs'][]           = $ticket;
413
-                    $datetimes[ $dtt_id ]['datetime']             = $datetime;
414
-                    $datetimes[ $dtt_id ]['evt_objs'][ $evt_id ]    = $event;
415
-                    $datetimes[ $dtt_id ]['reg_objs'][ $reg->ID() ] = $reg;
416
-                }
417
-            }
418
-
419
-            // let's loop through the unique event=>reg items and setup data on them
420
-
421
-            if (! empty($eventsetup)) {
422
-                foreach ($eventsetup as $evt_id => $items) {
423
-                    $ticket_line_items_for_event = array();
424
-                    if ($this->txn instanceof EE_Transaction) {
425
-                        $ticket_line_items_for_event = EEM_Line_Item::instance()->get_all(
426
-                            array(
427
-                                array(
428
-                                    'Ticket.Datetime.EVT_ID' => $evt_id,
429
-                                    'TXN_ID'                 => $this->txn->ID(),
430
-                                ),
431
-                                'default_where_conditions' => 'none',
432
-                            )
433
-                        );
434
-                    }
435
-                    $events[ $evt_id ] = array(
436
-                        'ID'              => $evt_id,
437
-                        'event'           => $evtcache[ $evt_id ],
438
-                        'name'            => $evtcache[ $evt_id ] instanceof EE_Event ? $evtcache[ $evt_id ]->name() : '',
439
-                        'total_attendees' => $event_attendee_count[ $evt_id ],
440
-                        'reg_objs'        => $items['reg_objs'],
441
-                        'tkt_objs'        => $items['tkt_objs'],
442
-                        'att_objs'        => $items['att_objs'],
443
-                        'dtt_objs'        => isset($items['dtt_objs']) ? $items['dtt_objs'] : array(),
444
-                        'line_items'      => $ticket_line_items_for_event,
445
-                    );
446
-
447
-                    // make sure the tickets have the line items setup for them.
448
-                    foreach ($ticket_line_items_for_event as $line_id => $line_item) {
449
-                        // only add the ticket line items if we already have this ticket in the $tickets array.
450
-                        if ($line_item instanceof EE_Line_Item && isset($tickets[ $line_item->ticket()->ID() ])) {
451
-                            $tickets[ $line_item->ticket()->ID() ]['line_item']      = $line_item;
452
-                            $tickets[ $line_item->ticket()->ID() ]['sub_line_items'] = $line_item->children();
453
-                            $line_items[ $line_item->ID() ]['children']              = $line_item->children();
454
-                            $line_items[ $line_item->ID() ]['EE_Ticket']             = $line_item->ticket();
455
-                        }
456
-                    }
457
-                }
458
-            }
459
-
460
-            $this->grand_total_line_item = $this->txn instanceof EE_Transaction
461
-                ? $this->txn->total_line_item()
462
-                : null;
463
-        }
464
-
465
-        // lets set the attendees and events properties
466
-        $this->attendees                = $attendees;
467
-        $this->events                   = $events;
468
-        $this->tickets                  = $tickets;
469
-        $this->line_items_with_children = $line_items;
470
-        $this->datetimes                = $datetimes;
471
-        $this->questions                = $questions;
472
-        $this->answers                  = $answers;
473
-        $this->total_ticket_count       = $total_ticket_count;
474
-        $this->registrations            = $registrations;
475
-
476
-        if ($this->txn instanceof EE_Transaction) {
477
-            $this->tax_line_items        = $this->txn->tax_items();
478
-            $this->additional_line_items = $this->txn->non_ticket_line_items();
479
-            $this->payments              = $this->txn->payments();
480
-
481
-            // setup primary registration if we have a single transaction object to work with
482
-
483
-            // let's get just the primary_attendee_data!  First we get the primary registration object.
484
-            $primary_reg = $this->txn->primary_registration();
485
-            // verify
486
-            if ($primary_reg instanceof EE_Registration) {
487
-                // get attendee object
488
-                if ($primary_reg->attendee() instanceof EE_Attendee) {
489
-                    // now we can setup the primary_attendee_data array
490
-                    $this->primary_attendee_data = array(
491
-                        'registration_id' => $primary_reg->ID(),
492
-                        'att_obj'         => $primary_reg->attendee(),
493
-                        'reg_obj'         => $primary_reg,
494
-                        'primary_att_obj' => $primary_reg->attendee(),
495
-                        'primary_reg_obj' => $primary_reg,
496
-                    );
497
-                } else {
498
-                    EE_Error::add_error(
499
-                        esc_html__(
500
-                            'Incoming data does not have a valid Attendee object for the primary registrant.',
501
-                            'event_espresso'
502
-                        ),
503
-                        __FILE__,
504
-                        __FUNCTION__,
505
-                        __LINE__
506
-                    );
507
-                }
508
-            } else {
509
-                EE_Error::add_error(
510
-                    esc_html__(
511
-                        'Incoming data does not have a valid Registration object for the primary registrant.',
512
-                        'event_espresso'
513
-                    ),
514
-                    __FILE__,
515
-                    __FUNCTION__,
516
-                    __LINE__
517
-                );
518
-            }
519
-        }
520
-    }
521
-
522
-    /**
523
-     * This simply considers whether the given registration should be processed or not based on comparison with the
524
-     * filtered_reg_status property.
525
-     *
526
-     * @param EE_Registration $registration
527
-     * @return bool  returning true means we DO want to skip processing.  returning false means we DON'T want to skip
528
-     *               processing
529
-     */
530
-    protected function _skip_registration_for_processing(EE_Registration $registration)
531
-    {
532
-        if (empty($this->filtered_reg_status)) {
533
-            return false;
534
-        }
535
-
536
-        // if we made it here then we just compare the filtered_reg_status with the registration status and return that
537
-        return $this->filtered_reg_status !== $registration->status_ID();
538
-    }
21
+	/**
22
+	 * user id for logged in user when data collected
23
+	 *
24
+	 * @var string $user_id
25
+	 */
26
+	public $user_id;
27
+
28
+	/**
29
+	 * IP Address of browser used
30
+	 *
31
+	 * @var string $ip_address
32
+	 */
33
+	public $ip_address;
34
+
35
+	/**
36
+	 * browser
37
+	 *
38
+	 * @var string $user_agent
39
+	 */
40
+	public $user_agent;
41
+
42
+	/**
43
+	 * Unix timestamp
44
+	 *
45
+	 * @var string $init_access
46
+	 */
47
+	public $init_access;
48
+
49
+	/**
50
+	 * Unix timestamp
51
+	 *
52
+	 * @var string $last_access
53
+	 */
54
+	public $last_access;
55
+
56
+	/**
57
+	 * The registrations details from the cart
58
+	 *
59
+	 * @var array $reg_info
60
+	 */
61
+	public $reg_info;
62
+
63
+	/**
64
+	 * Some data handlers can set what reg status all the registrations are filtered by.
65
+	 * The status should match a EEM_Registration status constant.
66
+	 *
67
+	 * @var string $filtered_reg_status
68
+	 */
69
+	public $filtered_reg_status;
70
+
71
+	/**
72
+	 * will hold an array of events assembled from $reg_info
73
+	 *
74
+	 * @var EE_Event[] $events
75
+	 */
76
+	public $events;
77
+
78
+	/**
79
+	 * holds an array of datetimes assembled from the incoming data.
80
+	 *
81
+	 * @var EE_Datetime[] $datetimes
82
+	 */
83
+	public $datetimes;
84
+
85
+	/**
86
+	 * holds an array of tickets assembled from the incoming data.
87
+	 *
88
+	 * @var EE_Ticket[] $tickets
89
+	 */
90
+	public $tickets;
91
+
92
+	/**
93
+	 * holds an array with a key of parent line item and values are an array of children of that line item.
94
+	 *
95
+	 * @since 4.5.0
96
+	 * @var EE_Line_Item[] $line_items_with_children
97
+	 */
98
+	public $line_items_with_children;
99
+
100
+	/**
101
+	 * will hold an array of attendees assembled from the $reg_info
102
+	 *
103
+	 * @var EE_Attendee[] $attendees
104
+	 */
105
+	public $attendees;
106
+
107
+	/**
108
+	 * will hold an array of cached registration objects and info assembled from reg_info
109
+	 *
110
+	 * @var array $registrations
111
+	 */
112
+	public $registrations;
113
+
114
+	/**
115
+	 * will hold an array of answers assembled from the $reg_info
116
+	 *
117
+	 * @var EE_Answer[] $answers
118
+	 */
119
+	public $answers;
120
+
121
+	/**
122
+	 * will hold an array of questions assembled from the $reg_info (indexed by Answer ID);
123
+	 *
124
+	 * @var EE_Question[] $questions
125
+	 */
126
+	public $questions;
127
+
128
+	/**
129
+	 * Will hold billing data assembled from $billing_info (if present)
130
+	 *
131
+	 * @var mixed (array|null) $billing
132
+	 */
133
+	public $billing;
134
+
135
+	/**
136
+	 * The total amount of tax for the transaction
137
+	 *
138
+	 * @var float $taxes
139
+	 */
140
+	public $taxes;
141
+
142
+	/**
143
+	 * Holds the line items related to taxes
144
+	 *
145
+	 * @since 4.5.0
146
+	 * @var EE_Line_Item[] $tax_line_items
147
+	 */
148
+	public $tax_line_items;
149
+
150
+	/**
151
+	 * Hold the line items which aren't taxes and don't relate
152
+	 * to tickets. So: promotions and miscellaneous charges
153
+	 *
154
+	 * @since 4.5
155
+	 * @var EE_Line_Item[] $additional_line_items
156
+	 */
157
+	public $additional_line_items;
158
+
159
+	/**
160
+	 * Holds the grand total EE_Line_Item
161
+	 *
162
+	 * @var EE_Line_Item $grand_total_line_item
163
+	 */
164
+	public $grand_total_line_item;
165
+
166
+	/**
167
+	 * holds the grand total price object
168
+	 * currently not used.
169
+	 *
170
+	 * @var null $grand_total_price_object
171
+	 */
172
+	public $grand_total_price_object;
173
+
174
+	/**
175
+	 * total number of tickets
176
+	 *
177
+	 * @var int $total_ticket_count
178
+	 */
179
+	public $total_ticket_count;
180
+
181
+	/**
182
+	 * Will hold the final transaction object (EE_Transaction)
183
+	 *
184
+	 * @var EE_Transaction $txn
185
+	 */
186
+	public $txn;
187
+
188
+	/**
189
+	 * Holds the payments related to a transaction
190
+	 *
191
+	 * @since 4.5.0
192
+	 * @var EE_Payment[] $payments
193
+	 */
194
+	public $payments;
195
+
196
+	/**
197
+	 * Holds the first related payment related for a transaction
198
+	 *
199
+	 * @since 4.5.0
200
+	 * @var EE_Payment $payment
201
+	 */
202
+	public $payment;
203
+
204
+	/**
205
+	 * Will hold the label for the txn status
206
+	 *
207
+	 * @var string $txn_status
208
+	 */
209
+	public $txn_status;
210
+
211
+	/**
212
+	 * Will hold the final registration object (EE_Registration)
213
+	 *
214
+	 * @var EE_Registration[] $reg_objs
215
+	 */
216
+	public $reg_objs;
217
+
218
+	/**
219
+	 * Will hold an array of primary attendee data (if present)
220
+	 *
221
+	 * @var array $primary_attendee_data
222
+	 */
223
+	public $primary_attendee_data;
224
+
225
+	/**
226
+	 * This is just an internal object used for passing around the incoming data.
227
+	 *
228
+	 * @var mixed $_data
229
+	 */
230
+	protected $_data;
231
+
232
+	/**
233
+	 * This is just an internal object used for passing around the incoming data.
234
+	 *
235
+	 * @var mixed $incoming_data
236
+	 */
237
+	public $incoming_data;
238
+
239
+	/**
240
+	 * hold objects that might be created
241
+	 *
242
+	 * @type EE_Registration $reg_obj
243
+	 */
244
+	public $reg_obj;
245
+
246
+
247
+	/**
248
+	 * constructor
249
+	 *
250
+	 * @param mixed $data incoming data object|array.  Suggested that child classes use type hinting for expected
251
+	 *                    data object.  But here parent will be generic because we don't know what's coming in.
252
+	 */
253
+	public function __construct($data)
254
+	{
255
+		$this->_data = $data;
256
+		$this->_setup_data();
257
+	}
258
+
259
+
260
+	/**
261
+	 * Every child class has to setup the data object !
262
+	 *
263
+	 * @return void
264
+	 */
265
+	abstract protected function _setup_data();
266
+
267
+
268
+	/**
269
+	 * Returns database safe representation of the data later used to when instantiating this object.
270
+	 *
271
+	 * @param mixed $data The incoming data to be prepped.
272
+	 * @return mixed   The prepped data for db
273
+	 */
274
+	public static function convert_data_for_persistent_storage($data)
275
+	{
276
+		return $data;
277
+	}
278
+
279
+
280
+	/**
281
+	 * Data that has been stored in persistent storage that was prepped by _convert_data_for_persistent_storage
282
+	 * can be sent into this method and converted back into the format used for instantiating with this data handler.
283
+	 *
284
+	 * @param $data
285
+	 * @return mixed
286
+	 */
287
+	public static function convert_data_from_persistent_storage($data)
288
+	{
289
+		return $data;
290
+	}
291
+
292
+
293
+	/**
294
+	 * only purpose is to return the data
295
+	 *
296
+	 * @access public
297
+	 * @return mixed the formatted data object!
298
+	 */
299
+	public function data()
300
+	{
301
+		return $this->_data;
302
+	}
303
+
304
+
305
+	/**
306
+	 * This helper method can be used by any incoming data handlers to setup the data correctly.  All that is required
307
+	 * is that $this->reg_objs be set.
308
+	 *
309
+	 * @throws EE_Error
310
+	 * @throws InvalidDataTypeException
311
+	 * @throws InvalidInterfaceException
312
+	 * @throws InvalidArgumentException
313
+	 * @throws EntityNotFoundException
314
+	 */
315
+	protected function _assemble_data()
316
+	{
317
+		// verify that reg_objs is set
318
+		if (
319
+			! is_array($this->reg_objs)
320
+			&& ! reset($this->reg_objs) instanceof EE_Registration
321
+		) {
322
+			throw new EE_Error(
323
+				esc_html__(
324
+					'In order to assemble the data correctly, the "reg_objs" property must be an array of EE_Registration objects',
325
+					'event_espresso'
326
+				)
327
+			);
328
+		}
329
+
330
+		// get all attendee and events associated with the registrations in this transaction
331
+		$events             = $event_setup = $evtcache = $tickets = $datetimes = array();
332
+		$answers            = $questions = $attendees = $line_items = $registrations = array();
333
+		$total_ticket_count = 0;
334
+
335
+		if (! empty($this->reg_objs)) {
336
+			$event_attendee_count = array();
337
+			/** @var EE_Registration $reg */
338
+			foreach ($this->reg_objs as $reg) {
339
+				if (
340
+					$this->_skip_registration_for_processing($reg)
341
+				) {
342
+					continue;
343
+				}
344
+
345
+				$evt_id = $reg->event_ID();
346
+				/** @type EE_Ticket $ticket */
347
+				$ticket          = $reg->get_first_related('Ticket');
348
+				$attendee = $reg->attendee();
349
+				$event = $reg->event();
350
+				// if none of the following entities are available, then we can't setup other data reliably,
351
+				// so let's just skip.
352
+				if (
353
+					! $ticket instanceof EE_Ticket
354
+					|| ! $attendee instanceof EE_Attendee
355
+					|| ! $event instanceof EE_Event
356
+				) {
357
+					continue;
358
+				}
359
+				$relateddatetime = $ticket->datetimes();
360
+				$total_ticket_count++;
361
+				$tickets[ $ticket->ID() ]['ticket']                        = $ticket;
362
+				$tickets[ $ticket->ID() ]['count']                         = is_array($tickets[ $ticket->ID() ])
363
+																		   && isset($tickets[ $ticket->ID() ]['count'])
364
+					? $tickets[ $ticket->ID() ]['count'] + 1
365
+					: 1;
366
+				$tickets[ $ticket->ID() ]['att_objs'][ $attendee->ID() ] = $attendee;
367
+				$tickets[ $ticket->ID() ]['dtt_objs']                      = $relateddatetime;
368
+				$tickets[ $ticket->ID() ]['reg_objs'][ $reg->ID() ]          = $reg;
369
+				$tickets[ $ticket->ID() ]['EE_Event']                      = $event;
370
+				$evtcache[ $evt_id ]                                       = $event;
371
+				$eventsetup[ $evt_id ]['reg_objs'][ $reg->ID() ]             = $reg;
372
+				$eventsetup[ $evt_id ]['tkt_objs'][ $ticket->ID() ]          = $ticket;
373
+				$eventsetup[ $evt_id ]['att_objs'][ $attendee->ID() ]    = $attendee;
374
+				$event_attendee_count[ $evt_id ]                           = isset($event_attendee_count[ $evt_id ])
375
+					? $event_attendee_count[ $evt_id ] + 1
376
+					: 0;
377
+				$attendees[ $reg->attendee_ID() ]['line_ref'][]            = $evt_id;
378
+				$attendees[ $reg->attendee_ID() ]['att_obj']               = $attendee;
379
+				$attendees[ $reg->attendee_ID() ]['reg_objs'][ $reg->ID() ]  = $reg;
380
+				// $attendees[ $reg->attendee_ID() ]['registration_id'] = $reg->ID();
381
+				$attendees[ $reg->attendee_ID() ]['attendee_email']          = $attendee->email();
382
+				$attendees[ $reg->attendee_ID() ]['tkt_objs'][ $ticket->ID() ] = $ticket;
383
+				$attendees[ $reg->attendee_ID() ]['evt_objs'][ $evt_id ]       = $event;
384
+
385
+				// registrations
386
+				$registrations[ $reg->ID() ]['tkt_obj'] = $ticket;
387
+				$registrations[ $reg->ID() ]['evt_obj'] = $event;
388
+				$registrations[ $reg->ID() ]['reg_obj'] = $reg;
389
+				$registrations[ $reg->ID() ]['att_obj'] = $attendee;
390
+
391
+				// set up answer objects
392
+				$rel_ans = $reg->get_many_related('Answer');
393
+				foreach ($rel_ans as $ansid => $answer) {
394
+					if (! isset($questions[ $ansid ])) {
395
+						$questions[ $ansid ] = $answer->get_first_related('Question');
396
+					}
397
+					$answers[ $ansid ]                               = $answer;
398
+					$registrations[ $reg->ID() ]['ans_objs'][ $ansid ] = $answer;
399
+				}
400
+				/**
401
+				 * @var int $dtt_id
402
+				 * @var EE_Datetime $datetime
403
+				 */
404
+				foreach ($relateddatetime as $dtt_id => $datetime) {
405
+					$eventsetup[ $evt_id ]['dtt_objs'][ $dtt_id ]       = $datetime;
406
+					$registrations[ $reg->ID() ]['dtt_objs'][ $dtt_id ] = $datetime;
407
+
408
+					if (isset($datetimes[ $dtt_id ])) {
409
+						continue; // already have this info in the datetimes array.
410
+					}
411
+
412
+					$datetimes[ $dtt_id ]['tkt_objs'][]           = $ticket;
413
+					$datetimes[ $dtt_id ]['datetime']             = $datetime;
414
+					$datetimes[ $dtt_id ]['evt_objs'][ $evt_id ]    = $event;
415
+					$datetimes[ $dtt_id ]['reg_objs'][ $reg->ID() ] = $reg;
416
+				}
417
+			}
418
+
419
+			// let's loop through the unique event=>reg items and setup data on them
420
+
421
+			if (! empty($eventsetup)) {
422
+				foreach ($eventsetup as $evt_id => $items) {
423
+					$ticket_line_items_for_event = array();
424
+					if ($this->txn instanceof EE_Transaction) {
425
+						$ticket_line_items_for_event = EEM_Line_Item::instance()->get_all(
426
+							array(
427
+								array(
428
+									'Ticket.Datetime.EVT_ID' => $evt_id,
429
+									'TXN_ID'                 => $this->txn->ID(),
430
+								),
431
+								'default_where_conditions' => 'none',
432
+							)
433
+						);
434
+					}
435
+					$events[ $evt_id ] = array(
436
+						'ID'              => $evt_id,
437
+						'event'           => $evtcache[ $evt_id ],
438
+						'name'            => $evtcache[ $evt_id ] instanceof EE_Event ? $evtcache[ $evt_id ]->name() : '',
439
+						'total_attendees' => $event_attendee_count[ $evt_id ],
440
+						'reg_objs'        => $items['reg_objs'],
441
+						'tkt_objs'        => $items['tkt_objs'],
442
+						'att_objs'        => $items['att_objs'],
443
+						'dtt_objs'        => isset($items['dtt_objs']) ? $items['dtt_objs'] : array(),
444
+						'line_items'      => $ticket_line_items_for_event,
445
+					);
446
+
447
+					// make sure the tickets have the line items setup for them.
448
+					foreach ($ticket_line_items_for_event as $line_id => $line_item) {
449
+						// only add the ticket line items if we already have this ticket in the $tickets array.
450
+						if ($line_item instanceof EE_Line_Item && isset($tickets[ $line_item->ticket()->ID() ])) {
451
+							$tickets[ $line_item->ticket()->ID() ]['line_item']      = $line_item;
452
+							$tickets[ $line_item->ticket()->ID() ]['sub_line_items'] = $line_item->children();
453
+							$line_items[ $line_item->ID() ]['children']              = $line_item->children();
454
+							$line_items[ $line_item->ID() ]['EE_Ticket']             = $line_item->ticket();
455
+						}
456
+					}
457
+				}
458
+			}
459
+
460
+			$this->grand_total_line_item = $this->txn instanceof EE_Transaction
461
+				? $this->txn->total_line_item()
462
+				: null;
463
+		}
464
+
465
+		// lets set the attendees and events properties
466
+		$this->attendees                = $attendees;
467
+		$this->events                   = $events;
468
+		$this->tickets                  = $tickets;
469
+		$this->line_items_with_children = $line_items;
470
+		$this->datetimes                = $datetimes;
471
+		$this->questions                = $questions;
472
+		$this->answers                  = $answers;
473
+		$this->total_ticket_count       = $total_ticket_count;
474
+		$this->registrations            = $registrations;
475
+
476
+		if ($this->txn instanceof EE_Transaction) {
477
+			$this->tax_line_items        = $this->txn->tax_items();
478
+			$this->additional_line_items = $this->txn->non_ticket_line_items();
479
+			$this->payments              = $this->txn->payments();
480
+
481
+			// setup primary registration if we have a single transaction object to work with
482
+
483
+			// let's get just the primary_attendee_data!  First we get the primary registration object.
484
+			$primary_reg = $this->txn->primary_registration();
485
+			// verify
486
+			if ($primary_reg instanceof EE_Registration) {
487
+				// get attendee object
488
+				if ($primary_reg->attendee() instanceof EE_Attendee) {
489
+					// now we can setup the primary_attendee_data array
490
+					$this->primary_attendee_data = array(
491
+						'registration_id' => $primary_reg->ID(),
492
+						'att_obj'         => $primary_reg->attendee(),
493
+						'reg_obj'         => $primary_reg,
494
+						'primary_att_obj' => $primary_reg->attendee(),
495
+						'primary_reg_obj' => $primary_reg,
496
+					);
497
+				} else {
498
+					EE_Error::add_error(
499
+						esc_html__(
500
+							'Incoming data does not have a valid Attendee object for the primary registrant.',
501
+							'event_espresso'
502
+						),
503
+						__FILE__,
504
+						__FUNCTION__,
505
+						__LINE__
506
+					);
507
+				}
508
+			} else {
509
+				EE_Error::add_error(
510
+					esc_html__(
511
+						'Incoming data does not have a valid Registration object for the primary registrant.',
512
+						'event_espresso'
513
+					),
514
+					__FILE__,
515
+					__FUNCTION__,
516
+					__LINE__
517
+				);
518
+			}
519
+		}
520
+	}
521
+
522
+	/**
523
+	 * This simply considers whether the given registration should be processed or not based on comparison with the
524
+	 * filtered_reg_status property.
525
+	 *
526
+	 * @param EE_Registration $registration
527
+	 * @return bool  returning true means we DO want to skip processing.  returning false means we DON'T want to skip
528
+	 *               processing
529
+	 */
530
+	protected function _skip_registration_for_processing(EE_Registration $registration)
531
+	{
532
+		if (empty($this->filtered_reg_status)) {
533
+			return false;
534
+		}
535
+
536
+		// if we made it here then we just compare the filtered_reg_status with the registration status and return that
537
+		return $this->filtered_reg_status !== $registration->status_ID();
538
+	}
539 539
 }
Please login to merge, or discard this patch.
Spacing   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
         $answers            = $questions = $attendees = $line_items = $registrations = array();
333 333
         $total_ticket_count = 0;
334 334
 
335
-        if (! empty($this->reg_objs)) {
335
+        if ( ! empty($this->reg_objs)) {
336 336
             $event_attendee_count = array();
337 337
             /** @var EE_Registration $reg */
338 338
             foreach ($this->reg_objs as $reg) {
@@ -344,7 +344,7 @@  discard block
 block discarded – undo
344 344
 
345 345
                 $evt_id = $reg->event_ID();
346 346
                 /** @type EE_Ticket $ticket */
347
-                $ticket          = $reg->get_first_related('Ticket');
347
+                $ticket = $reg->get_first_related('Ticket');
348 348
                 $attendee = $reg->attendee();
349 349
                 $event = $reg->event();
350 350
                 // if none of the following entities are available, then we can't setup other data reliably,
@@ -358,67 +358,67 @@  discard block
 block discarded – undo
358 358
                 }
359 359
                 $relateddatetime = $ticket->datetimes();
360 360
                 $total_ticket_count++;
361
-                $tickets[ $ticket->ID() ]['ticket']                        = $ticket;
362
-                $tickets[ $ticket->ID() ]['count']                         = is_array($tickets[ $ticket->ID() ])
363
-                                                                           && isset($tickets[ $ticket->ID() ]['count'])
364
-                    ? $tickets[ $ticket->ID() ]['count'] + 1
361
+                $tickets[$ticket->ID()]['ticket']                        = $ticket;
362
+                $tickets[$ticket->ID()]['count']                         = is_array($tickets[$ticket->ID()])
363
+                                                                           && isset($tickets[$ticket->ID()]['count'])
364
+                    ? $tickets[$ticket->ID()]['count'] + 1
365 365
                     : 1;
366
-                $tickets[ $ticket->ID() ]['att_objs'][ $attendee->ID() ] = $attendee;
367
-                $tickets[ $ticket->ID() ]['dtt_objs']                      = $relateddatetime;
368
-                $tickets[ $ticket->ID() ]['reg_objs'][ $reg->ID() ]          = $reg;
369
-                $tickets[ $ticket->ID() ]['EE_Event']                      = $event;
370
-                $evtcache[ $evt_id ]                                       = $event;
371
-                $eventsetup[ $evt_id ]['reg_objs'][ $reg->ID() ]             = $reg;
372
-                $eventsetup[ $evt_id ]['tkt_objs'][ $ticket->ID() ]          = $ticket;
373
-                $eventsetup[ $evt_id ]['att_objs'][ $attendee->ID() ]    = $attendee;
374
-                $event_attendee_count[ $evt_id ]                           = isset($event_attendee_count[ $evt_id ])
375
-                    ? $event_attendee_count[ $evt_id ] + 1
366
+                $tickets[$ticket->ID()]['att_objs'][$attendee->ID()] = $attendee;
367
+                $tickets[$ticket->ID()]['dtt_objs']                      = $relateddatetime;
368
+                $tickets[$ticket->ID()]['reg_objs'][$reg->ID()]          = $reg;
369
+                $tickets[$ticket->ID()]['EE_Event']                      = $event;
370
+                $evtcache[$evt_id]                                       = $event;
371
+                $eventsetup[$evt_id]['reg_objs'][$reg->ID()]             = $reg;
372
+                $eventsetup[$evt_id]['tkt_objs'][$ticket->ID()]          = $ticket;
373
+                $eventsetup[$evt_id]['att_objs'][$attendee->ID()] = $attendee;
374
+                $event_attendee_count[$evt_id]                           = isset($event_attendee_count[$evt_id])
375
+                    ? $event_attendee_count[$evt_id] + 1
376 376
                     : 0;
377
-                $attendees[ $reg->attendee_ID() ]['line_ref'][]            = $evt_id;
378
-                $attendees[ $reg->attendee_ID() ]['att_obj']               = $attendee;
379
-                $attendees[ $reg->attendee_ID() ]['reg_objs'][ $reg->ID() ]  = $reg;
377
+                $attendees[$reg->attendee_ID()]['line_ref'][]            = $evt_id;
378
+                $attendees[$reg->attendee_ID()]['att_obj']               = $attendee;
379
+                $attendees[$reg->attendee_ID()]['reg_objs'][$reg->ID()]  = $reg;
380 380
                 // $attendees[ $reg->attendee_ID() ]['registration_id'] = $reg->ID();
381
-                $attendees[ $reg->attendee_ID() ]['attendee_email']          = $attendee->email();
382
-                $attendees[ $reg->attendee_ID() ]['tkt_objs'][ $ticket->ID() ] = $ticket;
383
-                $attendees[ $reg->attendee_ID() ]['evt_objs'][ $evt_id ]       = $event;
381
+                $attendees[$reg->attendee_ID()]['attendee_email']          = $attendee->email();
382
+                $attendees[$reg->attendee_ID()]['tkt_objs'][$ticket->ID()] = $ticket;
383
+                $attendees[$reg->attendee_ID()]['evt_objs'][$evt_id]       = $event;
384 384
 
385 385
                 // registrations
386
-                $registrations[ $reg->ID() ]['tkt_obj'] = $ticket;
387
-                $registrations[ $reg->ID() ]['evt_obj'] = $event;
388
-                $registrations[ $reg->ID() ]['reg_obj'] = $reg;
389
-                $registrations[ $reg->ID() ]['att_obj'] = $attendee;
386
+                $registrations[$reg->ID()]['tkt_obj'] = $ticket;
387
+                $registrations[$reg->ID()]['evt_obj'] = $event;
388
+                $registrations[$reg->ID()]['reg_obj'] = $reg;
389
+                $registrations[$reg->ID()]['att_obj'] = $attendee;
390 390
 
391 391
                 // set up answer objects
392 392
                 $rel_ans = $reg->get_many_related('Answer');
393 393
                 foreach ($rel_ans as $ansid => $answer) {
394
-                    if (! isset($questions[ $ansid ])) {
395
-                        $questions[ $ansid ] = $answer->get_first_related('Question');
394
+                    if ( ! isset($questions[$ansid])) {
395
+                        $questions[$ansid] = $answer->get_first_related('Question');
396 396
                     }
397
-                    $answers[ $ansid ]                               = $answer;
398
-                    $registrations[ $reg->ID() ]['ans_objs'][ $ansid ] = $answer;
397
+                    $answers[$ansid] = $answer;
398
+                    $registrations[$reg->ID()]['ans_objs'][$ansid] = $answer;
399 399
                 }
400 400
                 /**
401 401
                  * @var int $dtt_id
402 402
                  * @var EE_Datetime $datetime
403 403
                  */
404 404
                 foreach ($relateddatetime as $dtt_id => $datetime) {
405
-                    $eventsetup[ $evt_id ]['dtt_objs'][ $dtt_id ]       = $datetime;
406
-                    $registrations[ $reg->ID() ]['dtt_objs'][ $dtt_id ] = $datetime;
405
+                    $eventsetup[$evt_id]['dtt_objs'][$dtt_id]       = $datetime;
406
+                    $registrations[$reg->ID()]['dtt_objs'][$dtt_id] = $datetime;
407 407
 
408
-                    if (isset($datetimes[ $dtt_id ])) {
408
+                    if (isset($datetimes[$dtt_id])) {
409 409
                         continue; // already have this info in the datetimes array.
410 410
                     }
411 411
 
412
-                    $datetimes[ $dtt_id ]['tkt_objs'][]           = $ticket;
413
-                    $datetimes[ $dtt_id ]['datetime']             = $datetime;
414
-                    $datetimes[ $dtt_id ]['evt_objs'][ $evt_id ]    = $event;
415
-                    $datetimes[ $dtt_id ]['reg_objs'][ $reg->ID() ] = $reg;
412
+                    $datetimes[$dtt_id]['tkt_objs'][]           = $ticket;
413
+                    $datetimes[$dtt_id]['datetime']             = $datetime;
414
+                    $datetimes[$dtt_id]['evt_objs'][$evt_id]    = $event;
415
+                    $datetimes[$dtt_id]['reg_objs'][$reg->ID()] = $reg;
416 416
                 }
417 417
             }
418 418
 
419 419
             // let's loop through the unique event=>reg items and setup data on them
420 420
 
421
-            if (! empty($eventsetup)) {
421
+            if ( ! empty($eventsetup)) {
422 422
                 foreach ($eventsetup as $evt_id => $items) {
423 423
                     $ticket_line_items_for_event = array();
424 424
                     if ($this->txn instanceof EE_Transaction) {
@@ -432,11 +432,11 @@  discard block
 block discarded – undo
432 432
                             )
433 433
                         );
434 434
                     }
435
-                    $events[ $evt_id ] = array(
435
+                    $events[$evt_id] = array(
436 436
                         'ID'              => $evt_id,
437
-                        'event'           => $evtcache[ $evt_id ],
438
-                        'name'            => $evtcache[ $evt_id ] instanceof EE_Event ? $evtcache[ $evt_id ]->name() : '',
439
-                        'total_attendees' => $event_attendee_count[ $evt_id ],
437
+                        'event'           => $evtcache[$evt_id],
438
+                        'name'            => $evtcache[$evt_id] instanceof EE_Event ? $evtcache[$evt_id]->name() : '',
439
+                        'total_attendees' => $event_attendee_count[$evt_id],
440 440
                         'reg_objs'        => $items['reg_objs'],
441 441
                         'tkt_objs'        => $items['tkt_objs'],
442 442
                         'att_objs'        => $items['att_objs'],
@@ -447,11 +447,11 @@  discard block
 block discarded – undo
447 447
                     // make sure the tickets have the line items setup for them.
448 448
                     foreach ($ticket_line_items_for_event as $line_id => $line_item) {
449 449
                         // only add the ticket line items if we already have this ticket in the $tickets array.
450
-                        if ($line_item instanceof EE_Line_Item && isset($tickets[ $line_item->ticket()->ID() ])) {
451
-                            $tickets[ $line_item->ticket()->ID() ]['line_item']      = $line_item;
452
-                            $tickets[ $line_item->ticket()->ID() ]['sub_line_items'] = $line_item->children();
453
-                            $line_items[ $line_item->ID() ]['children']              = $line_item->children();
454
-                            $line_items[ $line_item->ID() ]['EE_Ticket']             = $line_item->ticket();
450
+                        if ($line_item instanceof EE_Line_Item && isset($tickets[$line_item->ticket()->ID()])) {
451
+                            $tickets[$line_item->ticket()->ID()]['line_item']      = $line_item;
452
+                            $tickets[$line_item->ticket()->ID()]['sub_line_items'] = $line_item->children();
453
+                            $line_items[$line_item->ID()]['children']              = $line_item->children();
454
+                            $line_items[$line_item->ID()]['EE_Ticket']             = $line_item->ticket();
455 455
                         }
456 456
                     }
457 457
                 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Generator.lib.php 2 patches
Indentation   +996 added lines, -996 removed lines patch added patch discarded remove patch
@@ -17,1001 +17,1001 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * @type EE_Messages_Data_Handler_Collection
22
-     */
23
-    protected $_data_handler_collection;
24
-
25
-    /**
26
-     * @type  EE_Message_Template_Group_Collection
27
-     */
28
-    protected $_template_collection;
29
-
30
-    /**
31
-     * This will hold the data handler for the current EE_Message being generated.
32
-     *
33
-     * @type EE_Messages_incoming_data
34
-     */
35
-    protected $_current_data_handler;
36
-
37
-    /**
38
-     * This holds the EE_Messages_Queue that contains the messages to generate.
39
-     *
40
-     * @type EE_Messages_Queue
41
-     */
42
-    protected $_generation_queue;
43
-
44
-    /**
45
-     * This holds the EE_Messages_Queue that will store the generated EE_Message objects.
46
-     *
47
-     * @type EE_Messages_Queue
48
-     */
49
-    protected $_ready_queue;
50
-
51
-    /**
52
-     * This is a container for any error messages that get created through the generation
53
-     * process.
54
-     *
55
-     * @type array
56
-     */
57
-    protected $_error_msg = array();
58
-
59
-    /**
60
-     * Flag used to set when the current EE_Message in the generation queue has been verified.
61
-     *
62
-     * @type bool
63
-     */
64
-    protected $_verified = false;
65
-
66
-    /**
67
-     * This will hold the current messenger object corresponding with the current EE_Message in the generation queue.
68
-     *
69
-     * @type EE_messenger
70
-     */
71
-    protected $_current_messenger;
72
-
73
-    /**
74
-     * This will hold the current message type object corresponding with the current EE_Message in the generation queue.
75
-     *
76
-     * @type EE_message_type
77
-     */
78
-    protected $_current_message_type;
79
-
80
-    /**
81
-     * @type EEH_Parse_Shortcodes
82
-     */
83
-    protected $_shortcode_parser;
84
-
85
-
86
-    /**
87
-     * @param EE_Messages_Queue                     $generation_queue
88
-     * @param \EE_Messages_Queue                    $ready_queue
89
-     * @param \EE_Messages_Data_Handler_Collection  $data_handler_collection
90
-     * @param \EE_Message_Template_Group_Collection $template_collection
91
-     * @param \EEH_Parse_Shortcodes                 $shortcode_parser
92
-     */
93
-    public function __construct(
94
-        EE_Messages_Queue $generation_queue,
95
-        EE_Messages_Queue $ready_queue,
96
-        EE_Messages_Data_Handler_Collection $data_handler_collection,
97
-        EE_Message_Template_Group_Collection $template_collection,
98
-        EEH_Parse_Shortcodes $shortcode_parser
99
-    ) {
100
-        $this->_generation_queue        = $generation_queue;
101
-        $this->_ready_queue             = $ready_queue;
102
-        $this->_data_handler_collection = $data_handler_collection;
103
-        $this->_template_collection     = $template_collection;
104
-        $this->_shortcode_parser        = $shortcode_parser;
105
-    }
106
-
107
-
108
-    /**
109
-     * @return EE_Messages_Queue
110
-     */
111
-    public function generation_queue()
112
-    {
113
-        return $this->_generation_queue;
114
-    }
115
-
116
-
117
-    /**
118
-     *  This iterates through the provided queue and generates the EE_Message objects.
119
-     *  When iterating through the queue, the queued item that served as the base for generating other EE_Message
120
-     *  objects gets removed and the new EE_Message objects get added to a NEW queue.  The NEW queue is then returned
121
-     *  for the caller to decide what to do with it.
122
-     *
123
-     * @param   bool $save Whether to save the EE_Message objects in the new queue or just return.
124
-     * @return EE_Messages_Queue The new queue for holding generated EE_Message objects.
125
-     * @throws EE_Error
126
-     * @throws InvalidArgumentException
127
-     * @throws InvalidDataTypeException
128
-     * @throws InvalidInterfaceException
129
-     * @throws ReflectionException
130
-     */
131
-    public function generate($save = true)
132
-    {
133
-        // iterate through the messages in the queue, generate, and add to new queue.
134
-        $this->_generation_queue->get_message_repository()->rewind();
135
-        while ($this->_generation_queue->get_message_repository()->valid()) {
136
-            // reset "current" properties
137
-            $this->_reset_current_properties();
138
-
139
-            /** @type EE_Message $msg */
140
-            $msg = $this->_generation_queue->get_message_repository()->current();
141
-
142
-            /**
143
-             * need to get the next object and capture it for setting manually after deletes.  The reason is that when
144
-             * an object is removed from the repo then valid for the next object will fail.
145
-             */
146
-            $this->_generation_queue->get_message_repository()->next();
147
-            $next_msg = $this->_generation_queue->get_message_repository()->current();
148
-            // restore pointer to current item
149
-            $this->_generation_queue->get_message_repository()->set_current($msg);
150
-
151
-            // skip and delete if the current $msg is NOT incomplete (queued for generation)
152
-            if ($msg->STS_ID() !== EEM_Message::status_incomplete) {
153
-                // we keep this item in the db just remove from the repo.
154
-                $this->_generation_queue->get_message_repository()->remove($msg);
155
-                // next item
156
-                $this->_generation_queue->get_message_repository()->set_current($next_msg);
157
-                continue;
158
-            }
159
-
160
-            if ($this->_verify()) {
161
-                // let's get generating!
162
-                $this->_generate();
163
-            }
164
-
165
-            // don't persist debug_only messages if the messages system is not in debug mode.
166
-            if (
167
-                $msg->STS_ID() === EEM_Message::status_debug_only
168
-                && ! EEM_Message::debug()
169
-            ) {
170
-                do_action(
171
-                    'AHEE__EE_Messages_Generator__generate__before_debug_delete',
172
-                    $msg,
173
-                    $this->_error_msg,
174
-                    $this->_current_messenger,
175
-                    $this->_current_message_type,
176
-                    $this->_current_data_handler
177
-                );
178
-                $this->_generation_queue->get_message_repository()->delete();
179
-                $this->_generation_queue->get_message_repository()->set_current($next_msg);
180
-                continue;
181
-            }
182
-
183
-            // if there are error messages then let's set the status and the error message.
184
-            if ($this->_error_msg) {
185
-                // if the status is already debug only, then let's leave it at that.
186
-                if ($msg->STS_ID() !== EEM_Message::status_debug_only) {
187
-                    $msg->set_STS_ID(EEM_Message::status_failed);
188
-                }
189
-                do_action(
190
-                    'AHEE__EE_Messages_Generator__generate__processing_failed_message',
191
-                    $msg,
192
-                    $this->_error_msg,
193
-                    $this->_current_messenger,
194
-                    $this->_current_message_type,
195
-                    $this->_current_data_handler
196
-                );
197
-                $msg->set_error_message(
198
-                    esc_html__('Message failed to generate for the following reasons: ', 'event_espresso')
199
-                    . "\n"
200
-                    . implode("\n", $this->_error_msg)
201
-                );
202
-                $msg->set_modified(time());
203
-            } else {
204
-                do_action(
205
-                    'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete',
206
-                    $msg,
207
-                    $this->_error_msg,
208
-                    $this->_current_messenger,
209
-                    $this->_current_message_type,
210
-                    $this->_current_data_handler
211
-                );
212
-                // remove from db
213
-                $this->_generation_queue->get_message_repository()->delete();
214
-            }
215
-            // next item
216
-            $this->_generation_queue->get_message_repository()->set_current($next_msg);
217
-        }
218
-
219
-        // generation queue is ALWAYS saved to record any errors in the generation process.
220
-        $this->_generation_queue->save();
221
-
222
-        /**
223
-         * save _ready_queue if flag set.
224
-         * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method.  This
225
-         * means if a field was added that is not a valid database column.  The EE_Message was already saved to the db
226
-         * so a EE_Extra_Meta entry could be created and attached to the EE_Message.  In those cases the save flag is
227
-         * irrelevant.
228
-         */
229
-        if ($save) {
230
-            $this->_ready_queue->save();
231
-        }
232
-
233
-        // final reset of properties
234
-        $this->_reset_current_properties();
235
-
236
-        return $this->_ready_queue;
237
-    }
238
-
239
-
240
-    /**
241
-     * This resets all the properties used for holding "current" values corresponding to the current EE_Message object
242
-     * in the generation queue.
243
-     */
244
-    protected function _reset_current_properties()
245
-    {
246
-        $this->_verified = false;
247
-        // make sure any _data value in the current message type is reset
248
-        if ($this->_current_message_type instanceof EE_message_type) {
249
-            $this->_current_message_type->reset_data();
250
-        }
251
-        $this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null;
252
-    }
253
-
254
-
255
-    /**
256
-     * This proceeds with the actual generation of a message.  By the time this is called, there should already be a
257
-     * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the
258
-     * _generating_queue.
259
-     *
260
-     * @return bool Whether the message was successfully generated or not.
261
-     * @throws EE_Error
262
-     * @throws InvalidArgumentException
263
-     * @throws InvalidDataTypeException
264
-     * @throws InvalidInterfaceException
265
-     * @throws ReflectionException
266
-     */
267
-    protected function _generate()
268
-    {
269
-        // double check verification has run and that everything is ready to work with (saves us having to validate
270
-        // everything again).
271
-        if (! $this->_verified) {
272
-            return false; // get out because we don't have a valid setup to work with.
273
-        }
274
-
275
-
276
-        try {
277
-            $addressees = $this->_current_message_type->get_addressees(
278
-                $this->_current_data_handler,
279
-                $this->_generation_queue->get_message_repository()->current()->context()
280
-            );
281
-        } catch (EE_Error $e) {
282
-            $this->_error_msg[] = $e->getMessage();
283
-            return false;
284
-        }
285
-
286
-
287
-        // if no addressees then get out because there is nothing to generation (possible bad data).
288
-        if (! $this->_valid_addressees($addressees)) {
289
-            do_action(
290
-                'AHEE__EE_Messages_Generator___generate__invalid_addressees',
291
-                $this->_generation_queue->get_message_repository()->current(),
292
-                $addressees,
293
-                $this->_current_messenger,
294
-                $this->_current_message_type,
295
-                $this->_current_data_handler
296
-            );
297
-            $this->_generation_queue->get_message_repository()->current()->set_STS_ID(
298
-                EEM_Message::status_debug_only
299
-            );
300
-            $this->_error_msg[] = esc_html__(
301
-                'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects.  There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.',
302
-                'event_espresso'
303
-            );
304
-            return false;
305
-        }
306
-
307
-        $message_template_group = $this->_get_message_template_group();
308
-
309
-        // in the unlikely event there is no EE_Message_Template_Group available, get out!
310
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
311
-            $this->_error_msg[] = esc_html__(
312
-                'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
313
-                'event_espresso'
314
-            );
315
-            return false;
316
-        }
317
-
318
-        // get formatted templates for using to parse and setup EE_Message objects.
319
-        $templates = $this->_get_templates($message_template_group);
320
-
321
-
322
-        // setup new EE_Message objects (and add to _ready_queue)
323
-        return $this->_assemble_messages($addressees, $templates, $message_template_group);
324
-    }
325
-
326
-
327
-    /**
328
-     * Retrieves the message template group being used for generating messages.
329
-     * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times.
330
-     *
331
-     * @return EE_Message_Template_Group|null
332
-     * @throws EE_Error
333
-     * @throws InvalidArgumentException
334
-     * @throws InvalidDataTypeException
335
-     * @throws InvalidInterfaceException
336
-     * @throws ReflectionException
337
-     */
338
-    protected function _get_message_template_group()
339
-    {
340
-        // first see if there is a specific message template group requested (current message in the queue has a
341
-        // specific GRP_ID
342
-        $message_template_group = $this->_specific_message_template_group_from_queue();
343
-        if ($message_template_group instanceof EE_Message_Template_Group) {
344
-            return $message_template_group;
345
-        }
346
-
347
-        // get event_ids from the datahandler so we can check to see if there's already a message template group for
348
-        // them in the collection.
349
-        $event_ids              = $this->_get_event_ids_from_current_data_handler();
350
-        $message_template_group = $this->_template_collection->get_by_key(
351
-            $this->_template_collection->getKey(
352
-                $this->_current_messenger->name,
353
-                $this->_current_message_type->name,
354
-                $event_ids
355
-            )
356
-        );
357
-
358
-        // if we have a message template group then no need to hit the database, just return it.
359
-        if ($message_template_group instanceof EE_Message_Template_Group) {
360
-            return $message_template_group;
361
-        }
362
-
363
-        // okay made it here, so let's get the global group first for this messenger and message type to ensure
364
-        // there is no override set.
365
-        $global_message_template_group =
366
-            $this->_get_global_message_template_group_for_current_messenger_and_message_type();
367
-
368
-        if (
369
-            $global_message_template_group instanceof EE_Message_Template_Group
370
-            && $global_message_template_group->get('MTP_is_override')
371
-        ) {
372
-            return $global_message_template_group;
373
-        }
374
-
375
-        // if we're still here, that means there was no message template group for the events in the collection and
376
-        // the global message template group for the messenger and message type is not set for override.  So next step
377
-        // is to see if there is a common shared custom message template group for this set of events.
378
-        $message_template_group = $this->_get_shared_message_template_for_events($event_ids);
379
-        if ($message_template_group instanceof EE_Message_Template_Group) {
380
-            return $message_template_group;
381
-        }
382
-
383
-        // STILL here?  Okay that means the fallback is to just use the global message template group for this event
384
-        // set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this
385
-        // request) and return it.
386
-        if ($global_message_template_group instanceof EE_Message_Template_Group) {
387
-            $this->_template_collection->add(
388
-                $global_message_template_group,
389
-                $event_ids
390
-            );
391
-            return $global_message_template_group;
392
-        }
393
-
394
-        // if we land here that means there's NO active message template group for this set.
395
-        // TODO this will be a good target for some optimization down the road.  Whenever there is no active message
396
-        // template group for a given event set then cache that result so we don't repeat the logic.  However, for now,
397
-        // this should likely bit hit rarely enough that it's not a significant issue.
398
-        return null;
399
-    }
400
-
401
-
402
-    /**
403
-     * This checks the current message in the queue and determines if there is a specific Message Template Group
404
-     * requested for that message.
405
-     *
406
-     * @return EE_Message_Template_Group|null
407
-     * @throws EE_Error
408
-     * @throws InvalidArgumentException
409
-     * @throws InvalidDataTypeException
410
-     * @throws InvalidInterfaceException
411
-     */
412
-    protected function _specific_message_template_group_from_queue()
413
-    {
414
-        // is there a GRP_ID already on the EE_Message object?  If there is, then a specific template has been requested
415
-        // so let's use that.
416
-        $GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID();
417
-
418
-        if ($GRP_ID) {
419
-            // attempt to retrieve from repo first
420
-            $message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
421
-            if ($message_template_group instanceof EE_Message_Template_Group) {
422
-                return $message_template_group;  // got it!
423
-            }
424
-
425
-            // nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
426
-            // is not valid, so we'll continue on in the code assuming there's NO GRP_ID.
427
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
428
-            if ($message_template_group instanceof EE_Message_Template_Group) {
429
-                $this->_template_collection->add($message_template_group);
430
-                return $message_template_group;
431
-            }
432
-        }
433
-        return null;
434
-    }
435
-
436
-
437
-    /**
438
-     * Returns whether the event ids passed in all share the same message template group for the current message type
439
-     * and messenger.
440
-     *
441
-     * @param array $event_ids
442
-     * @return bool true means they DO share the same message template group, false means they don't.
443
-     * @throws EE_Error
444
-     * @throws InvalidArgumentException
445
-     * @throws InvalidDataTypeException
446
-     * @throws InvalidInterfaceException
447
-     */
448
-    protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
449
-    {
450
-        foreach ($this->_current_data_handler->events as $event) {
451
-            $event_ids[ $event['ID'] ] = $event['ID'];
452
-        }
453
-        $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
454
-            array(
455
-                array(
456
-                    'Event.EVT_ID'           => array('IN', $event_ids),
457
-                    'MTP_messenger'    => $this->_current_messenger->name,
458
-                    'MTP_message_type' => $this->_current_message_type->name,
459
-                ),
460
-            ),
461
-            'GRP_ID',
462
-            true
463
-        );
464
-        return $count_of_message_template_groups === 1;
465
-    }
466
-
467
-
468
-    /**
469
-     * This will get the shared message template group for events that are in the current data handler but ONLY if
470
-     * there's a single shared message template group among all the events.  Otherwise it returns null.
471
-     *
472
-     * @param array $event_ids
473
-     * @return EE_Message_Template_Group|null
474
-     * @throws EE_Error
475
-     * @throws InvalidArgumentException
476
-     * @throws InvalidDataTypeException
477
-     * @throws InvalidInterfaceException
478
-     */
479
-    protected function _get_shared_message_template_for_events(array $event_ids)
480
-    {
481
-        $message_template_group = null;
482
-        if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) {
483
-            $message_template_group = EEM_Message_Template_Group::instance()->get_one(
484
-                array(
485
-                    array(
486
-                        'Event.EVT_ID'           => array('IN', $event_ids),
487
-                        'MTP_messenger'    => $this->_current_messenger->name,
488
-                        'MTP_message_type' => $this->_current_message_type->name,
489
-                        'MTP_is_active'    => true,
490
-                    ),
491
-                    'group_by' => 'GRP_ID',
492
-                )
493
-            );
494
-            // store this in the collection if its valid
495
-            if ($message_template_group instanceof EE_Message_Template_Group) {
496
-                $this->_template_collection->add(
497
-                    $message_template_group,
498
-                    $event_ids
499
-                );
500
-            }
501
-        }
502
-        return $message_template_group;
503
-    }
504
-
505
-
506
-    /**
507
-     * Retrieves the global message template group for the current messenger and message type.
508
-     *
509
-     * @return EE_Message_Template_Group|null
510
-     * @throws EE_Error
511
-     * @throws InvalidArgumentException
512
-     * @throws InvalidDataTypeException
513
-     * @throws InvalidInterfaceException
514
-     */
515
-    protected function _get_global_message_template_group_for_current_messenger_and_message_type()
516
-    {
517
-        // first check the collection (we use an array with 0 in it to represent global groups).
518
-        $global_message_template_group = $this->_template_collection->get_by_key(
519
-            $this->_template_collection->getKey(
520
-                $this->_current_messenger->name,
521
-                $this->_current_message_type->name,
522
-                array(0)
523
-            )
524
-        );
525
-
526
-        // if we don't have a group lets hit the db.
527
-        if (! $global_message_template_group instanceof EE_Message_Template_Group) {
528
-            $global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
529
-                array(
530
-                    array(
531
-                        'MTP_messenger'    => $this->_current_messenger->name,
532
-                        'MTP_message_type' => $this->_current_message_type->name,
533
-                        'MTP_is_active'    => true,
534
-                        'MTP_is_global'    => true,
535
-                    ),
536
-                )
537
-            );
538
-            // if we have a group, add it to the collection.
539
-            if ($global_message_template_group instanceof EE_Message_Template_Group) {
540
-                $this->_template_collection->add(
541
-                    $global_message_template_group,
542
-                    array(0)
543
-                );
544
-            }
545
-        }
546
-        return $global_message_template_group;
547
-    }
548
-
549
-
550
-    /**
551
-     * Returns an array of event ids for all the events within the current data handler.
552
-     *
553
-     * @return array
554
-     */
555
-    protected function _get_event_ids_from_current_data_handler()
556
-    {
557
-        $event_ids = array();
558
-        foreach ($this->_current_data_handler->events as $event) {
559
-            $event_ids[ $event['ID'] ] = $event['ID'];
560
-        }
561
-        return $event_ids;
562
-    }
563
-
564
-
565
-    /**
566
-     *  Retrieves formatted array of template information for each context specific to the given
567
-     *  EE_Message_Template_Group
568
-     *
569
-     * @param EE_Message_Template_Group $message_template_group
570
-     * @return array The returned array is in this structure:
571
-     *                          array(
572
-     *                          'field_name' => array(
573
-     *                          'context' => 'content'
574
-     *                          )
575
-     *                          )
576
-     * @throws EE_Error
577
-     * @throws InvalidArgumentException
578
-     * @throws InvalidDataTypeException
579
-     * @throws InvalidInterfaceException
580
-     * @throws ReflectionException
581
-     */
582
-    protected function _get_templates(EE_Message_Template_Group $message_template_group)
583
-    {
584
-        $templates         = array();
585
-        $context_templates = $message_template_group->context_templates();
586
-        foreach ($context_templates as $context => $template_fields) {
587
-            foreach ($template_fields as $template_field => $template_obj) {
588
-                if (! $template_obj instanceof EE_Message_Template) {
589
-                    continue;
590
-                }
591
-                $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content');
592
-            }
593
-        }
594
-        return $templates;
595
-    }
596
-
597
-
598
-    /**
599
-     * Assembles new fully generated EE_Message objects and adds to _ready_queue
600
-     *
601
-     * @param array                     $addressees  Array of EE_Messages_Addressee objects indexed by message type
602
-     *                                               context.
603
-     * @param array                     $templates   formatted array of templates used for parsing data.
604
-     * @param EE_Message_Template_Group $message_template_group
605
-     * @return bool true if message generation went a-ok.  false if some sort of exception occurred.  Note: The
606
-     *                                               method will attempt to generate ALL EE_Message objects and add to
607
-     *                                               the _ready_queue.  Successfully generated messages get added to the
608
-     *                                               queue with EEM_Message::status_idle, unsuccessfully generated
609
-     *                                               messages will get added to the queue as EEM_Message::status_failed.
610
-     *                                               Very rarely should "false" be returned from this method.
611
-     * @throws EE_Error
612
-     * @throws InvalidArgumentException
613
-     * @throws InvalidDataTypeException
614
-     * @throws InvalidIdentifierException
615
-     * @throws InvalidInterfaceException
616
-     * @throws ReflectionException
617
-     */
618
-    protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group)
619
-    {
620
-
621
-        // if templates are empty then get out because we can't generate anything.
622
-        if (! $templates) {
623
-            $this->_error_msg[] = esc_html__(
624
-                'Unable to assemble messages because there are no templates retrieved for generating the messages with',
625
-                'event_espresso'
626
-            );
627
-            return false;
628
-        }
629
-
630
-        // We use this as the counter for generated messages because don't forget we may be executing this inside of a
631
-        // generation_queue.  So _ready_queue may have generated EE_Message objects already.
632
-        $generated_count = 0;
633
-        foreach ($addressees as $context => $recipients) {
634
-            foreach ($recipients as $recipient) {
635
-                $message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group);
636
-                if ($message instanceof EE_Message) {
637
-                    $this->_ready_queue->add(
638
-                        $message,
639
-                        array(),
640
-                        $this->_generation_queue->get_message_repository()->is_preview(),
641
-                        $this->_generation_queue->get_message_repository()->is_test_send()
642
-                    );
643
-                    $generated_count++;
644
-                }
645
-
646
-                // if the current MSG being generated is for a test send then we'll only use ONE message in the
647
-                // generation.
648
-                if ($this->_generation_queue->get_message_repository()->is_test_send()) {
649
-                    break 2;
650
-                }
651
-            }
652
-        }
653
-
654
-        // if there are no generated messages then something else fatal went wrong.
655
-        return $generated_count > 0;
656
-    }
657
-
658
-
659
-    /**
660
-     * @param string                    $context   The context for the generated message.
661
-     * @param EE_Messages_Addressee     $recipient
662
-     * @param array                     $templates formatted array of templates used for parsing data.
663
-     * @param EE_Message_Template_Group $message_template_group
664
-     * @return bool|EE_Message
665
-     * @throws EE_Error
666
-     * @throws InvalidArgumentException
667
-     * @throws InvalidDataTypeException
668
-     * @throws InvalidInterfaceException
669
-     * @throws ReflectionException
670
-     * @throws InvalidIdentifierException
671
-     */
672
-    protected function _setup_message_object(
673
-        $context,
674
-        EE_Messages_Addressee $recipient,
675
-        $templates,
676
-        EE_Message_Template_Group $message_template_group
677
-    ) {
678
-        // stuff we already know
679
-        $transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0;
680
-        $transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction
681
-            ? $this->_current_data_handler->txn->ID()
682
-            : $transaction_id;
683
-        $message_fields = array(
684
-            'GRP_ID'           => $message_template_group->ID(),
685
-            'TXN_ID'           => $transaction_id,
686
-            'MSG_messenger'    => $this->_current_messenger->name,
687
-            'MSG_message_type' => $this->_current_message_type->name,
688
-            'MSG_context'      => $context,
689
-        );
690
-
691
-        // recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab
692
-        // the info from the att_obj found in the EE_Messages_Addressee object.
693
-        if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) {
694
-            $message_fields['MSG_recipient_ID']   = $recipient->att_obj instanceof EE_Attendee
695
-                ? $recipient->att_obj->ID()
696
-                : 0;
697
-            $message_fields['MSG_recipient_type'] = 'Attendee';
698
-        } else {
699
-            $message_fields['MSG_recipient_ID']   = $recipient->recipient_id;
700
-            $message_fields['MSG_recipient_type'] = $recipient->recipient_type;
701
-        }
702
-        $message = EE_Message_Factory::create($message_fields);
703
-
704
-        // grab valid shortcodes for shortcode parser
705
-        $mt_shortcodes = $this->_current_message_type->get_valid_shortcodes();
706
-        $m_shortcodes  = $this->_current_messenger->get_valid_shortcodes();
707
-
708
-        // if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing
709
-        if (
710
-            ! $this->_generation_queue->get_message_repository()->is_preview()
711
-            && (
712
-                            (
713
-                                empty($templates['to'][ $context ])
714
-                                && ! $this->_current_messenger->allow_empty_to_field()
715
-                            )
716
-                            || ! $message_template_group->is_context_active($context)
717
-                        )
718
-        ) {
719
-            // we silently exit here and do NOT record a fail because the message is "turned off" by having no "to"
720
-            // field.
721
-            return false;
722
-        }
723
-        $error_msg = array();
724
-        foreach ($templates as $field => $field_context) {
725
-            $error_msg = array();
726
-            // let's setup the valid shortcodes for the incoming context.
727
-            $valid_shortcodes = $mt_shortcodes[ $context ];
728
-            // merge in valid shortcodes for the field.
729
-            $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes;
730
-            if (isset($templates[ $field ][ $context ])) {
731
-                // prefix field.
732
-                $column_name = 'MSG_' . $field;
733
-                try {
734
-                    $content = $this->_shortcode_parser->parse_message_template(
735
-                        $templates[ $field ][ $context ],
736
-                        $recipient,
737
-                        $shortcodes,
738
-                        $this->_current_message_type,
739
-                        $this->_current_messenger,
740
-                        $message
741
-                    );
742
-                    // the model field removes slashes when setting (usually necessary when the input is from the
743
-                    // request) but this value is from another model and has no slashes. So add them so it matchces
744
-                    // what the field expected (otherwise slashes will have been stripped from this an extra time)
745
-                    $message->set_field_or_extra_meta($column_name, addslashes($content));
746
-                } catch (EE_Error $e) {
747
-                    $error_msg[] = sprintf(
748
-                        /* Translators: First place holder is message model field name.
20
+	/**
21
+	 * @type EE_Messages_Data_Handler_Collection
22
+	 */
23
+	protected $_data_handler_collection;
24
+
25
+	/**
26
+	 * @type  EE_Message_Template_Group_Collection
27
+	 */
28
+	protected $_template_collection;
29
+
30
+	/**
31
+	 * This will hold the data handler for the current EE_Message being generated.
32
+	 *
33
+	 * @type EE_Messages_incoming_data
34
+	 */
35
+	protected $_current_data_handler;
36
+
37
+	/**
38
+	 * This holds the EE_Messages_Queue that contains the messages to generate.
39
+	 *
40
+	 * @type EE_Messages_Queue
41
+	 */
42
+	protected $_generation_queue;
43
+
44
+	/**
45
+	 * This holds the EE_Messages_Queue that will store the generated EE_Message objects.
46
+	 *
47
+	 * @type EE_Messages_Queue
48
+	 */
49
+	protected $_ready_queue;
50
+
51
+	/**
52
+	 * This is a container for any error messages that get created through the generation
53
+	 * process.
54
+	 *
55
+	 * @type array
56
+	 */
57
+	protected $_error_msg = array();
58
+
59
+	/**
60
+	 * Flag used to set when the current EE_Message in the generation queue has been verified.
61
+	 *
62
+	 * @type bool
63
+	 */
64
+	protected $_verified = false;
65
+
66
+	/**
67
+	 * This will hold the current messenger object corresponding with the current EE_Message in the generation queue.
68
+	 *
69
+	 * @type EE_messenger
70
+	 */
71
+	protected $_current_messenger;
72
+
73
+	/**
74
+	 * This will hold the current message type object corresponding with the current EE_Message in the generation queue.
75
+	 *
76
+	 * @type EE_message_type
77
+	 */
78
+	protected $_current_message_type;
79
+
80
+	/**
81
+	 * @type EEH_Parse_Shortcodes
82
+	 */
83
+	protected $_shortcode_parser;
84
+
85
+
86
+	/**
87
+	 * @param EE_Messages_Queue                     $generation_queue
88
+	 * @param \EE_Messages_Queue                    $ready_queue
89
+	 * @param \EE_Messages_Data_Handler_Collection  $data_handler_collection
90
+	 * @param \EE_Message_Template_Group_Collection $template_collection
91
+	 * @param \EEH_Parse_Shortcodes                 $shortcode_parser
92
+	 */
93
+	public function __construct(
94
+		EE_Messages_Queue $generation_queue,
95
+		EE_Messages_Queue $ready_queue,
96
+		EE_Messages_Data_Handler_Collection $data_handler_collection,
97
+		EE_Message_Template_Group_Collection $template_collection,
98
+		EEH_Parse_Shortcodes $shortcode_parser
99
+	) {
100
+		$this->_generation_queue        = $generation_queue;
101
+		$this->_ready_queue             = $ready_queue;
102
+		$this->_data_handler_collection = $data_handler_collection;
103
+		$this->_template_collection     = $template_collection;
104
+		$this->_shortcode_parser        = $shortcode_parser;
105
+	}
106
+
107
+
108
+	/**
109
+	 * @return EE_Messages_Queue
110
+	 */
111
+	public function generation_queue()
112
+	{
113
+		return $this->_generation_queue;
114
+	}
115
+
116
+
117
+	/**
118
+	 *  This iterates through the provided queue and generates the EE_Message objects.
119
+	 *  When iterating through the queue, the queued item that served as the base for generating other EE_Message
120
+	 *  objects gets removed and the new EE_Message objects get added to a NEW queue.  The NEW queue is then returned
121
+	 *  for the caller to decide what to do with it.
122
+	 *
123
+	 * @param   bool $save Whether to save the EE_Message objects in the new queue or just return.
124
+	 * @return EE_Messages_Queue The new queue for holding generated EE_Message objects.
125
+	 * @throws EE_Error
126
+	 * @throws InvalidArgumentException
127
+	 * @throws InvalidDataTypeException
128
+	 * @throws InvalidInterfaceException
129
+	 * @throws ReflectionException
130
+	 */
131
+	public function generate($save = true)
132
+	{
133
+		// iterate through the messages in the queue, generate, and add to new queue.
134
+		$this->_generation_queue->get_message_repository()->rewind();
135
+		while ($this->_generation_queue->get_message_repository()->valid()) {
136
+			// reset "current" properties
137
+			$this->_reset_current_properties();
138
+
139
+			/** @type EE_Message $msg */
140
+			$msg = $this->_generation_queue->get_message_repository()->current();
141
+
142
+			/**
143
+			 * need to get the next object and capture it for setting manually after deletes.  The reason is that when
144
+			 * an object is removed from the repo then valid for the next object will fail.
145
+			 */
146
+			$this->_generation_queue->get_message_repository()->next();
147
+			$next_msg = $this->_generation_queue->get_message_repository()->current();
148
+			// restore pointer to current item
149
+			$this->_generation_queue->get_message_repository()->set_current($msg);
150
+
151
+			// skip and delete if the current $msg is NOT incomplete (queued for generation)
152
+			if ($msg->STS_ID() !== EEM_Message::status_incomplete) {
153
+				// we keep this item in the db just remove from the repo.
154
+				$this->_generation_queue->get_message_repository()->remove($msg);
155
+				// next item
156
+				$this->_generation_queue->get_message_repository()->set_current($next_msg);
157
+				continue;
158
+			}
159
+
160
+			if ($this->_verify()) {
161
+				// let's get generating!
162
+				$this->_generate();
163
+			}
164
+
165
+			// don't persist debug_only messages if the messages system is not in debug mode.
166
+			if (
167
+				$msg->STS_ID() === EEM_Message::status_debug_only
168
+				&& ! EEM_Message::debug()
169
+			) {
170
+				do_action(
171
+					'AHEE__EE_Messages_Generator__generate__before_debug_delete',
172
+					$msg,
173
+					$this->_error_msg,
174
+					$this->_current_messenger,
175
+					$this->_current_message_type,
176
+					$this->_current_data_handler
177
+				);
178
+				$this->_generation_queue->get_message_repository()->delete();
179
+				$this->_generation_queue->get_message_repository()->set_current($next_msg);
180
+				continue;
181
+			}
182
+
183
+			// if there are error messages then let's set the status and the error message.
184
+			if ($this->_error_msg) {
185
+				// if the status is already debug only, then let's leave it at that.
186
+				if ($msg->STS_ID() !== EEM_Message::status_debug_only) {
187
+					$msg->set_STS_ID(EEM_Message::status_failed);
188
+				}
189
+				do_action(
190
+					'AHEE__EE_Messages_Generator__generate__processing_failed_message',
191
+					$msg,
192
+					$this->_error_msg,
193
+					$this->_current_messenger,
194
+					$this->_current_message_type,
195
+					$this->_current_data_handler
196
+				);
197
+				$msg->set_error_message(
198
+					esc_html__('Message failed to generate for the following reasons: ', 'event_espresso')
199
+					. "\n"
200
+					. implode("\n", $this->_error_msg)
201
+				);
202
+				$msg->set_modified(time());
203
+			} else {
204
+				do_action(
205
+					'AHEE__EE_Messages_Generator__generate__before_successful_generated_message_delete',
206
+					$msg,
207
+					$this->_error_msg,
208
+					$this->_current_messenger,
209
+					$this->_current_message_type,
210
+					$this->_current_data_handler
211
+				);
212
+				// remove from db
213
+				$this->_generation_queue->get_message_repository()->delete();
214
+			}
215
+			// next item
216
+			$this->_generation_queue->get_message_repository()->set_current($next_msg);
217
+		}
218
+
219
+		// generation queue is ALWAYS saved to record any errors in the generation process.
220
+		$this->_generation_queue->save();
221
+
222
+		/**
223
+		 * save _ready_queue if flag set.
224
+		 * Note: The EE_Message objects have values set via the EE_Base_Class::set_field_or_extra_meta() method.  This
225
+		 * means if a field was added that is not a valid database column.  The EE_Message was already saved to the db
226
+		 * so a EE_Extra_Meta entry could be created and attached to the EE_Message.  In those cases the save flag is
227
+		 * irrelevant.
228
+		 */
229
+		if ($save) {
230
+			$this->_ready_queue->save();
231
+		}
232
+
233
+		// final reset of properties
234
+		$this->_reset_current_properties();
235
+
236
+		return $this->_ready_queue;
237
+	}
238
+
239
+
240
+	/**
241
+	 * This resets all the properties used for holding "current" values corresponding to the current EE_Message object
242
+	 * in the generation queue.
243
+	 */
244
+	protected function _reset_current_properties()
245
+	{
246
+		$this->_verified = false;
247
+		// make sure any _data value in the current message type is reset
248
+		if ($this->_current_message_type instanceof EE_message_type) {
249
+			$this->_current_message_type->reset_data();
250
+		}
251
+		$this->_current_messenger = $this->_current_message_type = $this->_current_data_handler = null;
252
+	}
253
+
254
+
255
+	/**
256
+	 * This proceeds with the actual generation of a message.  By the time this is called, there should already be a
257
+	 * $_current_data_handler set and all incoming information should be validated for the current EE_Message in the
258
+	 * _generating_queue.
259
+	 *
260
+	 * @return bool Whether the message was successfully generated or not.
261
+	 * @throws EE_Error
262
+	 * @throws InvalidArgumentException
263
+	 * @throws InvalidDataTypeException
264
+	 * @throws InvalidInterfaceException
265
+	 * @throws ReflectionException
266
+	 */
267
+	protected function _generate()
268
+	{
269
+		// double check verification has run and that everything is ready to work with (saves us having to validate
270
+		// everything again).
271
+		if (! $this->_verified) {
272
+			return false; // get out because we don't have a valid setup to work with.
273
+		}
274
+
275
+
276
+		try {
277
+			$addressees = $this->_current_message_type->get_addressees(
278
+				$this->_current_data_handler,
279
+				$this->_generation_queue->get_message_repository()->current()->context()
280
+			);
281
+		} catch (EE_Error $e) {
282
+			$this->_error_msg[] = $e->getMessage();
283
+			return false;
284
+		}
285
+
286
+
287
+		// if no addressees then get out because there is nothing to generation (possible bad data).
288
+		if (! $this->_valid_addressees($addressees)) {
289
+			do_action(
290
+				'AHEE__EE_Messages_Generator___generate__invalid_addressees',
291
+				$this->_generation_queue->get_message_repository()->current(),
292
+				$addressees,
293
+				$this->_current_messenger,
294
+				$this->_current_message_type,
295
+				$this->_current_data_handler
296
+			);
297
+			$this->_generation_queue->get_message_repository()->current()->set_STS_ID(
298
+				EEM_Message::status_debug_only
299
+			);
300
+			$this->_error_msg[] = esc_html__(
301
+				'This is not a critical error but an informational notice. Unable to generate messages EE_Messages_Addressee objects.  There were no attendees prepared by the data handler. Sometimes this is because messages only get generated for certain registration statuses. For example, the ticket notice message type only goes to approved registrations.',
302
+				'event_espresso'
303
+			);
304
+			return false;
305
+		}
306
+
307
+		$message_template_group = $this->_get_message_template_group();
308
+
309
+		// in the unlikely event there is no EE_Message_Template_Group available, get out!
310
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
311
+			$this->_error_msg[] = esc_html__(
312
+				'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
313
+				'event_espresso'
314
+			);
315
+			return false;
316
+		}
317
+
318
+		// get formatted templates for using to parse and setup EE_Message objects.
319
+		$templates = $this->_get_templates($message_template_group);
320
+
321
+
322
+		// setup new EE_Message objects (and add to _ready_queue)
323
+		return $this->_assemble_messages($addressees, $templates, $message_template_group);
324
+	}
325
+
326
+
327
+	/**
328
+	 * Retrieves the message template group being used for generating messages.
329
+	 * Note: this also utilizes the EE_Message_Template_Group_Collection to avoid having to hit the db multiple times.
330
+	 *
331
+	 * @return EE_Message_Template_Group|null
332
+	 * @throws EE_Error
333
+	 * @throws InvalidArgumentException
334
+	 * @throws InvalidDataTypeException
335
+	 * @throws InvalidInterfaceException
336
+	 * @throws ReflectionException
337
+	 */
338
+	protected function _get_message_template_group()
339
+	{
340
+		// first see if there is a specific message template group requested (current message in the queue has a
341
+		// specific GRP_ID
342
+		$message_template_group = $this->_specific_message_template_group_from_queue();
343
+		if ($message_template_group instanceof EE_Message_Template_Group) {
344
+			return $message_template_group;
345
+		}
346
+
347
+		// get event_ids from the datahandler so we can check to see if there's already a message template group for
348
+		// them in the collection.
349
+		$event_ids              = $this->_get_event_ids_from_current_data_handler();
350
+		$message_template_group = $this->_template_collection->get_by_key(
351
+			$this->_template_collection->getKey(
352
+				$this->_current_messenger->name,
353
+				$this->_current_message_type->name,
354
+				$event_ids
355
+			)
356
+		);
357
+
358
+		// if we have a message template group then no need to hit the database, just return it.
359
+		if ($message_template_group instanceof EE_Message_Template_Group) {
360
+			return $message_template_group;
361
+		}
362
+
363
+		// okay made it here, so let's get the global group first for this messenger and message type to ensure
364
+		// there is no override set.
365
+		$global_message_template_group =
366
+			$this->_get_global_message_template_group_for_current_messenger_and_message_type();
367
+
368
+		if (
369
+			$global_message_template_group instanceof EE_Message_Template_Group
370
+			&& $global_message_template_group->get('MTP_is_override')
371
+		) {
372
+			return $global_message_template_group;
373
+		}
374
+
375
+		// if we're still here, that means there was no message template group for the events in the collection and
376
+		// the global message template group for the messenger and message type is not set for override.  So next step
377
+		// is to see if there is a common shared custom message template group for this set of events.
378
+		$message_template_group = $this->_get_shared_message_template_for_events($event_ids);
379
+		if ($message_template_group instanceof EE_Message_Template_Group) {
380
+			return $message_template_group;
381
+		}
382
+
383
+		// STILL here?  Okay that means the fallback is to just use the global message template group for this event
384
+		// set. So we'll cache the global group for this event set (so this logic doesn't have to be repeated in this
385
+		// request) and return it.
386
+		if ($global_message_template_group instanceof EE_Message_Template_Group) {
387
+			$this->_template_collection->add(
388
+				$global_message_template_group,
389
+				$event_ids
390
+			);
391
+			return $global_message_template_group;
392
+		}
393
+
394
+		// if we land here that means there's NO active message template group for this set.
395
+		// TODO this will be a good target for some optimization down the road.  Whenever there is no active message
396
+		// template group for a given event set then cache that result so we don't repeat the logic.  However, for now,
397
+		// this should likely bit hit rarely enough that it's not a significant issue.
398
+		return null;
399
+	}
400
+
401
+
402
+	/**
403
+	 * This checks the current message in the queue and determines if there is a specific Message Template Group
404
+	 * requested for that message.
405
+	 *
406
+	 * @return EE_Message_Template_Group|null
407
+	 * @throws EE_Error
408
+	 * @throws InvalidArgumentException
409
+	 * @throws InvalidDataTypeException
410
+	 * @throws InvalidInterfaceException
411
+	 */
412
+	protected function _specific_message_template_group_from_queue()
413
+	{
414
+		// is there a GRP_ID already on the EE_Message object?  If there is, then a specific template has been requested
415
+		// so let's use that.
416
+		$GRP_ID = $this->_generation_queue->get_message_repository()->current()->GRP_ID();
417
+
418
+		if ($GRP_ID) {
419
+			// attempt to retrieve from repo first
420
+			$message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
421
+			if ($message_template_group instanceof EE_Message_Template_Group) {
422
+				return $message_template_group;  // got it!
423
+			}
424
+
425
+			// nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
426
+			// is not valid, so we'll continue on in the code assuming there's NO GRP_ID.
427
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one_by_ID($GRP_ID);
428
+			if ($message_template_group instanceof EE_Message_Template_Group) {
429
+				$this->_template_collection->add($message_template_group);
430
+				return $message_template_group;
431
+			}
432
+		}
433
+		return null;
434
+	}
435
+
436
+
437
+	/**
438
+	 * Returns whether the event ids passed in all share the same message template group for the current message type
439
+	 * and messenger.
440
+	 *
441
+	 * @param array $event_ids
442
+	 * @return bool true means they DO share the same message template group, false means they don't.
443
+	 * @throws EE_Error
444
+	 * @throws InvalidArgumentException
445
+	 * @throws InvalidDataTypeException
446
+	 * @throws InvalidInterfaceException
447
+	 */
448
+	protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
449
+	{
450
+		foreach ($this->_current_data_handler->events as $event) {
451
+			$event_ids[ $event['ID'] ] = $event['ID'];
452
+		}
453
+		$count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
454
+			array(
455
+				array(
456
+					'Event.EVT_ID'           => array('IN', $event_ids),
457
+					'MTP_messenger'    => $this->_current_messenger->name,
458
+					'MTP_message_type' => $this->_current_message_type->name,
459
+				),
460
+			),
461
+			'GRP_ID',
462
+			true
463
+		);
464
+		return $count_of_message_template_groups === 1;
465
+	}
466
+
467
+
468
+	/**
469
+	 * This will get the shared message template group for events that are in the current data handler but ONLY if
470
+	 * there's a single shared message template group among all the events.  Otherwise it returns null.
471
+	 *
472
+	 * @param array $event_ids
473
+	 * @return EE_Message_Template_Group|null
474
+	 * @throws EE_Error
475
+	 * @throws InvalidArgumentException
476
+	 * @throws InvalidDataTypeException
477
+	 * @throws InvalidInterfaceException
478
+	 */
479
+	protected function _get_shared_message_template_for_events(array $event_ids)
480
+	{
481
+		$message_template_group = null;
482
+		if ($this->_queue_shares_same_message_template_group_for_events($event_ids)) {
483
+			$message_template_group = EEM_Message_Template_Group::instance()->get_one(
484
+				array(
485
+					array(
486
+						'Event.EVT_ID'           => array('IN', $event_ids),
487
+						'MTP_messenger'    => $this->_current_messenger->name,
488
+						'MTP_message_type' => $this->_current_message_type->name,
489
+						'MTP_is_active'    => true,
490
+					),
491
+					'group_by' => 'GRP_ID',
492
+				)
493
+			);
494
+			// store this in the collection if its valid
495
+			if ($message_template_group instanceof EE_Message_Template_Group) {
496
+				$this->_template_collection->add(
497
+					$message_template_group,
498
+					$event_ids
499
+				);
500
+			}
501
+		}
502
+		return $message_template_group;
503
+	}
504
+
505
+
506
+	/**
507
+	 * Retrieves the global message template group for the current messenger and message type.
508
+	 *
509
+	 * @return EE_Message_Template_Group|null
510
+	 * @throws EE_Error
511
+	 * @throws InvalidArgumentException
512
+	 * @throws InvalidDataTypeException
513
+	 * @throws InvalidInterfaceException
514
+	 */
515
+	protected function _get_global_message_template_group_for_current_messenger_and_message_type()
516
+	{
517
+		// first check the collection (we use an array with 0 in it to represent global groups).
518
+		$global_message_template_group = $this->_template_collection->get_by_key(
519
+			$this->_template_collection->getKey(
520
+				$this->_current_messenger->name,
521
+				$this->_current_message_type->name,
522
+				array(0)
523
+			)
524
+		);
525
+
526
+		// if we don't have a group lets hit the db.
527
+		if (! $global_message_template_group instanceof EE_Message_Template_Group) {
528
+			$global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
529
+				array(
530
+					array(
531
+						'MTP_messenger'    => $this->_current_messenger->name,
532
+						'MTP_message_type' => $this->_current_message_type->name,
533
+						'MTP_is_active'    => true,
534
+						'MTP_is_global'    => true,
535
+					),
536
+				)
537
+			);
538
+			// if we have a group, add it to the collection.
539
+			if ($global_message_template_group instanceof EE_Message_Template_Group) {
540
+				$this->_template_collection->add(
541
+					$global_message_template_group,
542
+					array(0)
543
+				);
544
+			}
545
+		}
546
+		return $global_message_template_group;
547
+	}
548
+
549
+
550
+	/**
551
+	 * Returns an array of event ids for all the events within the current data handler.
552
+	 *
553
+	 * @return array
554
+	 */
555
+	protected function _get_event_ids_from_current_data_handler()
556
+	{
557
+		$event_ids = array();
558
+		foreach ($this->_current_data_handler->events as $event) {
559
+			$event_ids[ $event['ID'] ] = $event['ID'];
560
+		}
561
+		return $event_ids;
562
+	}
563
+
564
+
565
+	/**
566
+	 *  Retrieves formatted array of template information for each context specific to the given
567
+	 *  EE_Message_Template_Group
568
+	 *
569
+	 * @param EE_Message_Template_Group $message_template_group
570
+	 * @return array The returned array is in this structure:
571
+	 *                          array(
572
+	 *                          'field_name' => array(
573
+	 *                          'context' => 'content'
574
+	 *                          )
575
+	 *                          )
576
+	 * @throws EE_Error
577
+	 * @throws InvalidArgumentException
578
+	 * @throws InvalidDataTypeException
579
+	 * @throws InvalidInterfaceException
580
+	 * @throws ReflectionException
581
+	 */
582
+	protected function _get_templates(EE_Message_Template_Group $message_template_group)
583
+	{
584
+		$templates         = array();
585
+		$context_templates = $message_template_group->context_templates();
586
+		foreach ($context_templates as $context => $template_fields) {
587
+			foreach ($template_fields as $template_field => $template_obj) {
588
+				if (! $template_obj instanceof EE_Message_Template) {
589
+					continue;
590
+				}
591
+				$templates[ $template_field ][ $context ] = $template_obj->get('MTP_content');
592
+			}
593
+		}
594
+		return $templates;
595
+	}
596
+
597
+
598
+	/**
599
+	 * Assembles new fully generated EE_Message objects and adds to _ready_queue
600
+	 *
601
+	 * @param array                     $addressees  Array of EE_Messages_Addressee objects indexed by message type
602
+	 *                                               context.
603
+	 * @param array                     $templates   formatted array of templates used for parsing data.
604
+	 * @param EE_Message_Template_Group $message_template_group
605
+	 * @return bool true if message generation went a-ok.  false if some sort of exception occurred.  Note: The
606
+	 *                                               method will attempt to generate ALL EE_Message objects and add to
607
+	 *                                               the _ready_queue.  Successfully generated messages get added to the
608
+	 *                                               queue with EEM_Message::status_idle, unsuccessfully generated
609
+	 *                                               messages will get added to the queue as EEM_Message::status_failed.
610
+	 *                                               Very rarely should "false" be returned from this method.
611
+	 * @throws EE_Error
612
+	 * @throws InvalidArgumentException
613
+	 * @throws InvalidDataTypeException
614
+	 * @throws InvalidIdentifierException
615
+	 * @throws InvalidInterfaceException
616
+	 * @throws ReflectionException
617
+	 */
618
+	protected function _assemble_messages($addressees, $templates, EE_Message_Template_Group $message_template_group)
619
+	{
620
+
621
+		// if templates are empty then get out because we can't generate anything.
622
+		if (! $templates) {
623
+			$this->_error_msg[] = esc_html__(
624
+				'Unable to assemble messages because there are no templates retrieved for generating the messages with',
625
+				'event_espresso'
626
+			);
627
+			return false;
628
+		}
629
+
630
+		// We use this as the counter for generated messages because don't forget we may be executing this inside of a
631
+		// generation_queue.  So _ready_queue may have generated EE_Message objects already.
632
+		$generated_count = 0;
633
+		foreach ($addressees as $context => $recipients) {
634
+			foreach ($recipients as $recipient) {
635
+				$message = $this->_setup_message_object($context, $recipient, $templates, $message_template_group);
636
+				if ($message instanceof EE_Message) {
637
+					$this->_ready_queue->add(
638
+						$message,
639
+						array(),
640
+						$this->_generation_queue->get_message_repository()->is_preview(),
641
+						$this->_generation_queue->get_message_repository()->is_test_send()
642
+					);
643
+					$generated_count++;
644
+				}
645
+
646
+				// if the current MSG being generated is for a test send then we'll only use ONE message in the
647
+				// generation.
648
+				if ($this->_generation_queue->get_message_repository()->is_test_send()) {
649
+					break 2;
650
+				}
651
+			}
652
+		}
653
+
654
+		// if there are no generated messages then something else fatal went wrong.
655
+		return $generated_count > 0;
656
+	}
657
+
658
+
659
+	/**
660
+	 * @param string                    $context   The context for the generated message.
661
+	 * @param EE_Messages_Addressee     $recipient
662
+	 * @param array                     $templates formatted array of templates used for parsing data.
663
+	 * @param EE_Message_Template_Group $message_template_group
664
+	 * @return bool|EE_Message
665
+	 * @throws EE_Error
666
+	 * @throws InvalidArgumentException
667
+	 * @throws InvalidDataTypeException
668
+	 * @throws InvalidInterfaceException
669
+	 * @throws ReflectionException
670
+	 * @throws InvalidIdentifierException
671
+	 */
672
+	protected function _setup_message_object(
673
+		$context,
674
+		EE_Messages_Addressee $recipient,
675
+		$templates,
676
+		EE_Message_Template_Group $message_template_group
677
+	) {
678
+		// stuff we already know
679
+		$transaction_id = $recipient->txn instanceof EE_Transaction ? $recipient->txn->ID() : 0;
680
+		$transaction_id = empty($transaction_id) && $this->_current_data_handler->txn instanceof EE_Transaction
681
+			? $this->_current_data_handler->txn->ID()
682
+			: $transaction_id;
683
+		$message_fields = array(
684
+			'GRP_ID'           => $message_template_group->ID(),
685
+			'TXN_ID'           => $transaction_id,
686
+			'MSG_messenger'    => $this->_current_messenger->name,
687
+			'MSG_message_type' => $this->_current_message_type->name,
688
+			'MSG_context'      => $context,
689
+		);
690
+
691
+		// recipient id and type should be on the EE_Messages_Addressee object but if this is empty, let's try to grab
692
+		// the info from the att_obj found in the EE_Messages_Addressee object.
693
+		if (empty($recipient->recipient_id) || empty($recipient->recipient_type)) {
694
+			$message_fields['MSG_recipient_ID']   = $recipient->att_obj instanceof EE_Attendee
695
+				? $recipient->att_obj->ID()
696
+				: 0;
697
+			$message_fields['MSG_recipient_type'] = 'Attendee';
698
+		} else {
699
+			$message_fields['MSG_recipient_ID']   = $recipient->recipient_id;
700
+			$message_fields['MSG_recipient_type'] = $recipient->recipient_type;
701
+		}
702
+		$message = EE_Message_Factory::create($message_fields);
703
+
704
+		// grab valid shortcodes for shortcode parser
705
+		$mt_shortcodes = $this->_current_message_type->get_valid_shortcodes();
706
+		$m_shortcodes  = $this->_current_messenger->get_valid_shortcodes();
707
+
708
+		// if the 'to' field is empty or the context is inactive we skip EXCEPT if we're previewing
709
+		if (
710
+			! $this->_generation_queue->get_message_repository()->is_preview()
711
+			&& (
712
+							(
713
+								empty($templates['to'][ $context ])
714
+								&& ! $this->_current_messenger->allow_empty_to_field()
715
+							)
716
+							|| ! $message_template_group->is_context_active($context)
717
+						)
718
+		) {
719
+			// we silently exit here and do NOT record a fail because the message is "turned off" by having no "to"
720
+			// field.
721
+			return false;
722
+		}
723
+		$error_msg = array();
724
+		foreach ($templates as $field => $field_context) {
725
+			$error_msg = array();
726
+			// let's setup the valid shortcodes for the incoming context.
727
+			$valid_shortcodes = $mt_shortcodes[ $context ];
728
+			// merge in valid shortcodes for the field.
729
+			$shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes;
730
+			if (isset($templates[ $field ][ $context ])) {
731
+				// prefix field.
732
+				$column_name = 'MSG_' . $field;
733
+				try {
734
+					$content = $this->_shortcode_parser->parse_message_template(
735
+						$templates[ $field ][ $context ],
736
+						$recipient,
737
+						$shortcodes,
738
+						$this->_current_message_type,
739
+						$this->_current_messenger,
740
+						$message
741
+					);
742
+					// the model field removes slashes when setting (usually necessary when the input is from the
743
+					// request) but this value is from another model and has no slashes. So add them so it matchces
744
+					// what the field expected (otherwise slashes will have been stripped from this an extra time)
745
+					$message->set_field_or_extra_meta($column_name, addslashes($content));
746
+				} catch (EE_Error $e) {
747
+					$error_msg[] = sprintf(
748
+						/* Translators: First place holder is message model field name.
749 749
                          * Second placeholder is exception error message */
750
-                        esc_html__(
751
-                            'There was a problem generating the content for the field %s: %s',
752
-                            'event_espresso'
753
-                        ),
754
-                        $field,
755
-                        $e->getMessage()
756
-                    );
757
-                    $message->set_STS_ID(EEM_Message::status_failed);
758
-                }
759
-            }
760
-        }
761
-
762
-        if ($message->STS_ID() === EEM_Message::status_failed) {
763
-            $error_msg = esc_html__('There were problems generating this message:', 'event_espresso')
764
-                         . "\n"
765
-                         . implode("\n", $error_msg);
766
-            $message->set_error_message($error_msg);
767
-        } else {
768
-            $message->set_STS_ID(EEM_Message::status_idle);
769
-        }
770
-        return $message;
771
-    }
772
-
773
-
774
-    /**
775
-     * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate
776
-     * error message if either is missing.
777
-     *
778
-     * @return bool true means there were no errors, false means there were errors.
779
-     */
780
-    protected function _verify()
781
-    {
782
-        // reset error message to an empty array.
783
-        $this->_error_msg = array();
784
-        $valid            = true;
785
-        $valid            = $valid ? $this->_validate_messenger_and_message_type() : $valid;
786
-        $valid            = $valid ? $this->_validate_and_setup_data() : $valid;
787
-
788
-        // set the verified flag so we know everything has been validated.
789
-        $this->_verified = $valid;
790
-
791
-        return $valid;
792
-    }
793
-
794
-
795
-    /**
796
-     * This accepts an array and validates that it is an array indexed by context with each value being an array of
797
-     * EE_Messages_Addressee objects.
798
-     *
799
-     * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[]
800
-     * @return bool
801
-     */
802
-    protected function _valid_addressees($addressees)
803
-    {
804
-        if (! $addressees || ! is_array($addressees)) {
805
-            return false;
806
-        }
807
-
808
-        foreach ($addressees as $addressee_array) {
809
-            foreach ($addressee_array as $addressee) {
810
-                if (! $addressee instanceof EE_Messages_Addressee) {
811
-                    return false;
812
-                }
813
-            }
814
-        }
815
-        return true;
816
-    }
817
-
818
-
819
-    /**
820
-     * This validates the messenger, message type, and presences of generation data for the current EE_Message in the
821
-     * queue. This process sets error messages if something is wrong.
822
-     *
823
-     * @return bool   true is if there are no errors.  false is if there is.
824
-     */
825
-    protected function _validate_messenger_and_message_type()
826
-    {
827
-
828
-        // first are there any existing error messages?  If so then return.
829
-        if ($this->_error_msg) {
830
-            return false;
831
-        }
832
-        /** @type EE_Message $message */
833
-        $message = $this->_generation_queue->get_message_repository()->current();
834
-        try {
835
-            $this->_current_messenger = $message->valid_messenger(true)
836
-                ? $message->messenger_object()
837
-                : null;
838
-        } catch (Exception $e) {
839
-            $this->_error_msg[] = $e->getMessage();
840
-        }
841
-        try {
842
-            $this->_current_message_type = $message->valid_message_type(true)
843
-                ? $message->message_type_object()
844
-                : null;
845
-        } catch (Exception $e) {
846
-            $this->_error_msg[] = $e->getMessage();
847
-        }
848
-
849
-        /**
850
-         * Check if there is any generation data, but only if this is not for a preview.
851
-         */
852
-        if (
853
-            ! $this->_generation_queue->get_message_repository()->get_generation_data()
854
-            && (
855
-                ! $this->_generation_queue->get_message_repository()->is_preview()
856
-                && $this->_generation_queue->get_message_repository()->get_data_handler()
857
-                   !== 'EE_Messages_Preview_incoming_data'
858
-            )
859
-        ) {
860
-            $this->_error_msg[] = esc_html__(
861
-                'There is no generation data for this message. Unable to generate.',
862
-                'event_espresso'
863
-            );
864
-        }
865
-
866
-        return empty($this->_error_msg);
867
-    }
868
-
869
-
870
-    /**
871
-     * This method retrieves the expected data handler for the message type and validates the generation data for that
872
-     * data handler.
873
-     *
874
-     * @return bool true means there are no errors.  false means there were errors (and handler did not get setup).
875
-     */
876
-    protected function _validate_and_setup_data()
877
-    {
878
-
879
-        // First, are there any existing error messages?  If so, return because if there were errors elsewhere this
880
-        // can't be used anyways.
881
-        if ($this->_error_msg) {
882
-            return false;
883
-        }
884
-
885
-        $generation_data = $this->_generation_queue->get_message_repository()->get_generation_data();
886
-
887
-        /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/
888
-        $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
889
-            ? $this->_generation_queue->get_message_repository()->get_data_handler()
890
-            : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
891
-
892
-        // If this EE_Message is for a preview, then let's switch out to the preview data handler.
893
-        if ($this->_generation_queue->get_message_repository()->is_preview()) {
894
-            $data_handler_class_name = 'EE_Messages_Preview_incoming_data';
895
-        }
896
-
897
-        // First get the class name for the data handler (and also verifies it exists.
898
-        if (! class_exists($data_handler_class_name)) {
899
-            $this->_error_msg[] = sprintf(
900
-                /* Translators: Both placeholders are the names of php classes. */
901
-                esc_html__(
902
-                    'The included data handler class name does not match any valid, accessible, "%1$s" classes.  Looking for %2$s.',
903
-                    'event_espresso'
904
-                ),
905
-                'EE_Messages_incoming_data',
906
-                $data_handler_class_name
907
-            );
908
-            return false;
909
-        }
910
-
911
-        // convert generation_data for data_handler_instantiation.
912
-        $generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data);
913
-
914
-        // note, this may set error messages as well.
915
-        $this->_set_data_handler($generation_data, $data_handler_class_name);
916
-
917
-        return empty($this->_error_msg);
918
-    }
919
-
920
-
921
-    /**
922
-     * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and
923
-     * adds it to the _data repository.
924
-     *
925
-     * @param mixed  $generating_data           This is data expected by the instantiated data handler.
926
-     * @param string $data_handler_class_name   This is the reference string indicating what data handler is being
927
-     *                                          instantiated.
928
-     */
929
-    protected function _set_data_handler($generating_data, $data_handler_class_name)
930
-    {
931
-        // valid classname for the data handler.  Now let's setup the key for the data handler repository to see if
932
-        // there is already a ready data handler in the repository.
933
-        $this->_current_data_handler = $this->_data_handler_collection->get_by_key(
934
-            $this->_data_handler_collection->get_key(
935
-                $data_handler_class_name,
936
-                $generating_data
937
-            )
938
-        );
939
-        if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
940
-            // no saved data_handler in the repo so let's set one up and add it to the repo.
941
-            try {
942
-                $this->_current_data_handler = new $data_handler_class_name($generating_data);
943
-                $this->_data_handler_collection->add($this->_current_data_handler, $generating_data);
944
-            } catch (Exception $e) {
945
-                $this->_error_msg[] = $e->getMessage();
946
-            }
947
-        }
948
-    }
949
-
950
-
951
-    /**
952
-     * The queued EE_Message for generation does not save the data used for generation as objects
953
-     * because serialization of those objects could be problematic if the data is saved to the db.
954
-     * So this method calls the static method on the associated data_handler for the given message_type
955
-     * and that preps the data for later instantiation when generating.
956
-     *
957
-     * @param EE_Message_To_Generate $message_to_generate
958
-     * @param bool                   $preview Indicate whether this is being used for a preview or not.
959
-     * @return mixed Prepped data for persisting to the queue.  false is returned if unable to prep data.
960
-     */
961
-    protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
962
-    {
963
-        /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
964
-        $data_handler = $message_to_generate->get_data_handler_class_name($preview);
965
-        if (! $message_to_generate->valid()) {
966
-            return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid.
967
-        }
968
-        return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
969
-    }
970
-
971
-
972
-    /**
973
-     * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue.
974
-     *
975
-     * @param EE_Message_To_Generate $message_to_generate
976
-     * @param bool                   $test_send Whether this is just a test send or not.  Typically used for previews.
977
-     * @throws InvalidArgumentException
978
-     * @throws InvalidDataTypeException
979
-     * @throws InvalidInterfaceException
980
-     */
981
-    public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false)
982
-    {
983
-        // prep data
984
-        $data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview());
985
-        $request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
986
-
987
-        $message = $message_to_generate->get_EE_Message();
988
-        $GRP_ID = $request->getRequestParam('GRP_ID', 0);
989
-
990
-        $GRP_ID = apply_filters(
991
-            'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID',
992
-            $GRP_ID > 0 ? $GRP_ID : $message->GRP_ID(),
993
-            $message,
994
-            $message_to_generate,
995
-            $test_send
996
-        );
997
-
998
-        if ($GRP_ID > 0) {
999
-            $message->set_GRP_ID($GRP_ID);
1000
-        }
1001
-
1002
-        if ($data === false) {
1003
-            $message->set_STS_ID(EEM_Message::status_failed);
1004
-            $message->set_error_message(
1005
-                esc_html__(
1006
-                    'Unable to prepare data for persistence to the database.',
1007
-                    'event_espresso'
1008
-                )
1009
-            );
1010
-        } else {
1011
-            // make sure that the data handler is cached on the message as well
1012
-            $data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name();
1013
-        }
1014
-
1015
-        $this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send);
1016
-    }
750
+						esc_html__(
751
+							'There was a problem generating the content for the field %s: %s',
752
+							'event_espresso'
753
+						),
754
+						$field,
755
+						$e->getMessage()
756
+					);
757
+					$message->set_STS_ID(EEM_Message::status_failed);
758
+				}
759
+			}
760
+		}
761
+
762
+		if ($message->STS_ID() === EEM_Message::status_failed) {
763
+			$error_msg = esc_html__('There were problems generating this message:', 'event_espresso')
764
+						 . "\n"
765
+						 . implode("\n", $error_msg);
766
+			$message->set_error_message($error_msg);
767
+		} else {
768
+			$message->set_STS_ID(EEM_Message::status_idle);
769
+		}
770
+		return $message;
771
+	}
772
+
773
+
774
+	/**
775
+	 * This verifies that the incoming array has a EE_messenger object and a EE_message_type object and sets appropriate
776
+	 * error message if either is missing.
777
+	 *
778
+	 * @return bool true means there were no errors, false means there were errors.
779
+	 */
780
+	protected function _verify()
781
+	{
782
+		// reset error message to an empty array.
783
+		$this->_error_msg = array();
784
+		$valid            = true;
785
+		$valid            = $valid ? $this->_validate_messenger_and_message_type() : $valid;
786
+		$valid            = $valid ? $this->_validate_and_setup_data() : $valid;
787
+
788
+		// set the verified flag so we know everything has been validated.
789
+		$this->_verified = $valid;
790
+
791
+		return $valid;
792
+	}
793
+
794
+
795
+	/**
796
+	 * This accepts an array and validates that it is an array indexed by context with each value being an array of
797
+	 * EE_Messages_Addressee objects.
798
+	 *
799
+	 * @param array $addressees Keys correspond to contexts for the message type and values are EE_Messages_Addressee[]
800
+	 * @return bool
801
+	 */
802
+	protected function _valid_addressees($addressees)
803
+	{
804
+		if (! $addressees || ! is_array($addressees)) {
805
+			return false;
806
+		}
807
+
808
+		foreach ($addressees as $addressee_array) {
809
+			foreach ($addressee_array as $addressee) {
810
+				if (! $addressee instanceof EE_Messages_Addressee) {
811
+					return false;
812
+				}
813
+			}
814
+		}
815
+		return true;
816
+	}
817
+
818
+
819
+	/**
820
+	 * This validates the messenger, message type, and presences of generation data for the current EE_Message in the
821
+	 * queue. This process sets error messages if something is wrong.
822
+	 *
823
+	 * @return bool   true is if there are no errors.  false is if there is.
824
+	 */
825
+	protected function _validate_messenger_and_message_type()
826
+	{
827
+
828
+		// first are there any existing error messages?  If so then return.
829
+		if ($this->_error_msg) {
830
+			return false;
831
+		}
832
+		/** @type EE_Message $message */
833
+		$message = $this->_generation_queue->get_message_repository()->current();
834
+		try {
835
+			$this->_current_messenger = $message->valid_messenger(true)
836
+				? $message->messenger_object()
837
+				: null;
838
+		} catch (Exception $e) {
839
+			$this->_error_msg[] = $e->getMessage();
840
+		}
841
+		try {
842
+			$this->_current_message_type = $message->valid_message_type(true)
843
+				? $message->message_type_object()
844
+				: null;
845
+		} catch (Exception $e) {
846
+			$this->_error_msg[] = $e->getMessage();
847
+		}
848
+
849
+		/**
850
+		 * Check if there is any generation data, but only if this is not for a preview.
851
+		 */
852
+		if (
853
+			! $this->_generation_queue->get_message_repository()->get_generation_data()
854
+			&& (
855
+				! $this->_generation_queue->get_message_repository()->is_preview()
856
+				&& $this->_generation_queue->get_message_repository()->get_data_handler()
857
+				   !== 'EE_Messages_Preview_incoming_data'
858
+			)
859
+		) {
860
+			$this->_error_msg[] = esc_html__(
861
+				'There is no generation data for this message. Unable to generate.',
862
+				'event_espresso'
863
+			);
864
+		}
865
+
866
+		return empty($this->_error_msg);
867
+	}
868
+
869
+
870
+	/**
871
+	 * This method retrieves the expected data handler for the message type and validates the generation data for that
872
+	 * data handler.
873
+	 *
874
+	 * @return bool true means there are no errors.  false means there were errors (and handler did not get setup).
875
+	 */
876
+	protected function _validate_and_setup_data()
877
+	{
878
+
879
+		// First, are there any existing error messages?  If so, return because if there were errors elsewhere this
880
+		// can't be used anyways.
881
+		if ($this->_error_msg) {
882
+			return false;
883
+		}
884
+
885
+		$generation_data = $this->_generation_queue->get_message_repository()->get_generation_data();
886
+
887
+		/** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/
888
+		$data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
889
+			? $this->_generation_queue->get_message_repository()->get_data_handler()
890
+			: 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
891
+
892
+		// If this EE_Message is for a preview, then let's switch out to the preview data handler.
893
+		if ($this->_generation_queue->get_message_repository()->is_preview()) {
894
+			$data_handler_class_name = 'EE_Messages_Preview_incoming_data';
895
+		}
896
+
897
+		// First get the class name for the data handler (and also verifies it exists.
898
+		if (! class_exists($data_handler_class_name)) {
899
+			$this->_error_msg[] = sprintf(
900
+				/* Translators: Both placeholders are the names of php classes. */
901
+				esc_html__(
902
+					'The included data handler class name does not match any valid, accessible, "%1$s" classes.  Looking for %2$s.',
903
+					'event_espresso'
904
+				),
905
+				'EE_Messages_incoming_data',
906
+				$data_handler_class_name
907
+			);
908
+			return false;
909
+		}
910
+
911
+		// convert generation_data for data_handler_instantiation.
912
+		$generation_data = $data_handler_class_name::convert_data_from_persistent_storage($generation_data);
913
+
914
+		// note, this may set error messages as well.
915
+		$this->_set_data_handler($generation_data, $data_handler_class_name);
916
+
917
+		return empty($this->_error_msg);
918
+	}
919
+
920
+
921
+	/**
922
+	 * Sets the $_current_data_handler property that is used for generating the current EE_Message in the queue, and
923
+	 * adds it to the _data repository.
924
+	 *
925
+	 * @param mixed  $generating_data           This is data expected by the instantiated data handler.
926
+	 * @param string $data_handler_class_name   This is the reference string indicating what data handler is being
927
+	 *                                          instantiated.
928
+	 */
929
+	protected function _set_data_handler($generating_data, $data_handler_class_name)
930
+	{
931
+		// valid classname for the data handler.  Now let's setup the key for the data handler repository to see if
932
+		// there is already a ready data handler in the repository.
933
+		$this->_current_data_handler = $this->_data_handler_collection->get_by_key(
934
+			$this->_data_handler_collection->get_key(
935
+				$data_handler_class_name,
936
+				$generating_data
937
+			)
938
+		);
939
+		if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
940
+			// no saved data_handler in the repo so let's set one up and add it to the repo.
941
+			try {
942
+				$this->_current_data_handler = new $data_handler_class_name($generating_data);
943
+				$this->_data_handler_collection->add($this->_current_data_handler, $generating_data);
944
+			} catch (Exception $e) {
945
+				$this->_error_msg[] = $e->getMessage();
946
+			}
947
+		}
948
+	}
949
+
950
+
951
+	/**
952
+	 * The queued EE_Message for generation does not save the data used for generation as objects
953
+	 * because serialization of those objects could be problematic if the data is saved to the db.
954
+	 * So this method calls the static method on the associated data_handler for the given message_type
955
+	 * and that preps the data for later instantiation when generating.
956
+	 *
957
+	 * @param EE_Message_To_Generate $message_to_generate
958
+	 * @param bool                   $preview Indicate whether this is being used for a preview or not.
959
+	 * @return mixed Prepped data for persisting to the queue.  false is returned if unable to prep data.
960
+	 */
961
+	protected function _prepare_data_for_queue(EE_Message_To_Generate $message_to_generate, $preview)
962
+	{
963
+		/** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
964
+		$data_handler = $message_to_generate->get_data_handler_class_name($preview);
965
+		if (! $message_to_generate->valid()) {
966
+			return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid.
967
+		}
968
+		return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
969
+	}
970
+
971
+
972
+	/**
973
+	 * This sets up a EEM_Message::status_incomplete EE_Message object and adds it to the generation queue.
974
+	 *
975
+	 * @param EE_Message_To_Generate $message_to_generate
976
+	 * @param bool                   $test_send Whether this is just a test send or not.  Typically used for previews.
977
+	 * @throws InvalidArgumentException
978
+	 * @throws InvalidDataTypeException
979
+	 * @throws InvalidInterfaceException
980
+	 */
981
+	public function create_and_add_message_to_queue(EE_Message_To_Generate $message_to_generate, $test_send = false)
982
+	{
983
+		// prep data
984
+		$data = $this->_prepare_data_for_queue($message_to_generate, $message_to_generate->preview());
985
+		$request = LoaderFactory::getLoader()->getShared('EventEspresso\core\services\request\RequestInterface');
986
+
987
+		$message = $message_to_generate->get_EE_Message();
988
+		$GRP_ID = $request->getRequestParam('GRP_ID', 0);
989
+
990
+		$GRP_ID = apply_filters(
991
+			'FHEE__EE_Messages_Generator__create_and_add_message_to_queue_GRP_ID',
992
+			$GRP_ID > 0 ? $GRP_ID : $message->GRP_ID(),
993
+			$message,
994
+			$message_to_generate,
995
+			$test_send
996
+		);
997
+
998
+		if ($GRP_ID > 0) {
999
+			$message->set_GRP_ID($GRP_ID);
1000
+		}
1001
+
1002
+		if ($data === false) {
1003
+			$message->set_STS_ID(EEM_Message::status_failed);
1004
+			$message->set_error_message(
1005
+				esc_html__(
1006
+					'Unable to prepare data for persistence to the database.',
1007
+					'event_espresso'
1008
+				)
1009
+			);
1010
+		} else {
1011
+			// make sure that the data handler is cached on the message as well
1012
+			$data['data_handler_class_name'] = $message_to_generate->get_data_handler_class_name();
1013
+		}
1014
+
1015
+		$this->_generation_queue->add($message, $data, $message_to_generate->preview(), $test_send);
1016
+	}
1017 1017
 }
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
     {
269 269
         // double check verification has run and that everything is ready to work with (saves us having to validate
270 270
         // everything again).
271
-        if (! $this->_verified) {
271
+        if ( ! $this->_verified) {
272 272
             return false; // get out because we don't have a valid setup to work with.
273 273
         }
274 274
 
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
 
286 286
 
287 287
         // if no addressees then get out because there is nothing to generation (possible bad data).
288
-        if (! $this->_valid_addressees($addressees)) {
288
+        if ( ! $this->_valid_addressees($addressees)) {
289 289
             do_action(
290 290
                 'AHEE__EE_Messages_Generator___generate__invalid_addressees',
291 291
                 $this->_generation_queue->get_message_repository()->current(),
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
         $message_template_group = $this->_get_message_template_group();
308 308
 
309 309
         // in the unlikely event there is no EE_Message_Template_Group available, get out!
310
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
310
+        if ( ! $message_template_group instanceof EE_Message_Template_Group) {
311 311
             $this->_error_msg[] = esc_html__(
312 312
                 'Unable to get the Message Templates for the Message being generated.  No message template group accessible.',
313 313
                 'event_espresso'
@@ -419,7 +419,7 @@  discard block
 block discarded – undo
419 419
             // attempt to retrieve from repo first
420 420
             $message_template_group = $this->_template_collection->get_by_ID($GRP_ID);
421 421
             if ($message_template_group instanceof EE_Message_Template_Group) {
422
-                return $message_template_group;  // got it!
422
+                return $message_template_group; // got it!
423 423
             }
424 424
 
425 425
             // nope don't have it yet.  Get from DB then add to repo if its not here, then that means the current GRP_ID
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
     protected function _queue_shares_same_message_template_group_for_events(array $event_ids)
449 449
     {
450 450
         foreach ($this->_current_data_handler->events as $event) {
451
-            $event_ids[ $event['ID'] ] = $event['ID'];
451
+            $event_ids[$event['ID']] = $event['ID'];
452 452
         }
453 453
         $count_of_message_template_groups = EEM_Message_Template_Group::instance()->count(
454 454
             array(
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
         );
525 525
 
526 526
         // if we don't have a group lets hit the db.
527
-        if (! $global_message_template_group instanceof EE_Message_Template_Group) {
527
+        if ( ! $global_message_template_group instanceof EE_Message_Template_Group) {
528 528
             $global_message_template_group = EEM_Message_Template_Group::instance()->get_one(
529 529
                 array(
530 530
                     array(
@@ -556,7 +556,7 @@  discard block
 block discarded – undo
556 556
     {
557 557
         $event_ids = array();
558 558
         foreach ($this->_current_data_handler->events as $event) {
559
-            $event_ids[ $event['ID'] ] = $event['ID'];
559
+            $event_ids[$event['ID']] = $event['ID'];
560 560
         }
561 561
         return $event_ids;
562 562
     }
@@ -585,10 +585,10 @@  discard block
 block discarded – undo
585 585
         $context_templates = $message_template_group->context_templates();
586 586
         foreach ($context_templates as $context => $template_fields) {
587 587
             foreach ($template_fields as $template_field => $template_obj) {
588
-                if (! $template_obj instanceof EE_Message_Template) {
588
+                if ( ! $template_obj instanceof EE_Message_Template) {
589 589
                     continue;
590 590
                 }
591
-                $templates[ $template_field ][ $context ] = $template_obj->get('MTP_content');
591
+                $templates[$template_field][$context] = $template_obj->get('MTP_content');
592 592
             }
593 593
         }
594 594
         return $templates;
@@ -619,7 +619,7 @@  discard block
 block discarded – undo
619 619
     {
620 620
 
621 621
         // if templates are empty then get out because we can't generate anything.
622
-        if (! $templates) {
622
+        if ( ! $templates) {
623 623
             $this->_error_msg[] = esc_html__(
624 624
                 'Unable to assemble messages because there are no templates retrieved for generating the messages with',
625 625
                 'event_espresso'
@@ -710,7 +710,7 @@  discard block
 block discarded – undo
710 710
             ! $this->_generation_queue->get_message_repository()->is_preview()
711 711
             && (
712 712
                             (
713
-                                empty($templates['to'][ $context ])
713
+                                empty($templates['to'][$context])
714 714
                                 && ! $this->_current_messenger->allow_empty_to_field()
715 715
                             )
716 716
                             || ! $message_template_group->is_context_active($context)
@@ -724,15 +724,15 @@  discard block
 block discarded – undo
724 724
         foreach ($templates as $field => $field_context) {
725 725
             $error_msg = array();
726 726
             // let's setup the valid shortcodes for the incoming context.
727
-            $valid_shortcodes = $mt_shortcodes[ $context ];
727
+            $valid_shortcodes = $mt_shortcodes[$context];
728 728
             // merge in valid shortcodes for the field.
729
-            $shortcodes = isset($m_shortcodes[ $field ]) ? $m_shortcodes[ $field ] : $valid_shortcodes;
730
-            if (isset($templates[ $field ][ $context ])) {
729
+            $shortcodes = isset($m_shortcodes[$field]) ? $m_shortcodes[$field] : $valid_shortcodes;
730
+            if (isset($templates[$field][$context])) {
731 731
                 // prefix field.
732
-                $column_name = 'MSG_' . $field;
732
+                $column_name = 'MSG_'.$field;
733 733
                 try {
734 734
                     $content = $this->_shortcode_parser->parse_message_template(
735
-                        $templates[ $field ][ $context ],
735
+                        $templates[$field][$context],
736 736
                         $recipient,
737 737
                         $shortcodes,
738 738
                         $this->_current_message_type,
@@ -801,13 +801,13 @@  discard block
 block discarded – undo
801 801
      */
802 802
     protected function _valid_addressees($addressees)
803 803
     {
804
-        if (! $addressees || ! is_array($addressees)) {
804
+        if ( ! $addressees || ! is_array($addressees)) {
805 805
             return false;
806 806
         }
807 807
 
808 808
         foreach ($addressees as $addressee_array) {
809 809
             foreach ($addressee_array as $addressee) {
810
-                if (! $addressee instanceof EE_Messages_Addressee) {
810
+                if ( ! $addressee instanceof EE_Messages_Addressee) {
811 811
                     return false;
812 812
                 }
813 813
             }
@@ -887,7 +887,7 @@  discard block
 block discarded – undo
887 887
         /** @type EE_Messages_incoming_data $data_handler_class_name - well not really... just the class name actually*/
888 888
         $data_handler_class_name = $this->_generation_queue->get_message_repository()->get_data_handler()
889 889
             ? $this->_generation_queue->get_message_repository()->get_data_handler()
890
-            : 'EE_Messages_' . $this->_current_message_type->get_data_handler($generation_data) . '_incoming_data';
890
+            : 'EE_Messages_'.$this->_current_message_type->get_data_handler($generation_data).'_incoming_data';
891 891
 
892 892
         // If this EE_Message is for a preview, then let's switch out to the preview data handler.
893 893
         if ($this->_generation_queue->get_message_repository()->is_preview()) {
@@ -895,7 +895,7 @@  discard block
 block discarded – undo
895 895
         }
896 896
 
897 897
         // First get the class name for the data handler (and also verifies it exists.
898
-        if (! class_exists($data_handler_class_name)) {
898
+        if ( ! class_exists($data_handler_class_name)) {
899 899
             $this->_error_msg[] = sprintf(
900 900
                 /* Translators: Both placeholders are the names of php classes. */
901 901
                 esc_html__(
@@ -936,7 +936,7 @@  discard block
 block discarded – undo
936 936
                 $generating_data
937 937
             )
938 938
         );
939
-        if (! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
939
+        if ( ! $this->_current_data_handler instanceof EE_Messages_incoming_data) {
940 940
             // no saved data_handler in the repo so let's set one up and add it to the repo.
941 941
             try {
942 942
                 $this->_current_data_handler = new $data_handler_class_name($generating_data);
@@ -962,7 +962,7 @@  discard block
 block discarded – undo
962 962
     {
963 963
         /** @type EE_Messages_incoming_data $data_handler - well not really... just the class name actually */
964 964
         $data_handler = $message_to_generate->get_data_handler_class_name($preview);
965
-        if (! $message_to_generate->valid()) {
965
+        if ( ! $message_to_generate->valid()) {
966 966
             return false; // unable to get the data because the info in the EE_Message_To_Generate class is invalid.
967 967
         }
968 968
         return $data_handler::convert_data_for_persistent_storage($message_to_generate->data());
Please login to merge, or discard this patch.
core/libraries/payment_methods/EE_Payment_Method_Manager.lib.php 2 patches
Indentation   +557 added lines, -557 removed lines patch added patch discarded remove patch
@@ -17,561 +17,561 @@
 block discarded – undo
17 17
 class EE_Payment_Method_Manager implements ResettableInterface
18 18
 {
19 19
 
20
-    /**
21
-     * prefix added to all payment method capabilities names
22
-     */
23
-    const   CAPABILITIES_PREFIX = 'ee_payment_method_';
24
-
25
-    /**
26
-     * @var EE_Payment_Method_Manager $_instance
27
-     */
28
-    private static $_instance;
29
-
30
-    /**
31
-     * @var boolean
32
-     */
33
-    protected $payment_method_caps_initialized = false;
34
-
35
-    /**
36
-     * @var array keys are class names without 'EE_PMT_', values are their filepaths
37
-     */
38
-    protected $_payment_method_types = array();
39
-
40
-    /**
41
-     * @var EE_PMT_Base[]
42
-     */
43
-    protected $payment_method_objects = array();
44
-
45
-
46
-    /**
47
-     * EE_Payment_Method_Manager constructor.
48
-     *
49
-     * @throws EE_Error
50
-     * @throws DomainException
51
-     */
52
-    public function __construct()
53
-    {
54
-        // if in admin lets ensure caps are set.
55
-        if (is_admin()) {
56
-            $this->_register_payment_methods();
57
-            // set them immediately
58
-            $this->initializePaymentMethodCaps();
59
-            // plus any time they get reset
60
-            add_filter(
61
-                'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
62
-                array($this, 'addPaymentMethodCapsDuringReset')
63
-            );
64
-        }
65
-    }
66
-
67
-
68
-    /**
69
-     * @singleton method used to instantiate class object
70
-     * @return EE_Payment_Method_Manager instance
71
-     * @throws DomainException
72
-     * @throws EE_Error
73
-     */
74
-    public static function instance()
75
-    {
76
-        // check if class object is instantiated, and instantiated properly
77
-        if (! self::$_instance instanceof EE_Payment_Method_Manager) {
78
-            EE_Registry::instance()->load_lib('PMT_Base');
79
-            self::$_instance = new self();
80
-        }
81
-        return self::$_instance;
82
-    }
83
-
84
-
85
-    /**
86
-     * Resets the instance and returns a new one
87
-     *
88
-     * @return EE_Payment_Method_Manager
89
-     * @throws DomainException
90
-     * @throws EE_Error
91
-     */
92
-    public static function reset()
93
-    {
94
-        self::$_instance = null;
95
-        return self::instance();
96
-    }
97
-
98
-
99
-    /**
100
-     * If necessary, re-register payment methods
101
-     *
102
-     * @param boolean $force_recheck whether to recheck for payment method types,
103
-     *                               or just re-use the PMTs we found last time we checked during this request (if
104
-     *                               we have not yet checked during this request, then we need to check anyways)
105
-     */
106
-    public function maybe_register_payment_methods($force_recheck = false)
107
-    {
108
-        if (! $this->_payment_method_types || $force_recheck) {
109
-            $this->_register_payment_methods();
110
-        }
111
-    }
112
-
113
-
114
-    /**
115
-     * register_payment_methods
116
-     *
117
-     * @return array
118
-     */
119
-    protected function _register_payment_methods()
120
-    {
121
-        // grab list of installed modules
122
-        $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
123
-        // filter list of modules to register
124
-        $pm_to_register = apply_filters(
125
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
126
-            $pm_to_register
127
-        );
128
-        // remove any duplicates if that should happen for some reason
129
-        $pm_to_register = array_unique($pm_to_register);
130
-        // loop through folders
131
-        foreach ($pm_to_register as $pm_path) {
132
-            $this->register_payment_method($pm_path);
133
-        }
134
-        do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods');
135
-        // filter list of installed modules
136
-        // keep them organized alphabetically by the payment method type's name
137
-        ksort($this->_payment_method_types);
138
-        return apply_filters(
139
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods',
140
-            $this->_payment_method_types
141
-        );
142
-    }
143
-
144
-
145
-    /**
146
-     * register_payment_method- makes core aware of this payment method
147
-     *
148
-     * @param string $payment_method_path - full path up to and including payment method folder
149
-     * @return boolean
150
-     */
151
-    public function register_payment_method($payment_method_path = '')
152
-    {
153
-        do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path);
154
-        $module_ext = '.pm.php';
155
-        // make all separators match
156
-        $payment_method_path = rtrim(str_replace('/\\', '/', $payment_method_path), '/');
157
-        // grab and sanitize module name
158
-        $module_dir = basename($payment_method_path);
159
-        // create class name from module directory name
160
-        $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
161
-        // add class prefix
162
-        $module_class = 'EE_PMT_' . $module;
163
-        // does the module exist ?
164
-        if (! is_readable($payment_method_path . '/' . $module_class . $module_ext)) {
165
-            $msg = sprintf(
166
-                esc_html__(
167
-                    'The requested %s payment method file could not be found or is not readable due to file permissions.',
168
-                    'event_espresso'
169
-                ),
170
-                $module
171
-            );
172
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
173
-            return false;
174
-        }
175
-        // load the module class file
176
-        require_once($payment_method_path . '/' . $module_class . $module_ext);
177
-        // verify that class exists
178
-        if (! class_exists($module_class)) {
179
-            $msg = sprintf(
180
-                esc_html__('The requested %s module class does not exist.', 'event_espresso'),
181
-                $module_class
182
-            );
183
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
184
-            return false;
185
-        }
186
-        // add to array of registered modules
187
-        $this->_payment_method_types[ $module ] = $payment_method_path . '/' . $module_class . $module_ext;
188
-        ksort($this->_payment_method_types);
189
-        return true;
190
-    }
191
-
192
-
193
-    /**
194
-     * Checks if a payment method has been registered, and if so includes it
195
-     *
196
-     * @param string  $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_')
197
-     * @param boolean $force_recheck       whether to force re-checking for new payment method types
198
-     * @return boolean
199
-     */
200
-    public function payment_method_type_exists($payment_method_name, $force_recheck = false)
201
-    {
202
-        if (
203
-            $force_recheck
204
-            || ! is_array($this->_payment_method_types)
205
-            || ! isset($this->_payment_method_types[ $payment_method_name ])
206
-        ) {
207
-            $this->maybe_register_payment_methods($force_recheck);
208
-        }
209
-        if (isset($this->_payment_method_types[ $payment_method_name ])) {
210
-            require_once($this->_payment_method_types[ $payment_method_name ]);
211
-            return true;
212
-        }
213
-        return false;
214
-    }
215
-
216
-
217
-    /**
218
-     * Returns all the class names of the various payment method types
219
-     *
220
-     * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names'
221
-     *                               (what you'd find in wp_esp_payment_method.PMD_type)
222
-     * @param boolean $force_recheck whether to force re-checking for new payment method types
223
-     * @return array
224
-     */
225
-    public function payment_method_type_names($with_prefixes = false, $force_recheck = false)
226
-    {
227
-        $this->maybe_register_payment_methods($force_recheck);
228
-        if ($with_prefixes) {
229
-            $classnames = array_keys($this->_payment_method_types);
230
-            $payment_methods = array();
231
-            foreach ($classnames as $classname) {
232
-                $payment_methods[] = $this->payment_method_class_from_type($classname);
233
-            }
234
-            return $payment_methods;
235
-        }
236
-        return array_keys($this->_payment_method_types);
237
-    }
238
-
239
-
240
-    /**
241
-     * Gets an object of each payment method type, none of which are bound to a
242
-     * payment method instance
243
-     *
244
-     * @param boolean $force_recheck whether to force re-checking for new payment method types
245
-     * @return EE_PMT_Base[]
246
-     */
247
-    public function payment_method_types($force_recheck = false)
248
-    {
249
-        if ($force_recheck || empty($this->payment_method_objects)) {
250
-            $this->maybe_register_payment_methods($force_recheck);
251
-            foreach ($this->payment_method_type_names(true) as $classname) {
252
-                if (! isset($this->payment_method_objects[ $classname ])) {
253
-                    $this->payment_method_objects[ $classname ] = new $classname();
254
-                }
255
-            }
256
-        }
257
-        return $this->payment_method_objects;
258
-    }
259
-
260
-
261
-    /**
262
-     * Changes the payment method's class name into the payment method type's name
263
-     * (as used on the payment method's table's PMD_type field)
264
-     *
265
-     * @param string $classname
266
-     * @return string
267
-     */
268
-    public function payment_method_type_sans_class_prefix($classname)
269
-    {
270
-        return str_replace('EE_PMT_', '', $classname);
271
-    }
272
-
273
-
274
-    /**
275
-     * Does the opposite of payment-method_type_sans_prefix
276
-     *
277
-     * @param string $type
278
-     * @return string
279
-     */
280
-    public function payment_method_class_from_type($type)
281
-    {
282
-        return 'EE_PMT_' . $type;
283
-    }
284
-
285
-
286
-    /**
287
-     * Activates a payment method of the given type.
288
-     *
289
-     * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice'
290
-     * @return EE_Payment_Method
291
-     * @throws InvalidDataTypeException
292
-     * @throws EE_Error
293
-     */
294
-    public function activate_a_payment_method_of_type($payment_method_type)
295
-    {
296
-        $this->maybe_register_payment_methods();
297
-        $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
298
-        if (! $payment_method instanceof EE_Payment_Method) {
299
-            $pm_type_class = $this->payment_method_class_from_type($payment_method_type);
300
-            if (class_exists($pm_type_class)) {
301
-                /** @var $pm_type_obj EE_PMT_Base */
302
-                $pm_type_obj = new $pm_type_class();
303
-                $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
304
-                if (! $payment_method) {
305
-                    $payment_method = $this->create_payment_method_of_type($pm_type_obj);
306
-                }
307
-                $payment_method->set_type($payment_method_type);
308
-                $this->initialize_payment_method($payment_method);
309
-            } else {
310
-                throw new EE_Error(
311
-                    sprintf(
312
-                        esc_html__(
313
-                            'There is no payment method of type %1$s, so it could not be activated',
314
-                            'event_espresso'
315
-                        ),
316
-                        $pm_type_class
317
-                    )
318
-                );
319
-            }
320
-        }
321
-        $payment_method->set_active();
322
-        $payment_method->save();
323
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
324
-        // if this was the invoice message type, make sure users can view their invoices
325
-        if (
326
-            $payment_method->type() === 'Invoice'
327
-            && (
328
-            ! EEH_MSG_Template::is_mt_active('invoice')
329
-            )
330
-        ) {
331
-            $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
332
-            /** @type EE_Message_Resource_Manager $message_resource_manager */
333
-            $message_resource_manager->ensure_message_type_is_active('invoice', 'html');
334
-            new PersistentAdminNotice(
335
-                'invoice_pm_requirements_notice',
336
-                sprintf(
337
-                    esc_html__(
338
-                        'The Invoice payment method has been activated. It requires the %1$sinvoice message%2$s type to be active, so it was automatically activated for you.',
339
-                        'event_espresso'
340
-                    ),
341
-                    '<a href="' . admin_url('admin.php?page=espresso_messages&action=settings') . '">',
342
-                    '</a>'
343
-                ),
344
-                true
345
-            );
346
-        }
347
-        return $payment_method;
348
-    }
349
-
350
-
351
-    /**
352
-     * Creates a payment method of the specified type. Does not save it.
353
-     *
354
-     * @global WP_User    $current_user
355
-     * @param EE_PMT_Base $pm_type_obj
356
-     * @return EE_Payment_Method
357
-     * @throws EE_Error
358
-     */
359
-    public function create_payment_method_of_type($pm_type_obj)
360
-    {
361
-        global $current_user;
362
-        $payment_method = EE_Payment_Method::new_instance(
363
-            array(
364
-                'PMD_type'       => $pm_type_obj->system_name(),
365
-                'PMD_name'       => $pm_type_obj->defaultFrontendName(),
366
-                'PMD_admin_name' => $pm_type_obj->pretty_name(),
367
-                'PMD_slug'       => $pm_type_obj->system_name(),// automatically converted to slug
368
-                'PMD_wp_user'    => $current_user->ID,
369
-                'PMD_order'      => EEM_Payment_Method::instance()->count(
370
-                    array(array('PMD_type' => array('!=', 'Admin_Only')))
371
-                ) * 10,
372
-            )
373
-        );
374
-        return $payment_method;
375
-    }
376
-
377
-
378
-    /**
379
-     * Sets the initial payment method properties (including extra meta)
380
-     *
381
-     * @param EE_Payment_Method $payment_method
382
-     * @return EE_Payment_Method
383
-     * @throws EE_Error
384
-     */
385
-    public function initialize_payment_method($payment_method)
386
-    {
387
-        $pm_type_obj = $payment_method->type_obj();
388
-        $payment_method->set_description($pm_type_obj->default_description());
389
-        if (! $payment_method->button_url()) {
390
-            $payment_method->set_button_url($pm_type_obj->default_button_url());
391
-        }
392
-        // now add setup its default extra meta properties
393
-        $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
394
-        if (! empty($extra_metas)) {
395
-            // verify the payment method has an ID before adding extra meta
396
-            if (! $payment_method->ID()) {
397
-                $payment_method->save();
398
-            }
399
-            foreach ($extra_metas as $meta_name => $input) {
400
-                $payment_method->update_extra_meta($meta_name, $input->raw_value());
401
-            }
402
-        }
403
-        return $payment_method;
404
-    }
405
-
406
-
407
-    /**
408
-     * Makes sure the payment method is related to the specified payment method
409
-     *
410
-     * @deprecated in 4.9.40 because the currency payment method table is being deprecated
411
-     * @param EE_Payment_Method $payment_method
412
-     * @return EE_Payment_Method
413
-     * @throws EE_Error
414
-     */
415
-    public function set_usable_currencies_on_payment_method($payment_method)
416
-    {
417
-        EE_Error::doing_it_wrong(
418
-            'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method',
419
-            esc_html__(
420
-                'We no longer define what currencies are usable by payment methods. Its not used nor efficient.',
421
-                'event_espresso'
422
-            ),
423
-            '4.9.40'
424
-        );
425
-        return $payment_method;
426
-    }
427
-
428
-
429
-    /**
430
-     * Deactivates a payment method of the given payment method slug.
431
-     *
432
-     * @param string $payment_method_slug The slug for the payment method to deactivate.
433
-     * @return int count of rows updated.
434
-     * @throws EE_Error
435
-     */
436
-    public function deactivate_payment_method($payment_method_slug)
437
-    {
438
-        EE_Log::instance()->log(
439
-            __FILE__,
440
-            __FUNCTION__,
441
-            sprintf(
442
-                esc_html__(
443
-                    'Payment method with slug %1$s is being deactivated by site admin',
444
-                    'event_espresso'
445
-                ),
446
-                $payment_method_slug
447
-            ),
448
-            'payment_method_change'
449
-        );
450
-        $count_updated = EEM_Payment_Method::instance()->update(
451
-            array('PMD_scope' => array()),
452
-            array(array('PMD_slug' => $payment_method_slug))
453
-        );
454
-        do_action(
455
-            'AHEE__EE_Payment_Method_Manager__deactivate_payment_method__after_deactivating_payment_method',
456
-            $payment_method_slug,
457
-            $count_updated
458
-        );
459
-        return $count_updated;
460
-    }
461
-
462
-
463
-    /**
464
-     * initializes payment method access caps via EE_Capabilities::init_role_caps()
465
-     * upon EE_Payment_Method_Manager construction
466
-     *
467
-     * @throws EE_Error
468
-     * @throws DomainException
469
-     */
470
-    protected function initializePaymentMethodCaps()
471
-    {
472
-        // don't do this twice
473
-        if ($this->payment_method_caps_initialized) {
474
-            return;
475
-        }
476
-        EE_Capabilities::instance()->addCaps(
477
-            $this->getPaymentMethodCaps()
478
-        );
479
-        $this->payment_method_caps_initialized = true;
480
-    }
481
-
482
-
483
-    /**
484
-     * array  of dynamic payment method access caps.
485
-     * at the time of writing, october 20 2014, these are the caps added:
486
-     *  ee_payment_method_admin_only
487
-     *  ee_payment_method_aim
488
-     *  ee_payment_method_bank
489
-     *  ee_payment_method_check
490
-     *  ee_payment_method_invoice
491
-     *  ee_payment_method_mijireh
492
-     *  ee_payment_method_paypal_pro
493
-     *  ee_payment_method_paypal_standard
494
-     * Any other payment methods added to core or via addons will also get
495
-     * their related capability automatically added too, so long as they are
496
-     * registered properly using EE_Register_Payment_Method::register()
497
-     *
498
-     * @return array
499
-     * @throws DomainException
500
-     */
501
-    protected function getPaymentMethodCaps()
502
-    {
503
-        $caps = array();
504
-        foreach ($this->payment_method_type_names() as $payment_method_name) {
505
-            $caps = $this->addPaymentMethodCap($payment_method_name, $caps);
506
-        }
507
-        return $caps;
508
-    }
509
-
510
-
511
-    /**
512
-     * @param string $payment_method_name
513
-     * @param array  $payment_method_caps
514
-     * @param string $role
515
-     * @return array
516
-     * @throws DomainException
517
-     */
518
-    public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator')
519
-    {
520
-        if (empty($payment_method_name)) {
521
-            throw new DomainException(
522
-                esc_html__(
523
-                    'The name of a payment method must be specified to add capabilities.',
524
-                    'event_espresso'
525
-                )
526
-            );
527
-        }
528
-        if (empty($role)) {
529
-            throw new DomainException(
530
-                sprintf(
531
-                    esc_html__(
532
-                        'No role was supplied while trying to add capabilities for the %1$s payment method.',
533
-                        'event_espresso'
534
-                    ),
535
-                    $payment_method_name
536
-                )
537
-            );
538
-        }
539
-        if (! isset($payment_method_caps[ $role ])) {
540
-            $payment_method_caps[ $role ] = array();
541
-        }
542
-        $payment_method_caps[ $role ][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
543
-                                          . strtolower($payment_method_name);
544
-        return $payment_method_caps;
545
-    }
546
-
547
-
548
-    /**
549
-     * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter
550
-     * to add dynamic payment method access caps when capabilities are reset
551
-     * (or if that filter is called and PM caps are not already set)
552
-     *
553
-     * @param array $caps capabilities being filtered
554
-     * @param bool  $reset
555
-     * @return array
556
-     * @throws DomainException
557
-     */
558
-    public function addPaymentMethodCapsDuringReset(array $caps, $reset = false)
559
-    {
560
-        if ($reset || ! $this->payment_method_caps_initialized) {
561
-            $this->payment_method_caps_initialized = true;
562
-            $caps = array_merge_recursive($caps, $this->getPaymentMethodCaps());
563
-        }
564
-        return $caps;
565
-    }
566
-
567
-
568
-    /**
569
-     * @deprecated 4.9.42
570
-     * @param $caps
571
-     * @return mixed
572
-     */
573
-    public function add_payment_method_caps($caps)
574
-    {
575
-        return $caps;
576
-    }
20
+	/**
21
+	 * prefix added to all payment method capabilities names
22
+	 */
23
+	const   CAPABILITIES_PREFIX = 'ee_payment_method_';
24
+
25
+	/**
26
+	 * @var EE_Payment_Method_Manager $_instance
27
+	 */
28
+	private static $_instance;
29
+
30
+	/**
31
+	 * @var boolean
32
+	 */
33
+	protected $payment_method_caps_initialized = false;
34
+
35
+	/**
36
+	 * @var array keys are class names without 'EE_PMT_', values are their filepaths
37
+	 */
38
+	protected $_payment_method_types = array();
39
+
40
+	/**
41
+	 * @var EE_PMT_Base[]
42
+	 */
43
+	protected $payment_method_objects = array();
44
+
45
+
46
+	/**
47
+	 * EE_Payment_Method_Manager constructor.
48
+	 *
49
+	 * @throws EE_Error
50
+	 * @throws DomainException
51
+	 */
52
+	public function __construct()
53
+	{
54
+		// if in admin lets ensure caps are set.
55
+		if (is_admin()) {
56
+			$this->_register_payment_methods();
57
+			// set them immediately
58
+			$this->initializePaymentMethodCaps();
59
+			// plus any time they get reset
60
+			add_filter(
61
+				'FHEE__EE_Capabilities__addCaps__capabilities_to_add',
62
+				array($this, 'addPaymentMethodCapsDuringReset')
63
+			);
64
+		}
65
+	}
66
+
67
+
68
+	/**
69
+	 * @singleton method used to instantiate class object
70
+	 * @return EE_Payment_Method_Manager instance
71
+	 * @throws DomainException
72
+	 * @throws EE_Error
73
+	 */
74
+	public static function instance()
75
+	{
76
+		// check if class object is instantiated, and instantiated properly
77
+		if (! self::$_instance instanceof EE_Payment_Method_Manager) {
78
+			EE_Registry::instance()->load_lib('PMT_Base');
79
+			self::$_instance = new self();
80
+		}
81
+		return self::$_instance;
82
+	}
83
+
84
+
85
+	/**
86
+	 * Resets the instance and returns a new one
87
+	 *
88
+	 * @return EE_Payment_Method_Manager
89
+	 * @throws DomainException
90
+	 * @throws EE_Error
91
+	 */
92
+	public static function reset()
93
+	{
94
+		self::$_instance = null;
95
+		return self::instance();
96
+	}
97
+
98
+
99
+	/**
100
+	 * If necessary, re-register payment methods
101
+	 *
102
+	 * @param boolean $force_recheck whether to recheck for payment method types,
103
+	 *                               or just re-use the PMTs we found last time we checked during this request (if
104
+	 *                               we have not yet checked during this request, then we need to check anyways)
105
+	 */
106
+	public function maybe_register_payment_methods($force_recheck = false)
107
+	{
108
+		if (! $this->_payment_method_types || $force_recheck) {
109
+			$this->_register_payment_methods();
110
+		}
111
+	}
112
+
113
+
114
+	/**
115
+	 * register_payment_methods
116
+	 *
117
+	 * @return array
118
+	 */
119
+	protected function _register_payment_methods()
120
+	{
121
+		// grab list of installed modules
122
+		$pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
123
+		// filter list of modules to register
124
+		$pm_to_register = apply_filters(
125
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
126
+			$pm_to_register
127
+		);
128
+		// remove any duplicates if that should happen for some reason
129
+		$pm_to_register = array_unique($pm_to_register);
130
+		// loop through folders
131
+		foreach ($pm_to_register as $pm_path) {
132
+			$this->register_payment_method($pm_path);
133
+		}
134
+		do_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods');
135
+		// filter list of installed modules
136
+		// keep them organized alphabetically by the payment method type's name
137
+		ksort($this->_payment_method_types);
138
+		return apply_filters(
139
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__installed_payment_methods',
140
+			$this->_payment_method_types
141
+		);
142
+	}
143
+
144
+
145
+	/**
146
+	 * register_payment_method- makes core aware of this payment method
147
+	 *
148
+	 * @param string $payment_method_path - full path up to and including payment method folder
149
+	 * @return boolean
150
+	 */
151
+	public function register_payment_method($payment_method_path = '')
152
+	{
153
+		do_action('AHEE__EE_Payment_Method_Manager__register_payment_method__begin', $payment_method_path);
154
+		$module_ext = '.pm.php';
155
+		// make all separators match
156
+		$payment_method_path = rtrim(str_replace('/\\', '/', $payment_method_path), '/');
157
+		// grab and sanitize module name
158
+		$module_dir = basename($payment_method_path);
159
+		// create class name from module directory name
160
+		$module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
161
+		// add class prefix
162
+		$module_class = 'EE_PMT_' . $module;
163
+		// does the module exist ?
164
+		if (! is_readable($payment_method_path . '/' . $module_class . $module_ext)) {
165
+			$msg = sprintf(
166
+				esc_html__(
167
+					'The requested %s payment method file could not be found or is not readable due to file permissions.',
168
+					'event_espresso'
169
+				),
170
+				$module
171
+			);
172
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
173
+			return false;
174
+		}
175
+		// load the module class file
176
+		require_once($payment_method_path . '/' . $module_class . $module_ext);
177
+		// verify that class exists
178
+		if (! class_exists($module_class)) {
179
+			$msg = sprintf(
180
+				esc_html__('The requested %s module class does not exist.', 'event_espresso'),
181
+				$module_class
182
+			);
183
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
184
+			return false;
185
+		}
186
+		// add to array of registered modules
187
+		$this->_payment_method_types[ $module ] = $payment_method_path . '/' . $module_class . $module_ext;
188
+		ksort($this->_payment_method_types);
189
+		return true;
190
+	}
191
+
192
+
193
+	/**
194
+	 * Checks if a payment method has been registered, and if so includes it
195
+	 *
196
+	 * @param string  $payment_method_name like 'PayPal_Pro', (ie class name without the prefix 'EEPM_')
197
+	 * @param boolean $force_recheck       whether to force re-checking for new payment method types
198
+	 * @return boolean
199
+	 */
200
+	public function payment_method_type_exists($payment_method_name, $force_recheck = false)
201
+	{
202
+		if (
203
+			$force_recheck
204
+			|| ! is_array($this->_payment_method_types)
205
+			|| ! isset($this->_payment_method_types[ $payment_method_name ])
206
+		) {
207
+			$this->maybe_register_payment_methods($force_recheck);
208
+		}
209
+		if (isset($this->_payment_method_types[ $payment_method_name ])) {
210
+			require_once($this->_payment_method_types[ $payment_method_name ]);
211
+			return true;
212
+		}
213
+		return false;
214
+	}
215
+
216
+
217
+	/**
218
+	 * Returns all the class names of the various payment method types
219
+	 *
220
+	 * @param boolean $with_prefixes TRUE: get payment method type class names; false just their 'names'
221
+	 *                               (what you'd find in wp_esp_payment_method.PMD_type)
222
+	 * @param boolean $force_recheck whether to force re-checking for new payment method types
223
+	 * @return array
224
+	 */
225
+	public function payment_method_type_names($with_prefixes = false, $force_recheck = false)
226
+	{
227
+		$this->maybe_register_payment_methods($force_recheck);
228
+		if ($with_prefixes) {
229
+			$classnames = array_keys($this->_payment_method_types);
230
+			$payment_methods = array();
231
+			foreach ($classnames as $classname) {
232
+				$payment_methods[] = $this->payment_method_class_from_type($classname);
233
+			}
234
+			return $payment_methods;
235
+		}
236
+		return array_keys($this->_payment_method_types);
237
+	}
238
+
239
+
240
+	/**
241
+	 * Gets an object of each payment method type, none of which are bound to a
242
+	 * payment method instance
243
+	 *
244
+	 * @param boolean $force_recheck whether to force re-checking for new payment method types
245
+	 * @return EE_PMT_Base[]
246
+	 */
247
+	public function payment_method_types($force_recheck = false)
248
+	{
249
+		if ($force_recheck || empty($this->payment_method_objects)) {
250
+			$this->maybe_register_payment_methods($force_recheck);
251
+			foreach ($this->payment_method_type_names(true) as $classname) {
252
+				if (! isset($this->payment_method_objects[ $classname ])) {
253
+					$this->payment_method_objects[ $classname ] = new $classname();
254
+				}
255
+			}
256
+		}
257
+		return $this->payment_method_objects;
258
+	}
259
+
260
+
261
+	/**
262
+	 * Changes the payment method's class name into the payment method type's name
263
+	 * (as used on the payment method's table's PMD_type field)
264
+	 *
265
+	 * @param string $classname
266
+	 * @return string
267
+	 */
268
+	public function payment_method_type_sans_class_prefix($classname)
269
+	{
270
+		return str_replace('EE_PMT_', '', $classname);
271
+	}
272
+
273
+
274
+	/**
275
+	 * Does the opposite of payment-method_type_sans_prefix
276
+	 *
277
+	 * @param string $type
278
+	 * @return string
279
+	 */
280
+	public function payment_method_class_from_type($type)
281
+	{
282
+		return 'EE_PMT_' . $type;
283
+	}
284
+
285
+
286
+	/**
287
+	 * Activates a payment method of the given type.
288
+	 *
289
+	 * @param string $payment_method_type the PMT_type; for EE_PMT_Invoice this would be 'Invoice'
290
+	 * @return EE_Payment_Method
291
+	 * @throws InvalidDataTypeException
292
+	 * @throws EE_Error
293
+	 */
294
+	public function activate_a_payment_method_of_type($payment_method_type)
295
+	{
296
+		$this->maybe_register_payment_methods();
297
+		$payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
298
+		if (! $payment_method instanceof EE_Payment_Method) {
299
+			$pm_type_class = $this->payment_method_class_from_type($payment_method_type);
300
+			if (class_exists($pm_type_class)) {
301
+				/** @var $pm_type_obj EE_PMT_Base */
302
+				$pm_type_obj = new $pm_type_class();
303
+				$payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
304
+				if (! $payment_method) {
305
+					$payment_method = $this->create_payment_method_of_type($pm_type_obj);
306
+				}
307
+				$payment_method->set_type($payment_method_type);
308
+				$this->initialize_payment_method($payment_method);
309
+			} else {
310
+				throw new EE_Error(
311
+					sprintf(
312
+						esc_html__(
313
+							'There is no payment method of type %1$s, so it could not be activated',
314
+							'event_espresso'
315
+						),
316
+						$pm_type_class
317
+					)
318
+				);
319
+			}
320
+		}
321
+		$payment_method->set_active();
322
+		$payment_method->save();
323
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
324
+		// if this was the invoice message type, make sure users can view their invoices
325
+		if (
326
+			$payment_method->type() === 'Invoice'
327
+			&& (
328
+			! EEH_MSG_Template::is_mt_active('invoice')
329
+			)
330
+		) {
331
+			$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
332
+			/** @type EE_Message_Resource_Manager $message_resource_manager */
333
+			$message_resource_manager->ensure_message_type_is_active('invoice', 'html');
334
+			new PersistentAdminNotice(
335
+				'invoice_pm_requirements_notice',
336
+				sprintf(
337
+					esc_html__(
338
+						'The Invoice payment method has been activated. It requires the %1$sinvoice message%2$s type to be active, so it was automatically activated for you.',
339
+						'event_espresso'
340
+					),
341
+					'<a href="' . admin_url('admin.php?page=espresso_messages&action=settings') . '">',
342
+					'</a>'
343
+				),
344
+				true
345
+			);
346
+		}
347
+		return $payment_method;
348
+	}
349
+
350
+
351
+	/**
352
+	 * Creates a payment method of the specified type. Does not save it.
353
+	 *
354
+	 * @global WP_User    $current_user
355
+	 * @param EE_PMT_Base $pm_type_obj
356
+	 * @return EE_Payment_Method
357
+	 * @throws EE_Error
358
+	 */
359
+	public function create_payment_method_of_type($pm_type_obj)
360
+	{
361
+		global $current_user;
362
+		$payment_method = EE_Payment_Method::new_instance(
363
+			array(
364
+				'PMD_type'       => $pm_type_obj->system_name(),
365
+				'PMD_name'       => $pm_type_obj->defaultFrontendName(),
366
+				'PMD_admin_name' => $pm_type_obj->pretty_name(),
367
+				'PMD_slug'       => $pm_type_obj->system_name(),// automatically converted to slug
368
+				'PMD_wp_user'    => $current_user->ID,
369
+				'PMD_order'      => EEM_Payment_Method::instance()->count(
370
+					array(array('PMD_type' => array('!=', 'Admin_Only')))
371
+				) * 10,
372
+			)
373
+		);
374
+		return $payment_method;
375
+	}
376
+
377
+
378
+	/**
379
+	 * Sets the initial payment method properties (including extra meta)
380
+	 *
381
+	 * @param EE_Payment_Method $payment_method
382
+	 * @return EE_Payment_Method
383
+	 * @throws EE_Error
384
+	 */
385
+	public function initialize_payment_method($payment_method)
386
+	{
387
+		$pm_type_obj = $payment_method->type_obj();
388
+		$payment_method->set_description($pm_type_obj->default_description());
389
+		if (! $payment_method->button_url()) {
390
+			$payment_method->set_button_url($pm_type_obj->default_button_url());
391
+		}
392
+		// now add setup its default extra meta properties
393
+		$extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
394
+		if (! empty($extra_metas)) {
395
+			// verify the payment method has an ID before adding extra meta
396
+			if (! $payment_method->ID()) {
397
+				$payment_method->save();
398
+			}
399
+			foreach ($extra_metas as $meta_name => $input) {
400
+				$payment_method->update_extra_meta($meta_name, $input->raw_value());
401
+			}
402
+		}
403
+		return $payment_method;
404
+	}
405
+
406
+
407
+	/**
408
+	 * Makes sure the payment method is related to the specified payment method
409
+	 *
410
+	 * @deprecated in 4.9.40 because the currency payment method table is being deprecated
411
+	 * @param EE_Payment_Method $payment_method
412
+	 * @return EE_Payment_Method
413
+	 * @throws EE_Error
414
+	 */
415
+	public function set_usable_currencies_on_payment_method($payment_method)
416
+	{
417
+		EE_Error::doing_it_wrong(
418
+			'EE_Payment_Method_Manager::set_usable_currencies_on_payment_method',
419
+			esc_html__(
420
+				'We no longer define what currencies are usable by payment methods. Its not used nor efficient.',
421
+				'event_espresso'
422
+			),
423
+			'4.9.40'
424
+		);
425
+		return $payment_method;
426
+	}
427
+
428
+
429
+	/**
430
+	 * Deactivates a payment method of the given payment method slug.
431
+	 *
432
+	 * @param string $payment_method_slug The slug for the payment method to deactivate.
433
+	 * @return int count of rows updated.
434
+	 * @throws EE_Error
435
+	 */
436
+	public function deactivate_payment_method($payment_method_slug)
437
+	{
438
+		EE_Log::instance()->log(
439
+			__FILE__,
440
+			__FUNCTION__,
441
+			sprintf(
442
+				esc_html__(
443
+					'Payment method with slug %1$s is being deactivated by site admin',
444
+					'event_espresso'
445
+				),
446
+				$payment_method_slug
447
+			),
448
+			'payment_method_change'
449
+		);
450
+		$count_updated = EEM_Payment_Method::instance()->update(
451
+			array('PMD_scope' => array()),
452
+			array(array('PMD_slug' => $payment_method_slug))
453
+		);
454
+		do_action(
455
+			'AHEE__EE_Payment_Method_Manager__deactivate_payment_method__after_deactivating_payment_method',
456
+			$payment_method_slug,
457
+			$count_updated
458
+		);
459
+		return $count_updated;
460
+	}
461
+
462
+
463
+	/**
464
+	 * initializes payment method access caps via EE_Capabilities::init_role_caps()
465
+	 * upon EE_Payment_Method_Manager construction
466
+	 *
467
+	 * @throws EE_Error
468
+	 * @throws DomainException
469
+	 */
470
+	protected function initializePaymentMethodCaps()
471
+	{
472
+		// don't do this twice
473
+		if ($this->payment_method_caps_initialized) {
474
+			return;
475
+		}
476
+		EE_Capabilities::instance()->addCaps(
477
+			$this->getPaymentMethodCaps()
478
+		);
479
+		$this->payment_method_caps_initialized = true;
480
+	}
481
+
482
+
483
+	/**
484
+	 * array  of dynamic payment method access caps.
485
+	 * at the time of writing, october 20 2014, these are the caps added:
486
+	 *  ee_payment_method_admin_only
487
+	 *  ee_payment_method_aim
488
+	 *  ee_payment_method_bank
489
+	 *  ee_payment_method_check
490
+	 *  ee_payment_method_invoice
491
+	 *  ee_payment_method_mijireh
492
+	 *  ee_payment_method_paypal_pro
493
+	 *  ee_payment_method_paypal_standard
494
+	 * Any other payment methods added to core or via addons will also get
495
+	 * their related capability automatically added too, so long as they are
496
+	 * registered properly using EE_Register_Payment_Method::register()
497
+	 *
498
+	 * @return array
499
+	 * @throws DomainException
500
+	 */
501
+	protected function getPaymentMethodCaps()
502
+	{
503
+		$caps = array();
504
+		foreach ($this->payment_method_type_names() as $payment_method_name) {
505
+			$caps = $this->addPaymentMethodCap($payment_method_name, $caps);
506
+		}
507
+		return $caps;
508
+	}
509
+
510
+
511
+	/**
512
+	 * @param string $payment_method_name
513
+	 * @param array  $payment_method_caps
514
+	 * @param string $role
515
+	 * @return array
516
+	 * @throws DomainException
517
+	 */
518
+	public function addPaymentMethodCap($payment_method_name, array $payment_method_caps, $role = 'administrator')
519
+	{
520
+		if (empty($payment_method_name)) {
521
+			throw new DomainException(
522
+				esc_html__(
523
+					'The name of a payment method must be specified to add capabilities.',
524
+					'event_espresso'
525
+				)
526
+			);
527
+		}
528
+		if (empty($role)) {
529
+			throw new DomainException(
530
+				sprintf(
531
+					esc_html__(
532
+						'No role was supplied while trying to add capabilities for the %1$s payment method.',
533
+						'event_espresso'
534
+					),
535
+					$payment_method_name
536
+				)
537
+			);
538
+		}
539
+		if (! isset($payment_method_caps[ $role ])) {
540
+			$payment_method_caps[ $role ] = array();
541
+		}
542
+		$payment_method_caps[ $role ][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
543
+										  . strtolower($payment_method_name);
544
+		return $payment_method_caps;
545
+	}
546
+
547
+
548
+	/**
549
+	 * callback for FHEE__EE_Capabilities__init_role_caps__caps_map filter
550
+	 * to add dynamic payment method access caps when capabilities are reset
551
+	 * (or if that filter is called and PM caps are not already set)
552
+	 *
553
+	 * @param array $caps capabilities being filtered
554
+	 * @param bool  $reset
555
+	 * @return array
556
+	 * @throws DomainException
557
+	 */
558
+	public function addPaymentMethodCapsDuringReset(array $caps, $reset = false)
559
+	{
560
+		if ($reset || ! $this->payment_method_caps_initialized) {
561
+			$this->payment_method_caps_initialized = true;
562
+			$caps = array_merge_recursive($caps, $this->getPaymentMethodCaps());
563
+		}
564
+		return $caps;
565
+	}
566
+
567
+
568
+	/**
569
+	 * @deprecated 4.9.42
570
+	 * @param $caps
571
+	 * @return mixed
572
+	 */
573
+	public function add_payment_method_caps($caps)
574
+	{
575
+		return $caps;
576
+	}
577 577
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
     public static function instance()
75 75
     {
76 76
         // check if class object is instantiated, and instantiated properly
77
-        if (! self::$_instance instanceof EE_Payment_Method_Manager) {
77
+        if ( ! self::$_instance instanceof EE_Payment_Method_Manager) {
78 78
             EE_Registry::instance()->load_lib('PMT_Base');
79 79
             self::$_instance = new self();
80 80
         }
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
      */
106 106
     public function maybe_register_payment_methods($force_recheck = false)
107 107
     {
108
-        if (! $this->_payment_method_types || $force_recheck) {
108
+        if ( ! $this->_payment_method_types || $force_recheck) {
109 109
             $this->_register_payment_methods();
110 110
         }
111 111
     }
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
     protected function _register_payment_methods()
120 120
     {
121 121
         // grab list of installed modules
122
-        $pm_to_register = glob(EE_PAYMENT_METHODS . '*', GLOB_ONLYDIR);
122
+        $pm_to_register = glob(EE_PAYMENT_METHODS.'*', GLOB_ONLYDIR);
123 123
         // filter list of modules to register
124 124
         $pm_to_register = apply_filters(
125 125
             'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
@@ -159,9 +159,9 @@  discard block
 block discarded – undo
159 159
         // create class name from module directory name
160 160
         $module = str_replace(array('_', ' '), array(' ', '_'), $module_dir);
161 161
         // add class prefix
162
-        $module_class = 'EE_PMT_' . $module;
162
+        $module_class = 'EE_PMT_'.$module;
163 163
         // does the module exist ?
164
-        if (! is_readable($payment_method_path . '/' . $module_class . $module_ext)) {
164
+        if ( ! is_readable($payment_method_path.'/'.$module_class.$module_ext)) {
165 165
             $msg = sprintf(
166 166
                 esc_html__(
167 167
                     'The requested %s payment method file could not be found or is not readable due to file permissions.',
@@ -169,22 +169,22 @@  discard block
 block discarded – undo
169 169
                 ),
170 170
                 $module
171 171
             );
172
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
172
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
173 173
             return false;
174 174
         }
175 175
         // load the module class file
176
-        require_once($payment_method_path . '/' . $module_class . $module_ext);
176
+        require_once($payment_method_path.'/'.$module_class.$module_ext);
177 177
         // verify that class exists
178
-        if (! class_exists($module_class)) {
178
+        if ( ! class_exists($module_class)) {
179 179
             $msg = sprintf(
180 180
                 esc_html__('The requested %s module class does not exist.', 'event_espresso'),
181 181
                 $module_class
182 182
             );
183
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
183
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
184 184
             return false;
185 185
         }
186 186
         // add to array of registered modules
187
-        $this->_payment_method_types[ $module ] = $payment_method_path . '/' . $module_class . $module_ext;
187
+        $this->_payment_method_types[$module] = $payment_method_path.'/'.$module_class.$module_ext;
188 188
         ksort($this->_payment_method_types);
189 189
         return true;
190 190
     }
@@ -202,12 +202,12 @@  discard block
 block discarded – undo
202 202
         if (
203 203
             $force_recheck
204 204
             || ! is_array($this->_payment_method_types)
205
-            || ! isset($this->_payment_method_types[ $payment_method_name ])
205
+            || ! isset($this->_payment_method_types[$payment_method_name])
206 206
         ) {
207 207
             $this->maybe_register_payment_methods($force_recheck);
208 208
         }
209
-        if (isset($this->_payment_method_types[ $payment_method_name ])) {
210
-            require_once($this->_payment_method_types[ $payment_method_name ]);
209
+        if (isset($this->_payment_method_types[$payment_method_name])) {
210
+            require_once($this->_payment_method_types[$payment_method_name]);
211 211
             return true;
212 212
         }
213 213
         return false;
@@ -249,8 +249,8 @@  discard block
 block discarded – undo
249 249
         if ($force_recheck || empty($this->payment_method_objects)) {
250 250
             $this->maybe_register_payment_methods($force_recheck);
251 251
             foreach ($this->payment_method_type_names(true) as $classname) {
252
-                if (! isset($this->payment_method_objects[ $classname ])) {
253
-                    $this->payment_method_objects[ $classname ] = new $classname();
252
+                if ( ! isset($this->payment_method_objects[$classname])) {
253
+                    $this->payment_method_objects[$classname] = new $classname();
254 254
                 }
255 255
             }
256 256
         }
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
      */
280 280
     public function payment_method_class_from_type($type)
281 281
     {
282
-        return 'EE_PMT_' . $type;
282
+        return 'EE_PMT_'.$type;
283 283
     }
284 284
 
285 285
 
@@ -295,13 +295,13 @@  discard block
 block discarded – undo
295 295
     {
296 296
         $this->maybe_register_payment_methods();
297 297
         $payment_method = EEM_Payment_Method::instance()->get_one_of_type($payment_method_type);
298
-        if (! $payment_method instanceof EE_Payment_Method) {
298
+        if ( ! $payment_method instanceof EE_Payment_Method) {
299 299
             $pm_type_class = $this->payment_method_class_from_type($payment_method_type);
300 300
             if (class_exists($pm_type_class)) {
301 301
                 /** @var $pm_type_obj EE_PMT_Base */
302 302
                 $pm_type_obj = new $pm_type_class();
303 303
                 $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_type_obj->system_name());
304
-                if (! $payment_method) {
304
+                if ( ! $payment_method) {
305 305
                     $payment_method = $this->create_payment_method_of_type($pm_type_obj);
306 306
                 }
307 307
                 $payment_method->set_type($payment_method_type);
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
                         'The Invoice payment method has been activated. It requires the %1$sinvoice message%2$s type to be active, so it was automatically activated for you.',
339 339
                         'event_espresso'
340 340
                     ),
341
-                    '<a href="' . admin_url('admin.php?page=espresso_messages&action=settings') . '">',
341
+                    '<a href="'.admin_url('admin.php?page=espresso_messages&action=settings').'">',
342 342
                     '</a>'
343 343
                 ),
344 344
                 true
@@ -364,7 +364,7 @@  discard block
 block discarded – undo
364 364
                 'PMD_type'       => $pm_type_obj->system_name(),
365 365
                 'PMD_name'       => $pm_type_obj->defaultFrontendName(),
366 366
                 'PMD_admin_name' => $pm_type_obj->pretty_name(),
367
-                'PMD_slug'       => $pm_type_obj->system_name(),// automatically converted to slug
367
+                'PMD_slug'       => $pm_type_obj->system_name(), // automatically converted to slug
368 368
                 'PMD_wp_user'    => $current_user->ID,
369 369
                 'PMD_order'      => EEM_Payment_Method::instance()->count(
370 370
                     array(array('PMD_type' => array('!=', 'Admin_Only')))
@@ -386,14 +386,14 @@  discard block
 block discarded – undo
386 386
     {
387 387
         $pm_type_obj = $payment_method->type_obj();
388 388
         $payment_method->set_description($pm_type_obj->default_description());
389
-        if (! $payment_method->button_url()) {
389
+        if ( ! $payment_method->button_url()) {
390 390
             $payment_method->set_button_url($pm_type_obj->default_button_url());
391 391
         }
392 392
         // now add setup its default extra meta properties
393 393
         $extra_metas = $pm_type_obj->settings_form()->extra_meta_inputs();
394
-        if (! empty($extra_metas)) {
394
+        if ( ! empty($extra_metas)) {
395 395
             // verify the payment method has an ID before adding extra meta
396
-            if (! $payment_method->ID()) {
396
+            if ( ! $payment_method->ID()) {
397 397
                 $payment_method->save();
398 398
             }
399 399
             foreach ($extra_metas as $meta_name => $input) {
@@ -536,10 +536,10 @@  discard block
 block discarded – undo
536 536
                 )
537 537
             );
538 538
         }
539
-        if (! isset($payment_method_caps[ $role ])) {
540
-            $payment_method_caps[ $role ] = array();
539
+        if ( ! isset($payment_method_caps[$role])) {
540
+            $payment_method_caps[$role] = array();
541 541
         }
542
-        $payment_method_caps[ $role ][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
542
+        $payment_method_caps[$role][] = EE_Payment_Method_Manager::CAPABILITIES_PREFIX
543 543
                                           . strtolower($payment_method_name);
544 544
         return $payment_method_caps;
545 545
     }
Please login to merge, or discard this patch.