Completed
Branch master (f06961)
by
unknown
22:07 queued 16:21
created
core/domain/services/cron/jobs/GarbageCollection.php 2 patches
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -18,54 +18,54 @@
 block discarded – undo
18 18
 
19 19
 class GarbageCollection extends CronJob
20 20
 {
21
-    public function setHooks(): void
22
-    {
23
-        add_action(
24
-            'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
25
-            [$this, 'cleanUpJunkTransactions']
26
-        );
27
-        add_action(
28
-            'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs',
29
-            [$this, 'cleanUpOldGatewayLogs']
30
-        );
31
-    }
21
+	public function setHooks(): void
22
+	{
23
+		add_action(
24
+			'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
25
+			[$this, 'cleanUpJunkTransactions']
26
+		);
27
+		add_action(
28
+			'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs',
29
+			[$this, 'cleanUpOldGatewayLogs']
30
+		);
31
+	}
32 32
 
33 33
 
34
-    /**
35
-     * callback for 'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'
36
-     * which is set up during activation to run on an hourly cron
37
-     *
38
-     * @throws EE_Error
39
-     * @throws DomainException
40
-     * @throws ReflectionException
41
-     */
42
-    public function cleanUpJunkTransactions(): void
43
-    {
44
-        if (DbStatus::isOnline()) {
45
-            EED_Ticket_Sales_Monitor::reset_reservation_counts();
46
-            EEM_Transaction::instance()->delete_junk_transactions();
47
-            EEM_Registration::instance()->delete_registrations_with_no_transaction();
48
-            EEM_Line_Item::instance()->delete_line_items_with_no_transaction();
49
-        }
50
-    }
34
+	/**
35
+	 * callback for 'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'
36
+	 * which is set up during activation to run on an hourly cron
37
+	 *
38
+	 * @throws EE_Error
39
+	 * @throws DomainException
40
+	 * @throws ReflectionException
41
+	 */
42
+	public function cleanUpJunkTransactions(): void
43
+	{
44
+		if (DbStatus::isOnline()) {
45
+			EED_Ticket_Sales_Monitor::reset_reservation_counts();
46
+			EEM_Transaction::instance()->delete_junk_transactions();
47
+			EEM_Registration::instance()->delete_registrations_with_no_transaction();
48
+			EEM_Line_Item::instance()->delete_line_items_with_no_transaction();
49
+		}
50
+	}
51 51
 
52 52
 
53
-    /**
54
-     * Deletes old gateway logs. After about a week we usually don't need them for debugging. But folks can filter that.
55
-     *
56
-     * @throws EE_Error
57
-     * @throws ReflectionException
58
-     * @throws Exception
59
-     */
60
-    public function cleanUpOldGatewayLogs(): void
61
-    {
62
-        if (DbStatus::isOnline()) {
63
-            $reg_config               = $this->loader->getShared(EE_Registration_Config::class);
64
-            $time_diff_for_comparison = apply_filters(
65
-                'FHEE__EE_Cron_Tasks__clean_out_old_gateway_logs__time_diff_for_comparison',
66
-                '-' . $reg_config->gateway_log_lifespan
67
-            );
68
-            EEM_Change_Log::instance()->delete_gateway_logs_older_than(new DateTime($time_diff_for_comparison));
69
-        }
70
-    }
53
+	/**
54
+	 * Deletes old gateway logs. After about a week we usually don't need them for debugging. But folks can filter that.
55
+	 *
56
+	 * @throws EE_Error
57
+	 * @throws ReflectionException
58
+	 * @throws Exception
59
+	 */
60
+	public function cleanUpOldGatewayLogs(): void
61
+	{
62
+		if (DbStatus::isOnline()) {
63
+			$reg_config               = $this->loader->getShared(EE_Registration_Config::class);
64
+			$time_diff_for_comparison = apply_filters(
65
+				'FHEE__EE_Cron_Tasks__clean_out_old_gateway_logs__time_diff_for_comparison',
66
+				'-' . $reg_config->gateway_log_lifespan
67
+			);
68
+			EEM_Change_Log::instance()->delete_gateway_logs_older_than(new DateTime($time_diff_for_comparison));
69
+		}
70
+	}
71 71
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -63,7 +63,7 @@
 block discarded – undo
63 63
             $reg_config               = $this->loader->getShared(EE_Registration_Config::class);
64 64
             $time_diff_for_comparison = apply_filters(
65 65
                 'FHEE__EE_Cron_Tasks__clean_out_old_gateway_logs__time_diff_for_comparison',
66
-                '-' . $reg_config->gateway_log_lifespan
66
+                '-'.$reg_config->gateway_log_lifespan
67 67
             );
68 68
             EEM_Change_Log::instance()->delete_gateway_logs_older_than(new DateTime($time_diff_for_comparison));
69 69
         }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -37,138 +37,138 @@
 block discarded – undo
37 37
  * @since           4.0
38 38
  */
39 39
 if (function_exists('espresso_version')) {
40
-    if (! function_exists('espresso_duplicate_plugin_error')) {
41
-        /**
42
-         *    espresso_duplicate_plugin_error
43
-         *    displays if more than one version of EE is activated at the same time.
44
-         */
45
-        function espresso_duplicate_plugin_error()
46
-        {
47
-            ?>
40
+	if (! function_exists('espresso_duplicate_plugin_error')) {
41
+		/**
42
+		 *    espresso_duplicate_plugin_error
43
+		 *    displays if more than one version of EE is activated at the same time.
44
+		 */
45
+		function espresso_duplicate_plugin_error()
46
+		{
47
+			?>
48 48
 <div class="error">
49 49
     <p>
50 50
         <?php
51
-                    echo esc_html__(
52
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
-                        'event_espresso'
54
-                    ); ?>
51
+					echo esc_html__(
52
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
+						'event_espresso'
54
+					); ?>
55 55
     </p>
56 56
 </div>
57 57
 <?php
58
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
59
-        }
60
-    }
61
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
58
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
59
+		}
60
+	}
61
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62 62
 } else {
63
-    define('EE_MIN_PHP_VER_REQUIRED', '7.4.0');
64
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
-        /**
66
-         * espresso_minimum_php_version_error
67
-         *
68
-         * @return void
69
-         */
70
-        function espresso_minimum_php_version_error()
71
-        {
72
-            ?>
63
+	define('EE_MIN_PHP_VER_REQUIRED', '7.4.0');
64
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
+		/**
66
+		 * espresso_minimum_php_version_error
67
+		 *
68
+		 * @return void
69
+		 */
70
+		function espresso_minimum_php_version_error()
71
+		{
72
+			?>
73 73
 <div class="error">
74 74
     <p>
75 75
         <?php
76
-                    printf(
77
-                        esc_html__(
78
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
-                            'event_espresso'
80
-                        ),
81
-                        EE_MIN_PHP_VER_REQUIRED,
82
-                        PHP_VERSION,
83
-                        '<br/>',
84
-                        '<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>'
85
-                    );
86
-        ?>
76
+					printf(
77
+						esc_html__(
78
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
+							'event_espresso'
80
+						),
81
+						EE_MIN_PHP_VER_REQUIRED,
82
+						PHP_VERSION,
83
+						'<br/>',
84
+						'<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>'
85
+					);
86
+		?>
87 87
     </p>
88 88
 </div>
89 89
 <?php
90
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
91
-        }
90
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
91
+		}
92 92
 
93
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
-    } else {
95
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
93
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
+	} else {
95
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
96 96
 
97
-        require_once __DIR__ . '/vendor/autoload.php';
97
+		require_once __DIR__ . '/vendor/autoload.php';
98 98
 
99
-        /**
100
-         * espresso_version
101
-         * Returns the plugin version
102
-         *
103
-         * @return string
104
-         */
105
-        function espresso_version(): string
106
-        {
107
-            return apply_filters('FHEE__espresso__espresso_version', '5.0.30.rc.000');
108
-        }
99
+		/**
100
+		 * espresso_version
101
+		 * Returns the plugin version
102
+		 *
103
+		 * @return string
104
+		 */
105
+		function espresso_version(): string
106
+		{
107
+			return apply_filters('FHEE__espresso__espresso_version', '5.0.30.rc.000');
108
+		}
109 109
 
110
-        /**
111
-         * espresso_plugin_activation
112
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
113
-         */
114
-        function espresso_plugin_activation()
115
-        {
116
-            update_option('ee_espresso_activation', true);
117
-            update_option('event-espresso-core_allow_tracking', 'no');
118
-            update_option('event-espresso-core_tracking_notice', 'hide');
119
-            // Run WP GraphQL activation callback
120
-            espressoLoadWpGraphQL();
121
-            graphql_activation_callback();
122
-        }
110
+		/**
111
+		 * espresso_plugin_activation
112
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
113
+		 */
114
+		function espresso_plugin_activation()
115
+		{
116
+			update_option('ee_espresso_activation', true);
117
+			update_option('event-espresso-core_allow_tracking', 'no');
118
+			update_option('event-espresso-core_tracking_notice', 'hide');
119
+			// Run WP GraphQL activation callback
120
+			espressoLoadWpGraphQL();
121
+			graphql_activation_callback();
122
+		}
123 123
 
124
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
124
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
125 125
 
126
-        /**
127
-         * espresso_plugin_deactivation
128
-         */
129
-        function espresso_plugin_deactivation()
130
-        {
131
-            // Run WP GraphQL deactivation callback
132
-            espressoLoadWpGraphQL();
133
-            graphql_deactivation_callback();
134
-            delete_option('event-espresso-core_allow_tracking');
135
-            delete_option('event-espresso-core_tracking_notice');
136
-        }
137
-        register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
126
+		/**
127
+		 * espresso_plugin_deactivation
128
+		 */
129
+		function espresso_plugin_deactivation()
130
+		{
131
+			// Run WP GraphQL deactivation callback
132
+			espressoLoadWpGraphQL();
133
+			graphql_deactivation_callback();
134
+			delete_option('event-espresso-core_allow_tracking');
135
+			delete_option('event-espresso-core_tracking_notice');
136
+		}
137
+		register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
138 138
 
139
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
140
-        bootstrap_espresso();
141
-    }
139
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
140
+		bootstrap_espresso();
141
+	}
142 142
 }
143 143
 
144 144
 if (! function_exists('espresso_deactivate_plugin')) {
145
-    /**
146
-     *    deactivate_plugin
147
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
148
-     *
149
-     * @access public
150
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
151
-     * @return    void
152
-     */
153
-    function espresso_deactivate_plugin(string $plugin_basename = '')
154
-    {
155
-        if (! function_exists('deactivate_plugins')) {
156
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
-        }
158
-        unset($_GET['activate'], $_REQUEST['activate']);
159
-        deactivate_plugins($plugin_basename);
160
-    }
145
+	/**
146
+	 *    deactivate_plugin
147
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
148
+	 *
149
+	 * @access public
150
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
151
+	 * @return    void
152
+	 */
153
+	function espresso_deactivate_plugin(string $plugin_basename = '')
154
+	{
155
+		if (! function_exists('deactivate_plugins')) {
156
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
+		}
158
+		unset($_GET['activate'], $_REQUEST['activate']);
159
+		deactivate_plugins($plugin_basename);
160
+	}
161 161
 }
162 162
 
163 163
 
164 164
 if (! function_exists('espressoLoadWpGraphQL')) {
165
-    function espressoLoadWpGraphQL()
166
-    {
167
-        if (
168
-            ! class_exists('WPGraphQL')
169
-            && is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php')
170
-        ) {
171
-            require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php';
172
-        }
173
-    }
165
+	function espressoLoadWpGraphQL()
166
+	{
167
+		if (
168
+			! class_exists('WPGraphQL')
169
+			&& is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php')
170
+		) {
171
+			require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php';
172
+		}
173
+	}
174 174
 }
Please login to merge, or discard this patch.
core/libraries/payment_methods/EE_PMT_Base.lib.php 2 patches
Indentation   +931 added lines, -931 removed lines patch added patch discarded remove patch
@@ -16,935 +16,935 @@
 block discarded – undo
16 16
  */
17 17
 abstract class EE_PMT_Base
18 18
 {
19
-    const onsite  = 'on-site';
20
-
21
-    const offsite = 'off-site';
22
-
23
-    const offline = 'off-line';
24
-
25
-    protected ?EE_Payment_Method $_pm_instance = null;
26
-
27
-    protected ?EE_Gateway $_gateway = null;
28
-
29
-    protected ?EE_Payment_Method_Form $_settings_form = null;
30
-
31
-    protected ?EE_Form_Section_Proper $_billing_form = null;
32
-
33
-    protected bool $_cache_billing_form = true;
34
-
35
-    protected ?bool $_has_billing_form;
36
-
37
-    protected bool $_requires_https = false;
38
-
39
-    /**
40
-     * String of the absolute path to the folder containing this file, with a trailing slash.
41
-     * eg '/public_html/wp-site/wp-content/plugins/event-espresso/payment_methods/Invoice/'
42
-     *
43
-     * @var string|null
44
-     */
45
-    protected $_file_folder = null;
46
-
47
-    /**
48
-     * String to the absolute URL to this file (useful for getting its web-accessible resources
49
-     * like images, js, or css)
50
-     *
51
-     * @var string|null
52
-     */
53
-    protected $_file_url = null;
54
-
55
-    /**
56
-     * Pretty name for the payment method
57
-     *
58
-     * @var string|null
59
-     */
60
-    protected $_pretty_name = null;
61
-
62
-    /**
63
-     * @var string|null
64
-     */
65
-    protected $_default_button_url = null;
66
-
67
-    /**
68
-     * @var string|null
69
-     */
70
-    protected $_default_description = null;
71
-
72
-    /**
73
-     * @var string|null
74
-     */
75
-    protected $_template_path = null;
76
-
77
-
78
-    /**
79
-     * @param EE_Payment_Method|null $pm_instance
80
-     * @throws ReflectionException
81
-     * @throws EE_Error
82
-     */
83
-    public function __construct($pm_instance = null)
84
-    {
85
-        if ($pm_instance instanceof EE_Payment_Method) {
86
-            $this->set_instance($pm_instance);
87
-        }
88
-        if ($this->_gateway) {
89
-            $this->_gateway->set_payment_model(EEM_Payment::instance());
90
-            $this->_gateway->set_payment_log(EEM_Change_Log::instance());
91
-            $this->_gateway->set_template_helper(new EEH_Template());
92
-            $this->_gateway->set_line_item_helper(new EEH_Line_Item());
93
-            $this->_gateway->set_money_helper(new EEH_Money());
94
-            $this->_gateway->set_gateway_data_formatter(new GatewayDataFormatter());
95
-            $this->_gateway->set_unsupported_character_remover(new AsciiOnly());
96
-            do_action('AHEE__EE_PMT_Base___construct__done_initializing_gateway_class', $this, $this->_gateway);
97
-        }
98
-        if (! isset($this->_has_billing_form)) {
99
-            // by default, On Site gateways have a billing form
100
-            if ($this->payment_occurs() == EE_PMT_Base::onsite) {
101
-                $this->set_has_billing_form(true);
102
-            } else {
103
-                $this->set_has_billing_form(false);
104
-            }
105
-        }
106
-
107
-        if (! $this->_pretty_name) {
108
-            throw new EE_Error(
109
-                esc_html__(
110
-                    'You must set the pretty name for the Payment Method Type in the constructor (_pretty_name), and please make it internationalized',
111
-                    'event_espresso'
112
-                )
113
-            );
114
-        }
115
-        // if the child didn't specify a default button, use the credit card one
116
-        if ($this->_default_button_url === null) {
117
-            $this->_default_button_url = EE_PLUGIN_DIR_URL . 'payment_methods/pay-by-credit-card.png';
118
-        }
119
-    }
120
-
121
-
122
-    /**
123
-     * @param bool|int|string $has_billing_form
124
-     */
125
-    public function set_has_billing_form($has_billing_form)
126
-    {
127
-        $this->_has_billing_form = filter_var($has_billing_form, FILTER_VALIDATE_BOOLEAN);
128
-    }
129
-
130
-
131
-    /**
132
-     * sets the file_folder property
133
-     */
134
-    protected function _set_file_folder()
135
-    {
136
-        $reflector          = new ReflectionClass(get_class($this));
137
-        $fn                 = $reflector->getFileName();
138
-        $this->_file_folder = dirname($fn) . '/';
139
-    }
140
-
141
-
142
-    /**
143
-     * sets the file URL with a trailing slash for this PMT
144
-     */
145
-    protected function _set_file_url()
146
-    {
147
-        $plugins_dir_fixed = str_replace('\\', '/', WP_PLUGIN_DIR);
148
-        $file_folder_fixed = str_replace('\\', '/', $this->file_folder());
149
-        $file_path         = str_replace($plugins_dir_fixed, WP_PLUGIN_URL, $file_folder_fixed);
150
-        $this->_file_url   = set_url_scheme($file_path);
151
-    }
152
-
153
-
154
-    /**
155
-     * Gets the default description on all payment methods of this type
156
-     *
157
-     * @return string
158
-     */
159
-    public function default_description(): ?string
160
-    {
161
-        return $this->_default_description;
162
-    }
163
-
164
-
165
-    /**
166
-     * Returns the folder containing the PMT child class, with a trailing slash
167
-     *
168
-     * @return string
169
-     */
170
-    public function file_folder(): ?string
171
-    {
172
-        if (! $this->_file_folder) {
173
-            $this->_set_file_folder();
174
-        }
175
-        return $this->_file_folder;
176
-    }
177
-
178
-
179
-    /**
180
-     * @return string
181
-     */
182
-    public function file_url(): ?string
183
-    {
184
-        if (! $this->_file_url) {
185
-            $this->_set_file_url();
186
-        }
187
-        return $this->_file_url;
188
-    }
189
-
190
-
191
-    /**
192
-     * Sets the payment method instance this payment method type is for.
193
-     * Its important teh payment method instance is set before
194
-     *
195
-     * @param EE_Payment_Method $payment_method_instance
196
-     * @throws EE_Error
197
-     * @throws ReflectionException
198
-     */
199
-    public function set_instance(EE_Payment_Method $payment_method_instance)
200
-    {
201
-        $this->_pm_instance = $payment_method_instance;
202
-        // if they have already requested the settings form, make sure its
203
-        // data matches this model object
204
-        if ($this->_settings_form) {
205
-            $this->settings_form()->populate_model_obj($payment_method_instance);
206
-        }
207
-        if ($this->_gateway instanceof EE_Gateway) {
208
-            $this->_gateway->set_settings($payment_method_instance->settings_array());
209
-        }
210
-    }
211
-
212
-
213
-    /**
214
-     * Gets teh form for displaying to admins where they set up the payment method
215
-     *
216
-     * @return EE_Payment_Method_Form
217
-     * @throws EE_Error
218
-     * @throws ReflectionException
219
-     */
220
-    public function settings_form(): EE_Payment_Method_Form
221
-    {
222
-        if (! $this->_settings_form) {
223
-            $this->_settings_form = $this->generate_new_settings_form();
224
-            $this->_settings_form->set_payment_method_type($this);
225
-            // if we have already assigned a model object to this pmt, make
226
-            // sure it's reflected in the form we just generated
227
-            if ($this->_pm_instance) {
228
-                $this->_settings_form->populate_model_obj($this->_pm_instance);
229
-            }
230
-        }
231
-        return $this->_settings_form;
232
-    }
233
-
234
-
235
-    /**
236
-     * Gets the form for all the settings related to this payment method type
237
-     *
238
-     * @return EE_Payment_Method_Form
239
-     */
240
-    abstract public function generate_new_settings_form();
241
-
242
-
243
-    /**
244
-     * Sets the form for settings. This may be useful if we have already received
245
-     * a form submission and have form data it in, and want to use it anytime we're showing
246
-     * this payment method type's settings form later in the request
247
-     *
248
-     * @param EE_Payment_Method_Form $form
249
-     */
250
-    public function set_settings_form(EE_Payment_Method_Form $form)
251
-    {
252
-        $this->_settings_form = $form;
253
-    }
254
-
255
-
256
-    /**
257
-     * @return boolean
258
-     */
259
-    public function has_billing_form(): bool
260
-    {
261
-        return $this->_has_billing_form;
262
-    }
263
-
264
-
265
-    /**
266
-     * Gets the form for displaying to attendees where they can enter their billing info
267
-     * which will be sent to teh gateway (can be null)
268
-     *
269
-     * @param EE_Transaction|null $transaction
270
-     * @param array               $extra_args
271
-     * @return EE_Billing_Attendee_Info_Form|EE_Billing_Info_Form|null
272
-     * @throws EE_Error
273
-     * @throws ReflectionException
274
-     */
275
-    public function billing_form(EE_Transaction $transaction = null, array $extra_args = [])
276
-    {
277
-        // has billing form already been regenerated ? or overwrite cache?
278
-        if (! $this->_billing_form instanceof EE_Billing_Info_Form || ! $this->_cache_billing_form) {
279
-            $this->_billing_form = $this->generate_new_billing_form($transaction, $extra_args);
280
-        }
281
-        // if we know who the attendee is, and this is a billing form
282
-        // that uses attendee info, populate it
283
-        if (
284
-            apply_filters(
285
-                'FHEE__populate_billing_form_fields_from_attendee',
286
-                (
287
-                    $this->_billing_form instanceof EE_Billing_Attendee_Info_Form
288
-                    && $transaction instanceof EE_Transaction
289
-                    && $transaction->primary_registration() instanceof EE_Registration
290
-                    && $transaction->primary_registration()->attendee() instanceof EE_Attendee
291
-                ),
292
-                $this->_billing_form,
293
-                $transaction
294
-            )
295
-        ) {
296
-            $this->_billing_form->populate_from_attendee($transaction->primary_registration()->attendee());
297
-        }
298
-        return $this->_billing_form;
299
-    }
300
-
301
-
302
-    /**
303
-     * Creates the billing form for this payment method type
304
-     *
305
-     * @param EE_Transaction|null $transaction
306
-     * @return EE_Billing_Info_Form|null
307
-     */
308
-    abstract public function generate_new_billing_form(EE_Transaction $transaction = null);
309
-
310
-
311
-    /**
312
-     * applies debug data to the form
313
-     *
314
-     * @param EE_Billing_Info_Form $billing_form
315
-     * @return EE_Billing_Info_Form|null
316
-     */
317
-    public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form)
318
-    {
319
-        return $billing_form;
320
-    }
321
-
322
-
323
-    /**
324
-     * Sets the billing form for this payment method type. You may want to use this
325
-     * if you have form
326
-     *
327
-     * @param EE_Billing_Info_Form $form
328
-     */
329
-    public function set_billing_form(EE_Billing_Info_Form $form)
330
-    {
331
-        $this->_billing_form = $form;
332
-    }
333
-
334
-
335
-    /**
336
-     * Returns whether this payment method requires HTTPS to be used
337
-     *
338
-     * @return boolean
339
-     */
340
-    public function requires_https(): bool
341
-    {
342
-        return $this->_requires_https;
343
-    }
344
-
345
-
346
-    /**
347
-     * @param EE_Transaction            $transaction
348
-     * @param float|null                $amount
349
-     * @param EE_Billing_Info_Form|null $billing_info
350
-     * @param string|null               $return_url
351
-     * @param string                    $fail_url
352
-     * @param string                    $method
353
-     * @param bool                      $by_admin
354
-     * @return EE_Payment
355
-     * @throws EE_Error
356
-     * @throws ReflectionException
357
-     */
358
-    public function process_payment(
359
-        EE_Transaction $transaction,
360
-        $amount = null,
361
-        $billing_info = null,
362
-        $return_url = null,
363
-        $fail_url = '',
364
-        $method = EEM_Payment_Method::scope_cart,
365
-        $by_admin = false
366
-    ) {
367
-        $amount = $amount ?: $transaction->remaining();
368
-        $method = EEM_Payment_Method::instance()->is_valid_scope($method) ? $method : EEM_Payment_Method::scope_cart;
369
-
370
-
371
-        // @todo: add surcharge for the payment method, if any
372
-        if (! $this->_gateway instanceof EE_Gateway) {
373
-            // no gateway provided, must be an offline gateway
374
-            // create a payment object anyways, but don't save it
375
-            // but if there is billing info, clean it and save it first
376
-            if ($billing_info instanceof EE_Billing_Attendee_Info_Form) {
377
-                $this->_save_billing_info_to_attendee($billing_info, $transaction);
378
-            }
379
-            return EE_Payment::new_instance(
380
-                [
381
-                    'STS_ID'        => EEM_Payment::status_id_pending,
382
-                    'TXN_ID'        => $transaction->ID(),
383
-                    'PMD_ID'        => $transaction->payment_method_ID(),
384
-                    'PAY_amount'    => 0.00,
385
-                    'PAY_timestamp' => time(),
386
-                ]
387
-            );
388
-        }
389
-
390
-        $payment = $this->getLastPayment($transaction, $amount, $method);
391
-        $payment = $this->validatePayment($transaction, $payment, $amount, $method);
392
-
393
-        $max_payment_attempts   = apply_filters(
394
-            'FHEE__EE_PMT_Base__process_payment__max_payment_attempts',
395
-            5,
396
-            $transaction
397
-        );
398
-        $previous_payment_count = $this->getPreviousPaymentCount($transaction, $amount, $method);
399
-        // only pass payment to gateway if we haven't exceeded the max attempts
400
-        $payment = $previous_payment_count < $max_payment_attempts
401
-            ? $this->passPaymentToGateway($payment, $transaction, $billing_info, $return_url, $fail_url)
402
-            : $payment;
403
-
404
-        // if there is billing info, clean it and save it
405
-        if ($billing_info instanceof EE_Billing_Attendee_Info_Form) {
406
-            $this->_save_billing_info_to_attendee($billing_info, $transaction);
407
-        }
408
-
409
-        return $payment;
410
-    }
411
-
412
-
413
-    /**
414
-     * Checks for any existing payments that are in a failed state for the same TXN, amount, and method
415
-     *
416
-     * @param EE_Transaction $transaction
417
-     * @param float          $amount
418
-     * @param string         $method
419
-     * @return EE_Payment|null
420
-     * @throws EE_Error
421
-     * @throws ReflectionException
422
-     * @since 5.0.28.p
423
-     */
424
-    private function getLastPayment(EE_Transaction $transaction, float $amount, string $method): ?EE_Payment
425
-    {
426
-        return EEM_Payment::instance()->get_one(
427
-            [
428
-                [
429
-                    'STS_ID'     => EEM_Payment::status_id_failed,
430
-                    'TXN_ID'     => $transaction->ID(),
431
-                    'PMD_ID'     => $this->_pm_instance->ID(),
432
-                    'PAY_source' => $method,
433
-                    'PAY_amount' => $amount,
434
-                ],
435
-            ]
436
-        );
437
-    }
438
-
439
-
440
-    /**
441
-     * IF the last payment was not a failed payment
442
-     * (which indicates a payment in progress that has yet to be updated),
443
-     * then create a new payment, otherwise just return the existing payment,
444
-     * but save it to ensure it has an ID
445
-     *
446
-     * @param EE_Transaction  $transaction
447
-     * @param EE_Payment|null $payment
448
-     * @param float           $amount
449
-     * @param string          $method
450
-     * @return EE_Payment
451
-     * @throws EE_Error
452
-     * @throws ReflectionException
453
-     * @since 5.0.28.p
454
-     */
455
-    private function validatePayment(
456
-        EE_Transaction $transaction,
457
-        ?EE_Payment $payment,
458
-        float $amount,
459
-        string $method
460
-    ): EE_Payment {
461
-        if (! $payment instanceof EE_Payment || ! $payment->is_failed()) {
462
-            $payment = EE_Payment::new_instance(
463
-                [
464
-                    'PAY_amount'           => $amount,
465
-                    'PAY_details'          => null,
466
-                    'PAY_extra_accntng'    => null,
467
-                    'PAY_gateway_response' => null,
468
-                    'PAY_po_number'        => null,
469
-                    'PAY_source'           => $method,
470
-                    'PAY_timestamp'        => time(),
471
-                    'PAY_txn_id_chq_nmbr'  => null,
472
-                    'PMD_ID'               => $this->_pm_instance->ID(),
473
-                    'STS_ID'               => EEM_Payment::status_id_failed,
474
-                    'TXN_ID'               => $transaction->ID(),
475
-                ]
476
-            );
477
-        }
478
-        // make sure the payment has been saved to show we started it,
479
-        // and so it has an ID should the gateway try to log it
480
-        $payment->save();
481
-
482
-        return $payment;
483
-    }
484
-
485
-
486
-    /**
487
-     * Checks for any existing payments that are in a failed state for the same TXN, amount, and method
488
-     *
489
-     * @param EE_Transaction $transaction
490
-     * @param float          $amount
491
-     * @param string         $method
492
-     * @return int
493
-     * @throws EE_Error
494
-     * @throws ReflectionException
495
-     * @since 5.0.28.p
496
-     */
497
-    private function getPreviousPaymentCount(EE_Transaction $transaction, float $amount, string $method): int
498
-    {
499
-        return EEM_Payment::instance()->count(
500
-            [
501
-                [
502
-                    'STS_ID'     => [
503
-                        'IN',
504
-                        [
505
-                            EEM_Payment::status_id_pending,
506
-                            EEM_Payment::status_id_cancelled,
507
-                            EEM_Payment::status_id_declined,
508
-                            EEM_Payment::status_id_failed,
509
-                        ],
510
-                    ],
511
-                    'TXN_ID'     => $transaction->ID(),
512
-                    'PMD_ID'     => $this->_pm_instance->ID(),
513
-                    'PAY_source' => $method,
514
-                    'PAY_amount' => $amount,
515
-                ],
516
-                'order_by' => ['PAY_timestamp' => 'DESC'],
517
-            ]
518
-        );
519
-    }
520
-
521
-
522
-    /**
523
-     * @param EE_Payment                $payment
524
-     * @param EE_Transaction            $transaction
525
-     * @param EE_Billing_Info_Form|null $billing_info
526
-     * @param string|null               $return_url
527
-     * @param string|null               $fail_url
528
-     * @return EE_Payment
529
-     * @throws EE_Error
530
-     * @throws ReflectionException
531
-     * @since 5.0.28.p
532
-     */
533
-    private function passPaymentToGateway(
534
-        EE_Payment $payment,
535
-        EE_Transaction $transaction,
536
-        ?EE_Billing_Info_Form $billing_info,
537
-        ?string $return_url = null,
538
-        ?string $fail_url = ''
539
-    ): EE_Payment {
540
-        $billing_values = $this->_get_billing_values_from_form($billing_info);
541
-        if ($this->_gateway instanceof EE_Offsite_Gateway) {
542
-            $payment = $this->_gateway->set_redirection_info(
543
-                $payment,
544
-                $billing_values,
545
-                $return_url,
546
-                EE_Config::instance()->core->txn_page_url(
547
-                    [
548
-                        'e_reg_url_link'    => $transaction->primary_registration()->reg_url_link(),
549
-                        'ee_payment_method' => $this->_pm_instance->slug(),
550
-                    ]
551
-                ),
552
-                $fail_url
553
-            );
554
-            $payment->save();
555
-        } elseif ($this->_gateway instanceof EE_Onsite_Gateway) {
556
-            $payment = $this->_gateway->do_direct_payment($payment, $billing_values);
557
-            $payment->save();
558
-        } else {
559
-            throw new EE_Error(
560
-                sprintf(
561
-                    esc_html__(
562
-                        'Gateway for payment method type "%s" is "%s", not a subclass of either EE_Offsite_Gateway or EE_Onsite_Gateway, or null (to indicate NO gateway)',
563
-                        'event_espresso'
564
-                    ),
565
-                    get_class($this),
566
-                    gettype($this->_gateway)
567
-                )
568
-            );
569
-        }
570
-        return $payment;
571
-    }
572
-
573
-
574
-    /**
575
-     * Gets the values we want to pass onto the gateway. Normally these
576
-     * are just the 'pretty' values, but there may be times the data may need
577
-     * a  little massaging. Proper subsections will become arrays of inputs
578
-     *
579
-     * @param EE_Billing_Info_Form|null $billing_form
580
-     * @return array
581
-     * @throws EE_Error
582
-     */
583
-    protected function _get_billing_values_from_form($billing_form)
584
-    {
585
-        return $billing_form instanceof EE_Form_Section_Proper
586
-            ? $billing_form->input_pretty_values(true)
587
-            : [];
588
-    }
589
-
590
-
591
-    /**
592
-     * Handles an instant payment notification when the transaction is known (by default).
593
-     *
594
-     * @param array          $req_data
595
-     * @param EE_Transaction $transaction
596
-     * @return EE_Payment
597
-     * @throws EE_Error
598
-     * @throws ReflectionException
599
-     */
600
-    public function handle_ipn(array $req_data, EE_Transaction $transaction): EE_Payment
601
-    {
602
-        $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction);
603
-        if (! $this->_gateway instanceof EE_Offsite_Gateway) {
604
-            throw new EE_Error(
605
-                sprintf(
606
-                    esc_html__("Could not handle IPN because '%s' is not an offsite gateway", "event_espresso"),
607
-                    print_r($this->_gateway, true)
608
-                )
609
-            );
610
-        }
611
-        return $this->_gateway->handle_payment_update($req_data, $transaction);
612
-    }
613
-
614
-
615
-    /**
616
-     * Saves the billing info onto the attendee of the primary registrant on this transaction, and
617
-     * cleans it first.
618
-     *
619
-     * @param EE_Billing_Attendee_Info_Form $billing_form
620
-     * @param EE_Transaction|null           $transaction
621
-     * @return boolean success
622
-     * @throws EE_Error
623
-     * @throws ReflectionException
624
-     */
625
-    protected function _save_billing_info_to_attendee(
626
-        EE_Billing_Attendee_Info_Form $billing_form,
627
-        ?EE_Transaction $transaction
628
-    ): bool {
629
-        if (! $transaction instanceof EE_Transaction) {
630
-            EE_Error::add_error(
631
-                esc_html__("Cannot save billing info because no transaction was specified", "event_espresso"),
632
-                __FILE__,
633
-                __FUNCTION__,
634
-                __LINE__
635
-            );
636
-            return false;
637
-        }
638
-        $primary_reg = $transaction->primary_registration();
639
-        if (! $primary_reg) {
640
-            EE_Error::add_error(
641
-                esc_html__(
642
-                    "Cannot save billing info because the transaction has no primary registration",
643
-                    "event_espresso"
644
-                ),
645
-                __FILE__,
646
-                __FUNCTION__,
647
-                __LINE__
648
-            );
649
-            return false;
650
-        }
651
-        $attendee = $primary_reg->attendee();
652
-        if (! $attendee) {
653
-            EE_Error::add_error(
654
-                esc_html__(
655
-                    "Cannot save billing info because the transaction's primary registration has no attendee!",
656
-                    "event_espresso"
657
-                ),
658
-                __FILE__,
659
-                __FUNCTION__,
660
-                __LINE__
661
-            );
662
-            return false;
663
-        }
664
-        return $attendee->save_and_clean_billing_info_for_payment_method($billing_form, $transaction->payment_method());
665
-    }
666
-
667
-
668
-    /**
669
-     * Gets the payment this IPN is for. Children may often want to
670
-     * override this to inspect the request
671
-     *
672
-     * @param EE_Transaction $transaction
673
-     * @param array          $req_data
674
-     * @return EE_Payment
675
-     * @throws EE_Error
676
-     * @throws ReflectionException
677
-     */
678
-    protected function find_payment_for_ipn(EE_Transaction $transaction, array $req_data = []): EE_Payment
679
-    {
680
-        return $transaction->last_payment();
681
-    }
682
-
683
-
684
-    /**
685
-     * In case generic code cannot provide the payment processor with a specific payment method
686
-     * and transaction, it will try calling this method on each activate payment method.
687
-     * If the payment method is able to identify the request as being for it, it should fetch
688
-     * the payment it's for and return it. If not, it should throw an EE_Error to indicate it cannot
689
-     * handle the IPN
690
-     *
691
-     * @param array $req_data
692
-     * @return EE_Payment only if this payment method can find the info its needs from $req_data
693
-     * and identifies the IPN as being for this payment method (not just fo ra payment method of this type)
694
-     * @throws EE_Error
695
-     */
696
-    public function handle_unclaimed_ipn(array $req_data = []): EE_Payment
697
-    {
698
-        throw new EE_Error(
699
-            sprintf(
700
-                esc_html__("Payment Method '%s' cannot handle unclaimed IPNs", "event_espresso"),
701
-                get_class($this)
702
-            )
703
-        );
704
-    }
705
-
706
-
707
-    /**
708
-     * Logic to be accomplished when the payment attempt is complete.
709
-     * Most payment methods don't need to do anything at this point; but some, like Mijireh, do.
710
-     * (Mijireh is an offsite gateway which doesn't send an IPN. So when the user returns to EE from
711
-     * mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status
712
-     * of the payment). Fed a transaction because it's always assumed to be the last payment that
713
-     * we're dealing with. Returns that last payment (if there is one)
714
-     *
715
-     * @param EE_Transaction $transaction
716
-     * @return EE_Payment|null
717
-     * @throws EE_Error
718
-     * @throws ReflectionException
719
-     */
720
-    public function finalize_payment_for(EE_Transaction $transaction): ?EE_Payment
721
-    {
722
-        return $transaction->last_payment();
723
-    }
724
-
725
-
726
-    /**
727
-     * Whether this payment method's gateway supports sending refund requests
728
-     *
729
-     * @return boolean
730
-     */
731
-    public function supports_sending_refunds(): bool
732
-    {
733
-        return $this->_gateway instanceof EE_Gateway && $this->_gateway->supports_sending_refunds();
734
-    }
735
-
736
-
737
-    /**
738
-     * @param EE_Payment $payment
739
-     * @param array      $refund_info
740
-     * @return EE_Payment
741
-     * @throws EE_Error
742
-     */
743
-    public function process_refund(EE_Payment $payment, array $refund_info = []): EE_Payment
744
-    {
745
-        if ($this->_gateway instanceof EE_Gateway) {
746
-            return $this->_gateway->do_direct_refund($payment, $refund_info);
747
-        } else {
748
-            throw new EE_Error(
749
-                sprintf(
750
-                    esc_html__('Payment Method Type "%s" does not support sending refund requests', 'event_espresso'),
751
-                    get_class($this)
752
-                )
753
-            );
754
-        }
755
-    }
756
-
757
-
758
-    /**
759
-     * Returns one the class's constants onsite,offsite, or offline, depending on this
760
-     * payment method's gateway.
761
-     *
762
-     * @return string
763
-     * @throws EE_Error
764
-     */
765
-    public function payment_occurs(): string
766
-    {
767
-        if (! $this->_gateway) {
768
-            return EE_PMT_Base::offline;
769
-        }
770
-        if ($this->_gateway instanceof EE_Onsite_Gateway) {
771
-            return EE_PMT_Base::onsite;
772
-        }
773
-        if ($this->_gateway instanceof EE_Offsite_Gateway) {
774
-            return EE_PMT_Base::offsite;
775
-        }
776
-        throw new EE_Error(
777
-            sprintf(
778
-                esc_html__(
779
-                    "Payment method type '%s's gateway isn't an instance of EE_Onsite_Gateway, EE_Offsite_Gateway, or null. It must be one of those",
780
-                    "event_espresso"
781
-                ),
782
-                get_class($this)
783
-            )
784
-        );
785
-    }
786
-
787
-
788
-    /**
789
-     * For adding any html output ab ove the payment overview.
790
-     * Many gateways won't want ot display anything, so this function just returns an empty string.
791
-     * Other gateways may want to override this, such as offline gateways.
792
-     *
793
-     * @param EE_Payment $payment
794
-     * @return string
795
-     */
796
-    public function payment_overview_content(EE_Payment $payment)
797
-    {
798
-        return EEH_Template::display_template(
799
-            EE_LIBRARIES . 'payment_methods/templates/payment_details_content.template.php',
800
-            ['payment_method' => $this->_pm_instance, 'payment' => $payment],
801
-            true
802
-        );
803
-    }
804
-
805
-
806
-    /**
807
-     * @return array where keys are the help tab name,
808
-     * values are: array {
809
-     * @type string $title         i18n name for the help tab
810
-     * @type string $filename      name of the file located in ./help_tabs/ (ie, in a folder next to this file)
811
-     * @type array  $template_args any arguments you want passed to the template file while rendering.
812
-     *                             Keys will be variable names and values with be their values.
813
-     */
814
-    public function help_tabs_config()
815
-    {
816
-        return [];
817
-    }
818
-
819
-
820
-    /**
821
-     * The system name for this PMT (eg AIM, Paypal_Pro, Invoice... what gets put into
822
-     * the payment method's table's PMT_type column)
823
-     *
824
-     * @return string
825
-     */
826
-    public function system_name()
827
-    {
828
-        $classname = get_class($this);
829
-        return str_replace("EE_PMT_", '', $classname);
830
-    }
831
-
832
-
833
-    /**
834
-     * A pretty i18n version of the PMT name. Often the same as the "pretty_name", but you can change it by overriding
835
-     * this method.
836
-     *
837
-     * @return string|null
838
-     */
839
-    public function defaultFrontendName()
840
-    {
841
-        return $this->pretty_name();
842
-    }
843
-
844
-
845
-    /**
846
-     * A pretty i18n version of the PMT name
847
-     *
848
-     * @return string|null
849
-     */
850
-    public function pretty_name(): ?string
851
-    {
852
-        return $this->_pretty_name;
853
-    }
854
-
855
-
856
-    /**
857
-     * Gets the default absolute URL to the payment method type's button
858
-     *
859
-     * @return string|null
860
-     */
861
-    public function default_button_url(): ?string
862
-    {
863
-        return $this->_default_button_url;
864
-    }
865
-
866
-
867
-    /**
868
-     * Gets the gateway used by this payment method (if any)
869
-     *
870
-     * @return EE_Gateway
871
-     */
872
-    public function get_gateway(): ?EE_Gateway
873
-    {
874
-        return $this->_gateway;
875
-    }
876
-
877
-
878
-    /**
879
-     * @return string html for the link to a help tab
880
-     */
881
-    public function get_help_tab_link(): string
882
-    {
883
-        return EEH_Template::get_help_tab_link(
884
-            $this->get_help_tab_name(),
885
-            'espresso_payment_settings',
886
-            'default'
887
-        );
888
-    }
889
-
890
-
891
-    /**
892
-     * Returns the name of the help tab for this PMT
893
-     *
894
-     * @return string
895
-     */
896
-    public function get_help_tab_name(): string
897
-    {
898
-        return 'ee_' . strtolower($this->system_name()) . '_help_tab';
899
-    }
900
-
901
-
902
-    /**
903
-     * The name of the wp capability that should be associated with the usage of
904
-     * this PMT by an admin
905
-     *
906
-     * @return string
907
-     */
908
-    public function cap_name(): string
909
-    {
910
-        return 'ee_payment_method_' . strtolower($this->system_name());
911
-    }
912
-
913
-
914
-    /**
915
-     * Called by client code to tell the gateway that if it wants to change
916
-     * the transaction or line items or registrations related to teh payment it already
917
-     * processed (we think, but possibly not) that now's the time to do it.
918
-     * It is expected that gateways will store any info they need for this on the PAY_details,
919
-     * or maybe an extra meta value
920
-     *
921
-     * @param EE_Payment $payment
922
-     * @return void
923
-     */
924
-    public function update_txn_based_on_payment($payment)
925
-    {
926
-        if ($this->_gateway instanceof EE_Gateway) {
927
-            $this->_gateway->update_txn_based_on_payment($payment);
928
-        }
929
-    }
930
-
931
-
932
-    /**
933
-     * Returns a string of HTML describing this payment method type for an admin,
934
-     * primarily intended for them to read before activating it.
935
-     * The easiest way to set this is to create a folder 'templates' alongside
936
-     * your EE_PMT_{System_Name} file, and in it create a file named "{system_name}_intro.template.php".
937
-     * Eg, if your payment method file is named "EE_PMT_Foo_Bar.pm.php",
938
-     * then you'd create a file named "templates" in the same folder as it, and name the file
939
-     * "foo_bar_intro.template.php", and its content will be returned by this method
940
-     *
941
-     * @return string
942
-     */
943
-    public function introductory_html(): string
944
-    {
945
-        return EEH_Template::locate_template(
946
-            $this->file_folder() . 'templates/' . strtolower($this->system_name()) . '_intro.template.php',
947
-            ['pmt_obj' => $this, 'pm_instance' => $this->_pm_instance]
948
-        );
949
-    }
19
+	const onsite  = 'on-site';
20
+
21
+	const offsite = 'off-site';
22
+
23
+	const offline = 'off-line';
24
+
25
+	protected ?EE_Payment_Method $_pm_instance = null;
26
+
27
+	protected ?EE_Gateway $_gateway = null;
28
+
29
+	protected ?EE_Payment_Method_Form $_settings_form = null;
30
+
31
+	protected ?EE_Form_Section_Proper $_billing_form = null;
32
+
33
+	protected bool $_cache_billing_form = true;
34
+
35
+	protected ?bool $_has_billing_form;
36
+
37
+	protected bool $_requires_https = false;
38
+
39
+	/**
40
+	 * String of the absolute path to the folder containing this file, with a trailing slash.
41
+	 * eg '/public_html/wp-site/wp-content/plugins/event-espresso/payment_methods/Invoice/'
42
+	 *
43
+	 * @var string|null
44
+	 */
45
+	protected $_file_folder = null;
46
+
47
+	/**
48
+	 * String to the absolute URL to this file (useful for getting its web-accessible resources
49
+	 * like images, js, or css)
50
+	 *
51
+	 * @var string|null
52
+	 */
53
+	protected $_file_url = null;
54
+
55
+	/**
56
+	 * Pretty name for the payment method
57
+	 *
58
+	 * @var string|null
59
+	 */
60
+	protected $_pretty_name = null;
61
+
62
+	/**
63
+	 * @var string|null
64
+	 */
65
+	protected $_default_button_url = null;
66
+
67
+	/**
68
+	 * @var string|null
69
+	 */
70
+	protected $_default_description = null;
71
+
72
+	/**
73
+	 * @var string|null
74
+	 */
75
+	protected $_template_path = null;
76
+
77
+
78
+	/**
79
+	 * @param EE_Payment_Method|null $pm_instance
80
+	 * @throws ReflectionException
81
+	 * @throws EE_Error
82
+	 */
83
+	public function __construct($pm_instance = null)
84
+	{
85
+		if ($pm_instance instanceof EE_Payment_Method) {
86
+			$this->set_instance($pm_instance);
87
+		}
88
+		if ($this->_gateway) {
89
+			$this->_gateway->set_payment_model(EEM_Payment::instance());
90
+			$this->_gateway->set_payment_log(EEM_Change_Log::instance());
91
+			$this->_gateway->set_template_helper(new EEH_Template());
92
+			$this->_gateway->set_line_item_helper(new EEH_Line_Item());
93
+			$this->_gateway->set_money_helper(new EEH_Money());
94
+			$this->_gateway->set_gateway_data_formatter(new GatewayDataFormatter());
95
+			$this->_gateway->set_unsupported_character_remover(new AsciiOnly());
96
+			do_action('AHEE__EE_PMT_Base___construct__done_initializing_gateway_class', $this, $this->_gateway);
97
+		}
98
+		if (! isset($this->_has_billing_form)) {
99
+			// by default, On Site gateways have a billing form
100
+			if ($this->payment_occurs() == EE_PMT_Base::onsite) {
101
+				$this->set_has_billing_form(true);
102
+			} else {
103
+				$this->set_has_billing_form(false);
104
+			}
105
+		}
106
+
107
+		if (! $this->_pretty_name) {
108
+			throw new EE_Error(
109
+				esc_html__(
110
+					'You must set the pretty name for the Payment Method Type in the constructor (_pretty_name), and please make it internationalized',
111
+					'event_espresso'
112
+				)
113
+			);
114
+		}
115
+		// if the child didn't specify a default button, use the credit card one
116
+		if ($this->_default_button_url === null) {
117
+			$this->_default_button_url = EE_PLUGIN_DIR_URL . 'payment_methods/pay-by-credit-card.png';
118
+		}
119
+	}
120
+
121
+
122
+	/**
123
+	 * @param bool|int|string $has_billing_form
124
+	 */
125
+	public function set_has_billing_form($has_billing_form)
126
+	{
127
+		$this->_has_billing_form = filter_var($has_billing_form, FILTER_VALIDATE_BOOLEAN);
128
+	}
129
+
130
+
131
+	/**
132
+	 * sets the file_folder property
133
+	 */
134
+	protected function _set_file_folder()
135
+	{
136
+		$reflector          = new ReflectionClass(get_class($this));
137
+		$fn                 = $reflector->getFileName();
138
+		$this->_file_folder = dirname($fn) . '/';
139
+	}
140
+
141
+
142
+	/**
143
+	 * sets the file URL with a trailing slash for this PMT
144
+	 */
145
+	protected function _set_file_url()
146
+	{
147
+		$plugins_dir_fixed = str_replace('\\', '/', WP_PLUGIN_DIR);
148
+		$file_folder_fixed = str_replace('\\', '/', $this->file_folder());
149
+		$file_path         = str_replace($plugins_dir_fixed, WP_PLUGIN_URL, $file_folder_fixed);
150
+		$this->_file_url   = set_url_scheme($file_path);
151
+	}
152
+
153
+
154
+	/**
155
+	 * Gets the default description on all payment methods of this type
156
+	 *
157
+	 * @return string
158
+	 */
159
+	public function default_description(): ?string
160
+	{
161
+		return $this->_default_description;
162
+	}
163
+
164
+
165
+	/**
166
+	 * Returns the folder containing the PMT child class, with a trailing slash
167
+	 *
168
+	 * @return string
169
+	 */
170
+	public function file_folder(): ?string
171
+	{
172
+		if (! $this->_file_folder) {
173
+			$this->_set_file_folder();
174
+		}
175
+		return $this->_file_folder;
176
+	}
177
+
178
+
179
+	/**
180
+	 * @return string
181
+	 */
182
+	public function file_url(): ?string
183
+	{
184
+		if (! $this->_file_url) {
185
+			$this->_set_file_url();
186
+		}
187
+		return $this->_file_url;
188
+	}
189
+
190
+
191
+	/**
192
+	 * Sets the payment method instance this payment method type is for.
193
+	 * Its important teh payment method instance is set before
194
+	 *
195
+	 * @param EE_Payment_Method $payment_method_instance
196
+	 * @throws EE_Error
197
+	 * @throws ReflectionException
198
+	 */
199
+	public function set_instance(EE_Payment_Method $payment_method_instance)
200
+	{
201
+		$this->_pm_instance = $payment_method_instance;
202
+		// if they have already requested the settings form, make sure its
203
+		// data matches this model object
204
+		if ($this->_settings_form) {
205
+			$this->settings_form()->populate_model_obj($payment_method_instance);
206
+		}
207
+		if ($this->_gateway instanceof EE_Gateway) {
208
+			$this->_gateway->set_settings($payment_method_instance->settings_array());
209
+		}
210
+	}
211
+
212
+
213
+	/**
214
+	 * Gets teh form for displaying to admins where they set up the payment method
215
+	 *
216
+	 * @return EE_Payment_Method_Form
217
+	 * @throws EE_Error
218
+	 * @throws ReflectionException
219
+	 */
220
+	public function settings_form(): EE_Payment_Method_Form
221
+	{
222
+		if (! $this->_settings_form) {
223
+			$this->_settings_form = $this->generate_new_settings_form();
224
+			$this->_settings_form->set_payment_method_type($this);
225
+			// if we have already assigned a model object to this pmt, make
226
+			// sure it's reflected in the form we just generated
227
+			if ($this->_pm_instance) {
228
+				$this->_settings_form->populate_model_obj($this->_pm_instance);
229
+			}
230
+		}
231
+		return $this->_settings_form;
232
+	}
233
+
234
+
235
+	/**
236
+	 * Gets the form for all the settings related to this payment method type
237
+	 *
238
+	 * @return EE_Payment_Method_Form
239
+	 */
240
+	abstract public function generate_new_settings_form();
241
+
242
+
243
+	/**
244
+	 * Sets the form for settings. This may be useful if we have already received
245
+	 * a form submission and have form data it in, and want to use it anytime we're showing
246
+	 * this payment method type's settings form later in the request
247
+	 *
248
+	 * @param EE_Payment_Method_Form $form
249
+	 */
250
+	public function set_settings_form(EE_Payment_Method_Form $form)
251
+	{
252
+		$this->_settings_form = $form;
253
+	}
254
+
255
+
256
+	/**
257
+	 * @return boolean
258
+	 */
259
+	public function has_billing_form(): bool
260
+	{
261
+		return $this->_has_billing_form;
262
+	}
263
+
264
+
265
+	/**
266
+	 * Gets the form for displaying to attendees where they can enter their billing info
267
+	 * which will be sent to teh gateway (can be null)
268
+	 *
269
+	 * @param EE_Transaction|null $transaction
270
+	 * @param array               $extra_args
271
+	 * @return EE_Billing_Attendee_Info_Form|EE_Billing_Info_Form|null
272
+	 * @throws EE_Error
273
+	 * @throws ReflectionException
274
+	 */
275
+	public function billing_form(EE_Transaction $transaction = null, array $extra_args = [])
276
+	{
277
+		// has billing form already been regenerated ? or overwrite cache?
278
+		if (! $this->_billing_form instanceof EE_Billing_Info_Form || ! $this->_cache_billing_form) {
279
+			$this->_billing_form = $this->generate_new_billing_form($transaction, $extra_args);
280
+		}
281
+		// if we know who the attendee is, and this is a billing form
282
+		// that uses attendee info, populate it
283
+		if (
284
+			apply_filters(
285
+				'FHEE__populate_billing_form_fields_from_attendee',
286
+				(
287
+					$this->_billing_form instanceof EE_Billing_Attendee_Info_Form
288
+					&& $transaction instanceof EE_Transaction
289
+					&& $transaction->primary_registration() instanceof EE_Registration
290
+					&& $transaction->primary_registration()->attendee() instanceof EE_Attendee
291
+				),
292
+				$this->_billing_form,
293
+				$transaction
294
+			)
295
+		) {
296
+			$this->_billing_form->populate_from_attendee($transaction->primary_registration()->attendee());
297
+		}
298
+		return $this->_billing_form;
299
+	}
300
+
301
+
302
+	/**
303
+	 * Creates the billing form for this payment method type
304
+	 *
305
+	 * @param EE_Transaction|null $transaction
306
+	 * @return EE_Billing_Info_Form|null
307
+	 */
308
+	abstract public function generate_new_billing_form(EE_Transaction $transaction = null);
309
+
310
+
311
+	/**
312
+	 * applies debug data to the form
313
+	 *
314
+	 * @param EE_Billing_Info_Form $billing_form
315
+	 * @return EE_Billing_Info_Form|null
316
+	 */
317
+	public function apply_billing_form_debug_settings(EE_Billing_Info_Form $billing_form)
318
+	{
319
+		return $billing_form;
320
+	}
321
+
322
+
323
+	/**
324
+	 * Sets the billing form for this payment method type. You may want to use this
325
+	 * if you have form
326
+	 *
327
+	 * @param EE_Billing_Info_Form $form
328
+	 */
329
+	public function set_billing_form(EE_Billing_Info_Form $form)
330
+	{
331
+		$this->_billing_form = $form;
332
+	}
333
+
334
+
335
+	/**
336
+	 * Returns whether this payment method requires HTTPS to be used
337
+	 *
338
+	 * @return boolean
339
+	 */
340
+	public function requires_https(): bool
341
+	{
342
+		return $this->_requires_https;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @param EE_Transaction            $transaction
348
+	 * @param float|null                $amount
349
+	 * @param EE_Billing_Info_Form|null $billing_info
350
+	 * @param string|null               $return_url
351
+	 * @param string                    $fail_url
352
+	 * @param string                    $method
353
+	 * @param bool                      $by_admin
354
+	 * @return EE_Payment
355
+	 * @throws EE_Error
356
+	 * @throws ReflectionException
357
+	 */
358
+	public function process_payment(
359
+		EE_Transaction $transaction,
360
+		$amount = null,
361
+		$billing_info = null,
362
+		$return_url = null,
363
+		$fail_url = '',
364
+		$method = EEM_Payment_Method::scope_cart,
365
+		$by_admin = false
366
+	) {
367
+		$amount = $amount ?: $transaction->remaining();
368
+		$method = EEM_Payment_Method::instance()->is_valid_scope($method) ? $method : EEM_Payment_Method::scope_cart;
369
+
370
+
371
+		// @todo: add surcharge for the payment method, if any
372
+		if (! $this->_gateway instanceof EE_Gateway) {
373
+			// no gateway provided, must be an offline gateway
374
+			// create a payment object anyways, but don't save it
375
+			// but if there is billing info, clean it and save it first
376
+			if ($billing_info instanceof EE_Billing_Attendee_Info_Form) {
377
+				$this->_save_billing_info_to_attendee($billing_info, $transaction);
378
+			}
379
+			return EE_Payment::new_instance(
380
+				[
381
+					'STS_ID'        => EEM_Payment::status_id_pending,
382
+					'TXN_ID'        => $transaction->ID(),
383
+					'PMD_ID'        => $transaction->payment_method_ID(),
384
+					'PAY_amount'    => 0.00,
385
+					'PAY_timestamp' => time(),
386
+				]
387
+			);
388
+		}
389
+
390
+		$payment = $this->getLastPayment($transaction, $amount, $method);
391
+		$payment = $this->validatePayment($transaction, $payment, $amount, $method);
392
+
393
+		$max_payment_attempts   = apply_filters(
394
+			'FHEE__EE_PMT_Base__process_payment__max_payment_attempts',
395
+			5,
396
+			$transaction
397
+		);
398
+		$previous_payment_count = $this->getPreviousPaymentCount($transaction, $amount, $method);
399
+		// only pass payment to gateway if we haven't exceeded the max attempts
400
+		$payment = $previous_payment_count < $max_payment_attempts
401
+			? $this->passPaymentToGateway($payment, $transaction, $billing_info, $return_url, $fail_url)
402
+			: $payment;
403
+
404
+		// if there is billing info, clean it and save it
405
+		if ($billing_info instanceof EE_Billing_Attendee_Info_Form) {
406
+			$this->_save_billing_info_to_attendee($billing_info, $transaction);
407
+		}
408
+
409
+		return $payment;
410
+	}
411
+
412
+
413
+	/**
414
+	 * Checks for any existing payments that are in a failed state for the same TXN, amount, and method
415
+	 *
416
+	 * @param EE_Transaction $transaction
417
+	 * @param float          $amount
418
+	 * @param string         $method
419
+	 * @return EE_Payment|null
420
+	 * @throws EE_Error
421
+	 * @throws ReflectionException
422
+	 * @since 5.0.28.p
423
+	 */
424
+	private function getLastPayment(EE_Transaction $transaction, float $amount, string $method): ?EE_Payment
425
+	{
426
+		return EEM_Payment::instance()->get_one(
427
+			[
428
+				[
429
+					'STS_ID'     => EEM_Payment::status_id_failed,
430
+					'TXN_ID'     => $transaction->ID(),
431
+					'PMD_ID'     => $this->_pm_instance->ID(),
432
+					'PAY_source' => $method,
433
+					'PAY_amount' => $amount,
434
+				],
435
+			]
436
+		);
437
+	}
438
+
439
+
440
+	/**
441
+	 * IF the last payment was not a failed payment
442
+	 * (which indicates a payment in progress that has yet to be updated),
443
+	 * then create a new payment, otherwise just return the existing payment,
444
+	 * but save it to ensure it has an ID
445
+	 *
446
+	 * @param EE_Transaction  $transaction
447
+	 * @param EE_Payment|null $payment
448
+	 * @param float           $amount
449
+	 * @param string          $method
450
+	 * @return EE_Payment
451
+	 * @throws EE_Error
452
+	 * @throws ReflectionException
453
+	 * @since 5.0.28.p
454
+	 */
455
+	private function validatePayment(
456
+		EE_Transaction $transaction,
457
+		?EE_Payment $payment,
458
+		float $amount,
459
+		string $method
460
+	): EE_Payment {
461
+		if (! $payment instanceof EE_Payment || ! $payment->is_failed()) {
462
+			$payment = EE_Payment::new_instance(
463
+				[
464
+					'PAY_amount'           => $amount,
465
+					'PAY_details'          => null,
466
+					'PAY_extra_accntng'    => null,
467
+					'PAY_gateway_response' => null,
468
+					'PAY_po_number'        => null,
469
+					'PAY_source'           => $method,
470
+					'PAY_timestamp'        => time(),
471
+					'PAY_txn_id_chq_nmbr'  => null,
472
+					'PMD_ID'               => $this->_pm_instance->ID(),
473
+					'STS_ID'               => EEM_Payment::status_id_failed,
474
+					'TXN_ID'               => $transaction->ID(),
475
+				]
476
+			);
477
+		}
478
+		// make sure the payment has been saved to show we started it,
479
+		// and so it has an ID should the gateway try to log it
480
+		$payment->save();
481
+
482
+		return $payment;
483
+	}
484
+
485
+
486
+	/**
487
+	 * Checks for any existing payments that are in a failed state for the same TXN, amount, and method
488
+	 *
489
+	 * @param EE_Transaction $transaction
490
+	 * @param float          $amount
491
+	 * @param string         $method
492
+	 * @return int
493
+	 * @throws EE_Error
494
+	 * @throws ReflectionException
495
+	 * @since 5.0.28.p
496
+	 */
497
+	private function getPreviousPaymentCount(EE_Transaction $transaction, float $amount, string $method): int
498
+	{
499
+		return EEM_Payment::instance()->count(
500
+			[
501
+				[
502
+					'STS_ID'     => [
503
+						'IN',
504
+						[
505
+							EEM_Payment::status_id_pending,
506
+							EEM_Payment::status_id_cancelled,
507
+							EEM_Payment::status_id_declined,
508
+							EEM_Payment::status_id_failed,
509
+						],
510
+					],
511
+					'TXN_ID'     => $transaction->ID(),
512
+					'PMD_ID'     => $this->_pm_instance->ID(),
513
+					'PAY_source' => $method,
514
+					'PAY_amount' => $amount,
515
+				],
516
+				'order_by' => ['PAY_timestamp' => 'DESC'],
517
+			]
518
+		);
519
+	}
520
+
521
+
522
+	/**
523
+	 * @param EE_Payment                $payment
524
+	 * @param EE_Transaction            $transaction
525
+	 * @param EE_Billing_Info_Form|null $billing_info
526
+	 * @param string|null               $return_url
527
+	 * @param string|null               $fail_url
528
+	 * @return EE_Payment
529
+	 * @throws EE_Error
530
+	 * @throws ReflectionException
531
+	 * @since 5.0.28.p
532
+	 */
533
+	private function passPaymentToGateway(
534
+		EE_Payment $payment,
535
+		EE_Transaction $transaction,
536
+		?EE_Billing_Info_Form $billing_info,
537
+		?string $return_url = null,
538
+		?string $fail_url = ''
539
+	): EE_Payment {
540
+		$billing_values = $this->_get_billing_values_from_form($billing_info);
541
+		if ($this->_gateway instanceof EE_Offsite_Gateway) {
542
+			$payment = $this->_gateway->set_redirection_info(
543
+				$payment,
544
+				$billing_values,
545
+				$return_url,
546
+				EE_Config::instance()->core->txn_page_url(
547
+					[
548
+						'e_reg_url_link'    => $transaction->primary_registration()->reg_url_link(),
549
+						'ee_payment_method' => $this->_pm_instance->slug(),
550
+					]
551
+				),
552
+				$fail_url
553
+			);
554
+			$payment->save();
555
+		} elseif ($this->_gateway instanceof EE_Onsite_Gateway) {
556
+			$payment = $this->_gateway->do_direct_payment($payment, $billing_values);
557
+			$payment->save();
558
+		} else {
559
+			throw new EE_Error(
560
+				sprintf(
561
+					esc_html__(
562
+						'Gateway for payment method type "%s" is "%s", not a subclass of either EE_Offsite_Gateway or EE_Onsite_Gateway, or null (to indicate NO gateway)',
563
+						'event_espresso'
564
+					),
565
+					get_class($this),
566
+					gettype($this->_gateway)
567
+				)
568
+			);
569
+		}
570
+		return $payment;
571
+	}
572
+
573
+
574
+	/**
575
+	 * Gets the values we want to pass onto the gateway. Normally these
576
+	 * are just the 'pretty' values, but there may be times the data may need
577
+	 * a  little massaging. Proper subsections will become arrays of inputs
578
+	 *
579
+	 * @param EE_Billing_Info_Form|null $billing_form
580
+	 * @return array
581
+	 * @throws EE_Error
582
+	 */
583
+	protected function _get_billing_values_from_form($billing_form)
584
+	{
585
+		return $billing_form instanceof EE_Form_Section_Proper
586
+			? $billing_form->input_pretty_values(true)
587
+			: [];
588
+	}
589
+
590
+
591
+	/**
592
+	 * Handles an instant payment notification when the transaction is known (by default).
593
+	 *
594
+	 * @param array          $req_data
595
+	 * @param EE_Transaction $transaction
596
+	 * @return EE_Payment
597
+	 * @throws EE_Error
598
+	 * @throws ReflectionException
599
+	 */
600
+	public function handle_ipn(array $req_data, EE_Transaction $transaction): EE_Payment
601
+	{
602
+		$transaction = EEM_Transaction::instance()->ensure_is_obj($transaction);
603
+		if (! $this->_gateway instanceof EE_Offsite_Gateway) {
604
+			throw new EE_Error(
605
+				sprintf(
606
+					esc_html__("Could not handle IPN because '%s' is not an offsite gateway", "event_espresso"),
607
+					print_r($this->_gateway, true)
608
+				)
609
+			);
610
+		}
611
+		return $this->_gateway->handle_payment_update($req_data, $transaction);
612
+	}
613
+
614
+
615
+	/**
616
+	 * Saves the billing info onto the attendee of the primary registrant on this transaction, and
617
+	 * cleans it first.
618
+	 *
619
+	 * @param EE_Billing_Attendee_Info_Form $billing_form
620
+	 * @param EE_Transaction|null           $transaction
621
+	 * @return boolean success
622
+	 * @throws EE_Error
623
+	 * @throws ReflectionException
624
+	 */
625
+	protected function _save_billing_info_to_attendee(
626
+		EE_Billing_Attendee_Info_Form $billing_form,
627
+		?EE_Transaction $transaction
628
+	): bool {
629
+		if (! $transaction instanceof EE_Transaction) {
630
+			EE_Error::add_error(
631
+				esc_html__("Cannot save billing info because no transaction was specified", "event_espresso"),
632
+				__FILE__,
633
+				__FUNCTION__,
634
+				__LINE__
635
+			);
636
+			return false;
637
+		}
638
+		$primary_reg = $transaction->primary_registration();
639
+		if (! $primary_reg) {
640
+			EE_Error::add_error(
641
+				esc_html__(
642
+					"Cannot save billing info because the transaction has no primary registration",
643
+					"event_espresso"
644
+				),
645
+				__FILE__,
646
+				__FUNCTION__,
647
+				__LINE__
648
+			);
649
+			return false;
650
+		}
651
+		$attendee = $primary_reg->attendee();
652
+		if (! $attendee) {
653
+			EE_Error::add_error(
654
+				esc_html__(
655
+					"Cannot save billing info because the transaction's primary registration has no attendee!",
656
+					"event_espresso"
657
+				),
658
+				__FILE__,
659
+				__FUNCTION__,
660
+				__LINE__
661
+			);
662
+			return false;
663
+		}
664
+		return $attendee->save_and_clean_billing_info_for_payment_method($billing_form, $transaction->payment_method());
665
+	}
666
+
667
+
668
+	/**
669
+	 * Gets the payment this IPN is for. Children may often want to
670
+	 * override this to inspect the request
671
+	 *
672
+	 * @param EE_Transaction $transaction
673
+	 * @param array          $req_data
674
+	 * @return EE_Payment
675
+	 * @throws EE_Error
676
+	 * @throws ReflectionException
677
+	 */
678
+	protected function find_payment_for_ipn(EE_Transaction $transaction, array $req_data = []): EE_Payment
679
+	{
680
+		return $transaction->last_payment();
681
+	}
682
+
683
+
684
+	/**
685
+	 * In case generic code cannot provide the payment processor with a specific payment method
686
+	 * and transaction, it will try calling this method on each activate payment method.
687
+	 * If the payment method is able to identify the request as being for it, it should fetch
688
+	 * the payment it's for and return it. If not, it should throw an EE_Error to indicate it cannot
689
+	 * handle the IPN
690
+	 *
691
+	 * @param array $req_data
692
+	 * @return EE_Payment only if this payment method can find the info its needs from $req_data
693
+	 * and identifies the IPN as being for this payment method (not just fo ra payment method of this type)
694
+	 * @throws EE_Error
695
+	 */
696
+	public function handle_unclaimed_ipn(array $req_data = []): EE_Payment
697
+	{
698
+		throw new EE_Error(
699
+			sprintf(
700
+				esc_html__("Payment Method '%s' cannot handle unclaimed IPNs", "event_espresso"),
701
+				get_class($this)
702
+			)
703
+		);
704
+	}
705
+
706
+
707
+	/**
708
+	 * Logic to be accomplished when the payment attempt is complete.
709
+	 * Most payment methods don't need to do anything at this point; but some, like Mijireh, do.
710
+	 * (Mijireh is an offsite gateway which doesn't send an IPN. So when the user returns to EE from
711
+	 * mijireh, this method needs to be called so the Mijireh PM can ping Mijireh to know the status
712
+	 * of the payment). Fed a transaction because it's always assumed to be the last payment that
713
+	 * we're dealing with. Returns that last payment (if there is one)
714
+	 *
715
+	 * @param EE_Transaction $transaction
716
+	 * @return EE_Payment|null
717
+	 * @throws EE_Error
718
+	 * @throws ReflectionException
719
+	 */
720
+	public function finalize_payment_for(EE_Transaction $transaction): ?EE_Payment
721
+	{
722
+		return $transaction->last_payment();
723
+	}
724
+
725
+
726
+	/**
727
+	 * Whether this payment method's gateway supports sending refund requests
728
+	 *
729
+	 * @return boolean
730
+	 */
731
+	public function supports_sending_refunds(): bool
732
+	{
733
+		return $this->_gateway instanceof EE_Gateway && $this->_gateway->supports_sending_refunds();
734
+	}
735
+
736
+
737
+	/**
738
+	 * @param EE_Payment $payment
739
+	 * @param array      $refund_info
740
+	 * @return EE_Payment
741
+	 * @throws EE_Error
742
+	 */
743
+	public function process_refund(EE_Payment $payment, array $refund_info = []): EE_Payment
744
+	{
745
+		if ($this->_gateway instanceof EE_Gateway) {
746
+			return $this->_gateway->do_direct_refund($payment, $refund_info);
747
+		} else {
748
+			throw new EE_Error(
749
+				sprintf(
750
+					esc_html__('Payment Method Type "%s" does not support sending refund requests', 'event_espresso'),
751
+					get_class($this)
752
+				)
753
+			);
754
+		}
755
+	}
756
+
757
+
758
+	/**
759
+	 * Returns one the class's constants onsite,offsite, or offline, depending on this
760
+	 * payment method's gateway.
761
+	 *
762
+	 * @return string
763
+	 * @throws EE_Error
764
+	 */
765
+	public function payment_occurs(): string
766
+	{
767
+		if (! $this->_gateway) {
768
+			return EE_PMT_Base::offline;
769
+		}
770
+		if ($this->_gateway instanceof EE_Onsite_Gateway) {
771
+			return EE_PMT_Base::onsite;
772
+		}
773
+		if ($this->_gateway instanceof EE_Offsite_Gateway) {
774
+			return EE_PMT_Base::offsite;
775
+		}
776
+		throw new EE_Error(
777
+			sprintf(
778
+				esc_html__(
779
+					"Payment method type '%s's gateway isn't an instance of EE_Onsite_Gateway, EE_Offsite_Gateway, or null. It must be one of those",
780
+					"event_espresso"
781
+				),
782
+				get_class($this)
783
+			)
784
+		);
785
+	}
786
+
787
+
788
+	/**
789
+	 * For adding any html output ab ove the payment overview.
790
+	 * Many gateways won't want ot display anything, so this function just returns an empty string.
791
+	 * Other gateways may want to override this, such as offline gateways.
792
+	 *
793
+	 * @param EE_Payment $payment
794
+	 * @return string
795
+	 */
796
+	public function payment_overview_content(EE_Payment $payment)
797
+	{
798
+		return EEH_Template::display_template(
799
+			EE_LIBRARIES . 'payment_methods/templates/payment_details_content.template.php',
800
+			['payment_method' => $this->_pm_instance, 'payment' => $payment],
801
+			true
802
+		);
803
+	}
804
+
805
+
806
+	/**
807
+	 * @return array where keys are the help tab name,
808
+	 * values are: array {
809
+	 * @type string $title         i18n name for the help tab
810
+	 * @type string $filename      name of the file located in ./help_tabs/ (ie, in a folder next to this file)
811
+	 * @type array  $template_args any arguments you want passed to the template file while rendering.
812
+	 *                             Keys will be variable names and values with be their values.
813
+	 */
814
+	public function help_tabs_config()
815
+	{
816
+		return [];
817
+	}
818
+
819
+
820
+	/**
821
+	 * The system name for this PMT (eg AIM, Paypal_Pro, Invoice... what gets put into
822
+	 * the payment method's table's PMT_type column)
823
+	 *
824
+	 * @return string
825
+	 */
826
+	public function system_name()
827
+	{
828
+		$classname = get_class($this);
829
+		return str_replace("EE_PMT_", '', $classname);
830
+	}
831
+
832
+
833
+	/**
834
+	 * A pretty i18n version of the PMT name. Often the same as the "pretty_name", but you can change it by overriding
835
+	 * this method.
836
+	 *
837
+	 * @return string|null
838
+	 */
839
+	public function defaultFrontendName()
840
+	{
841
+		return $this->pretty_name();
842
+	}
843
+
844
+
845
+	/**
846
+	 * A pretty i18n version of the PMT name
847
+	 *
848
+	 * @return string|null
849
+	 */
850
+	public function pretty_name(): ?string
851
+	{
852
+		return $this->_pretty_name;
853
+	}
854
+
855
+
856
+	/**
857
+	 * Gets the default absolute URL to the payment method type's button
858
+	 *
859
+	 * @return string|null
860
+	 */
861
+	public function default_button_url(): ?string
862
+	{
863
+		return $this->_default_button_url;
864
+	}
865
+
866
+
867
+	/**
868
+	 * Gets the gateway used by this payment method (if any)
869
+	 *
870
+	 * @return EE_Gateway
871
+	 */
872
+	public function get_gateway(): ?EE_Gateway
873
+	{
874
+		return $this->_gateway;
875
+	}
876
+
877
+
878
+	/**
879
+	 * @return string html for the link to a help tab
880
+	 */
881
+	public function get_help_tab_link(): string
882
+	{
883
+		return EEH_Template::get_help_tab_link(
884
+			$this->get_help_tab_name(),
885
+			'espresso_payment_settings',
886
+			'default'
887
+		);
888
+	}
889
+
890
+
891
+	/**
892
+	 * Returns the name of the help tab for this PMT
893
+	 *
894
+	 * @return string
895
+	 */
896
+	public function get_help_tab_name(): string
897
+	{
898
+		return 'ee_' . strtolower($this->system_name()) . '_help_tab';
899
+	}
900
+
901
+
902
+	/**
903
+	 * The name of the wp capability that should be associated with the usage of
904
+	 * this PMT by an admin
905
+	 *
906
+	 * @return string
907
+	 */
908
+	public function cap_name(): string
909
+	{
910
+		return 'ee_payment_method_' . strtolower($this->system_name());
911
+	}
912
+
913
+
914
+	/**
915
+	 * Called by client code to tell the gateway that if it wants to change
916
+	 * the transaction or line items or registrations related to teh payment it already
917
+	 * processed (we think, but possibly not) that now's the time to do it.
918
+	 * It is expected that gateways will store any info they need for this on the PAY_details,
919
+	 * or maybe an extra meta value
920
+	 *
921
+	 * @param EE_Payment $payment
922
+	 * @return void
923
+	 */
924
+	public function update_txn_based_on_payment($payment)
925
+	{
926
+		if ($this->_gateway instanceof EE_Gateway) {
927
+			$this->_gateway->update_txn_based_on_payment($payment);
928
+		}
929
+	}
930
+
931
+
932
+	/**
933
+	 * Returns a string of HTML describing this payment method type for an admin,
934
+	 * primarily intended for them to read before activating it.
935
+	 * The easiest way to set this is to create a folder 'templates' alongside
936
+	 * your EE_PMT_{System_Name} file, and in it create a file named "{system_name}_intro.template.php".
937
+	 * Eg, if your payment method file is named "EE_PMT_Foo_Bar.pm.php",
938
+	 * then you'd create a file named "templates" in the same folder as it, and name the file
939
+	 * "foo_bar_intro.template.php", and its content will be returned by this method
940
+	 *
941
+	 * @return string
942
+	 */
943
+	public function introductory_html(): string
944
+	{
945
+		return EEH_Template::locate_template(
946
+			$this->file_folder() . 'templates/' . strtolower($this->system_name()) . '_intro.template.php',
947
+			['pmt_obj' => $this, 'pm_instance' => $this->_pm_instance]
948
+		);
949
+	}
950 950
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
             $this->_gateway->set_unsupported_character_remover(new AsciiOnly());
96 96
             do_action('AHEE__EE_PMT_Base___construct__done_initializing_gateway_class', $this, $this->_gateway);
97 97
         }
98
-        if (! isset($this->_has_billing_form)) {
98
+        if ( ! isset($this->_has_billing_form)) {
99 99
             // by default, On Site gateways have a billing form
100 100
             if ($this->payment_occurs() == EE_PMT_Base::onsite) {
101 101
                 $this->set_has_billing_form(true);
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
             }
105 105
         }
106 106
 
107
-        if (! $this->_pretty_name) {
107
+        if ( ! $this->_pretty_name) {
108 108
             throw new EE_Error(
109 109
                 esc_html__(
110 110
                     'You must set the pretty name for the Payment Method Type in the constructor (_pretty_name), and please make it internationalized',
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
         }
115 115
         // if the child didn't specify a default button, use the credit card one
116 116
         if ($this->_default_button_url === null) {
117
-            $this->_default_button_url = EE_PLUGIN_DIR_URL . 'payment_methods/pay-by-credit-card.png';
117
+            $this->_default_button_url = EE_PLUGIN_DIR_URL.'payment_methods/pay-by-credit-card.png';
118 118
         }
119 119
     }
120 120
 
@@ -135,7 +135,7 @@  discard block
 block discarded – undo
135 135
     {
136 136
         $reflector          = new ReflectionClass(get_class($this));
137 137
         $fn                 = $reflector->getFileName();
138
-        $this->_file_folder = dirname($fn) . '/';
138
+        $this->_file_folder = dirname($fn).'/';
139 139
     }
140 140
 
141 141
 
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
      */
170 170
     public function file_folder(): ?string
171 171
     {
172
-        if (! $this->_file_folder) {
172
+        if ( ! $this->_file_folder) {
173 173
             $this->_set_file_folder();
174 174
         }
175 175
         return $this->_file_folder;
@@ -181,7 +181,7 @@  discard block
 block discarded – undo
181 181
      */
182 182
     public function file_url(): ?string
183 183
     {
184
-        if (! $this->_file_url) {
184
+        if ( ! $this->_file_url) {
185 185
             $this->_set_file_url();
186 186
         }
187 187
         return $this->_file_url;
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
      */
220 220
     public function settings_form(): EE_Payment_Method_Form
221 221
     {
222
-        if (! $this->_settings_form) {
222
+        if ( ! $this->_settings_form) {
223 223
             $this->_settings_form = $this->generate_new_settings_form();
224 224
             $this->_settings_form->set_payment_method_type($this);
225 225
             // if we have already assigned a model object to this pmt, make
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
     public function billing_form(EE_Transaction $transaction = null, array $extra_args = [])
276 276
     {
277 277
         // has billing form already been regenerated ? or overwrite cache?
278
-        if (! $this->_billing_form instanceof EE_Billing_Info_Form || ! $this->_cache_billing_form) {
278
+        if ( ! $this->_billing_form instanceof EE_Billing_Info_Form || ! $this->_cache_billing_form) {
279 279
             $this->_billing_form = $this->generate_new_billing_form($transaction, $extra_args);
280 280
         }
281 281
         // if we know who the attendee is, and this is a billing form
@@ -369,7 +369,7 @@  discard block
 block discarded – undo
369 369
 
370 370
 
371 371
         // @todo: add surcharge for the payment method, if any
372
-        if (! $this->_gateway instanceof EE_Gateway) {
372
+        if ( ! $this->_gateway instanceof EE_Gateway) {
373 373
             // no gateway provided, must be an offline gateway
374 374
             // create a payment object anyways, but don't save it
375 375
             // but if there is billing info, clean it and save it first
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
         $payment = $this->getLastPayment($transaction, $amount, $method);
391 391
         $payment = $this->validatePayment($transaction, $payment, $amount, $method);
392 392
 
393
-        $max_payment_attempts   = apply_filters(
393
+        $max_payment_attempts = apply_filters(
394 394
             'FHEE__EE_PMT_Base__process_payment__max_payment_attempts',
395 395
             5,
396 396
             $transaction
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
         float $amount,
459 459
         string $method
460 460
     ): EE_Payment {
461
-        if (! $payment instanceof EE_Payment || ! $payment->is_failed()) {
461
+        if ( ! $payment instanceof EE_Payment || ! $payment->is_failed()) {
462 462
             $payment = EE_Payment::new_instance(
463 463
                 [
464 464
                     'PAY_amount'           => $amount,
@@ -600,7 +600,7 @@  discard block
 block discarded – undo
600 600
     public function handle_ipn(array $req_data, EE_Transaction $transaction): EE_Payment
601 601
     {
602 602
         $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction);
603
-        if (! $this->_gateway instanceof EE_Offsite_Gateway) {
603
+        if ( ! $this->_gateway instanceof EE_Offsite_Gateway) {
604 604
             throw new EE_Error(
605 605
                 sprintf(
606 606
                     esc_html__("Could not handle IPN because '%s' is not an offsite gateway", "event_espresso"),
@@ -626,7 +626,7 @@  discard block
 block discarded – undo
626 626
         EE_Billing_Attendee_Info_Form $billing_form,
627 627
         ?EE_Transaction $transaction
628 628
     ): bool {
629
-        if (! $transaction instanceof EE_Transaction) {
629
+        if ( ! $transaction instanceof EE_Transaction) {
630 630
             EE_Error::add_error(
631 631
                 esc_html__("Cannot save billing info because no transaction was specified", "event_espresso"),
632 632
                 __FILE__,
@@ -636,7 +636,7 @@  discard block
 block discarded – undo
636 636
             return false;
637 637
         }
638 638
         $primary_reg = $transaction->primary_registration();
639
-        if (! $primary_reg) {
639
+        if ( ! $primary_reg) {
640 640
             EE_Error::add_error(
641 641
                 esc_html__(
642 642
                     "Cannot save billing info because the transaction has no primary registration",
@@ -649,7 +649,7 @@  discard block
 block discarded – undo
649 649
             return false;
650 650
         }
651 651
         $attendee = $primary_reg->attendee();
652
-        if (! $attendee) {
652
+        if ( ! $attendee) {
653 653
             EE_Error::add_error(
654 654
                 esc_html__(
655 655
                     "Cannot save billing info because the transaction's primary registration has no attendee!",
@@ -764,7 +764,7 @@  discard block
 block discarded – undo
764 764
      */
765 765
     public function payment_occurs(): string
766 766
     {
767
-        if (! $this->_gateway) {
767
+        if ( ! $this->_gateway) {
768 768
             return EE_PMT_Base::offline;
769 769
         }
770 770
         if ($this->_gateway instanceof EE_Onsite_Gateway) {
@@ -796,7 +796,7 @@  discard block
 block discarded – undo
796 796
     public function payment_overview_content(EE_Payment $payment)
797 797
     {
798 798
         return EEH_Template::display_template(
799
-            EE_LIBRARIES . 'payment_methods/templates/payment_details_content.template.php',
799
+            EE_LIBRARIES.'payment_methods/templates/payment_details_content.template.php',
800 800
             ['payment_method' => $this->_pm_instance, 'payment' => $payment],
801 801
             true
802 802
         );
@@ -895,7 +895,7 @@  discard block
 block discarded – undo
895 895
      */
896 896
     public function get_help_tab_name(): string
897 897
     {
898
-        return 'ee_' . strtolower($this->system_name()) . '_help_tab';
898
+        return 'ee_'.strtolower($this->system_name()).'_help_tab';
899 899
     }
900 900
 
901 901
 
@@ -907,7 +907,7 @@  discard block
 block discarded – undo
907 907
      */
908 908
     public function cap_name(): string
909 909
     {
910
-        return 'ee_payment_method_' . strtolower($this->system_name());
910
+        return 'ee_payment_method_'.strtolower($this->system_name());
911 911
     }
912 912
 
913 913
 
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
     public function introductory_html(): string
944 944
     {
945 945
         return EEH_Template::locate_template(
946
-            $this->file_folder() . 'templates/' . strtolower($this->system_name()) . '_intro.template.php',
946
+            $this->file_folder().'templates/'.strtolower($this->system_name()).'_intro.template.php',
947 947
             ['pmt_obj' => $this, 'pm_instance' => $this->_pm_instance]
948 948
         );
949 949
     }
Please login to merge, or discard this patch.