Completed
Push — 23 ( 340196...de9e92 )
by Harald
08:30 queued 03:42
created

paypal_express   D

Complexity

Total Complexity 137

Size/Duplication

Total Lines 603
Duplicated Lines 24.05 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 145
loc 603
rs 4.8599
c 0
b 0
f 0
wmc 137
lcom 1
cbo 1

21 Methods

Rating   Name   Duplication   Size   Complexity  
F paypal_express() 15 85 35
B update_status() 21 21 7
F checkout_initialization_method() 28 141 21
A javascript_validation() 0 3 1
A selection() 0 4 1
C pre_confirmation_check() 12 23 9
A confirmation() 0 16 3
A process_button() 0 3 1
A before_process() 0 7 2
C before_process_paypal() 14 56 13
C before_process_payflow() 14 45 11
A after_process() 0 7 2
A after_process_paypal() 0 21 1
F after_process_payflow() 31 111 17
A get_error() 0 3 1
A check() 10 10 2
A install() 0 3 1
A remove() 0 3 1
A keys() 0 3 1
A getProductType() 0 11 3
A templateClassExists() 0 3 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like paypal_express often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use paypal_express, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
  $Id$
4
5
  osCommerce, Open Source E-Commerce Solutions
6
  http://www.oscommerce.com
7
8
  Copyright (c) 2017 osCommerce
9
10
  Released under the GNU General Public License
11
*/
12
13
  if ( !class_exists('OSCOM_PayPal') ) {
14
    include(DIR_FS_CATALOG . 'includes/apps/paypal/OSCOM_PayPal.php');
15
  }
16
17
  class paypal_express {
18
    var $code, $title, $description, $enabled, $_app;
19
20
    function paypal_express() {
21
      global $PHP_SELF, $oscTemplate, $order, $payment, $request_type;
22
23
      $this->_app = new OSCOM_PayPal();
24
      $this->_app->loadLanguageFile('modules/EC/EC.php');
25
26
      $this->signature = 'paypal|paypal_express|' . $this->_app->getVersion() . '|2.3';
0 ignored issues
show
Bug introduced by
The property signature does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
27
      $this->api_version = $this->_app->getApiVersion();
0 ignored issues
show
Bug introduced by
The property api_version does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
28
29
      $this->code = 'paypal_express';
30
      $this->title = $this->_app->getDef('module_ec_title');
31
      $this->public_title = $this->_app->getDef('module_ec_public_title');
0 ignored issues
show
Bug introduced by
The property public_title does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
32
      $this->description = '<div align="center">' . $this->_app->drawButton($this->_app->getDef('module_ec_legacy_admin_app_button'), tep_href_link('paypal.php', 'action=configure&module=EC'), 'primary', null, true) . '</div>';
33
      $this->sort_order = defined('OSCOM_APP_PAYPAL_EC_SORT_ORDER') ? OSCOM_APP_PAYPAL_EC_SORT_ORDER : 0;
0 ignored issues
show
Bug introduced by
The property sort_order does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
34
      $this->enabled = defined('OSCOM_APP_PAYPAL_EC_STATUS') && in_array(OSCOM_APP_PAYPAL_EC_STATUS, array('1', '0')) ? true : false;
35
      $this->order_status = defined('OSCOM_APP_PAYPAL_EC_ORDER_STATUS_ID') && ((int)OSCOM_APP_PAYPAL_EC_ORDER_STATUS_ID > 0) ? (int)OSCOM_APP_PAYPAL_EC_ORDER_STATUS_ID : 0;
0 ignored issues
show
Bug introduced by
The property order_status does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
36
37
      if ( defined('OSCOM_APP_PAYPAL_EC_STATUS') ) {
38
        if ( OSCOM_APP_PAYPAL_EC_STATUS == '0' ) {
39
          $this->title .= ' [Sandbox]';
40
          $this->public_title .= ' (' . $this->code . '; Sandbox)';
41
        }
42
      }
43
44
      if ( !function_exists('curl_init') ) {
45
        $this->description .= '<div class="secWarning">' . $this->_app->getDef('module_ec_error_curl') . '</div>';
46
47
        $this->enabled = false;
48
      }
49
50 View Code Duplication
      if ( $this->enabled === true ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
        if ( OSCOM_APP_PAYPAL_GATEWAY == '1' ) { // PayPal
52
          if ( !$this->_app->hasCredentials('EC') ) {
53
            $this->description .= '<div class="secWarning">' . $this->_app->getDef('module_ec_error_credentials') . '</div>';
54
55
            $this->enabled = false;
56
          }
57
        } else { // Payflow
58
          if ( !$this->_app->hasCredentials('EC', 'payflow') ) {
59
            $this->description .= '<div class="secWarning">' . $this->_app->getDef('module_ec_error_credentials_payflow') . '</div>';
60
61
            $this->enabled = false;
62
          }
63
        }
64
      }
65
66
      if ( $this->enabled === true ) {
67
        if ( isset($order) && is_object($order) ) {
68
          $this->update_status();
69
        }
70
      }
71
72
      if ( defined('FILENAME_SHOPPING_CART') && (basename($PHP_SELF) == FILENAME_SHOPPING_CART) ) {
73
        if ( (OSCOM_APP_PAYPAL_GATEWAY == '1') && (OSCOM_APP_PAYPAL_EC_CHECKOUT_FLOW == '1') ) {
74
          if ( isset($request_type) && ($request_type != 'SSL') && (ENABLE_SSL == true) ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
75
            tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, tep_get_all_get_params(), 'SSL'));
76
          }
77
78
          header('X-UA-Compatible: IE=edge', true);
79
        }
80
      }
81
82
// When changing the shipping address due to no shipping rates being available, head straight to the checkout confirmation page
83
      if ( defined('FILENAME_CHECKOUT_PAYMENT') && (basename($PHP_SELF) == FILENAME_CHECKOUT_PAYMENT) && tep_session_is_registered('appPayPalEcRightTurn') ) {
84
        tep_session_unregister('appPayPalEcRightTurn');
85
86
        if ( tep_session_is_registered('payment') && ($payment == $this->code) ) {
87
          tep_redirect(tep_href_link(FILENAME_CHECKOUT_CONFIRMATION, '', 'SSL'));
88
        }
89
      }
90
91
      if ( $this->enabled === true ) {
92
        if ( defined('FILENAME_SHOPPING_CART') && (basename($PHP_SELF) == FILENAME_SHOPPING_CART) ) {
93
          if ( $this->templateClassExists() ) {
94
            if ( (OSCOM_APP_PAYPAL_GATEWAY == '1') && (OSCOM_APP_PAYPAL_EC_CHECKOUT_FLOW == '1') ) {
95
              $oscTemplate->addBlock('<style>#ppECButton { display: inline-block; }</style>', 'header_tags');
96
            }
97
98
            if ( file_exists(DIR_FS_CATALOG . 'ext/modules/payment/paypal/express.css') ) {
99
              $oscTemplate->addBlock('<link rel="stylesheet" type="text/css" href="ext/modules/payment/paypal/express.css" />', 'header_tags');
100
            }
101
          }
102
        }
103
      }
104
    }
105
106 View Code Duplication
    function update_status() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
      global $order;
108
109
      if ( ($this->enabled == true) && ((int)OSCOM_APP_PAYPAL_EC_ZONE > 0) ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
110
        $check_flag = false;
111
        $check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . OSCOM_APP_PAYPAL_EC_ZONE . "' and zone_country_id = '" . $order->delivery['country']['id'] . "' order by zone_id");
112
        while ($check = tep_db_fetch_array($check_query)) {
113
          if ($check['zone_id'] < 1) {
114
            $check_flag = true;
115
            break;
116
          } elseif ($check['zone_id'] == $order->delivery['zone_id']) {
117
            $check_flag = true;
118
            break;
119
          }
120
        }
121
122
        if ($check_flag == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
123
          $this->enabled = false;
124
        }
125
      }
126
    }
127
128
    function checkout_initialization_method() {
129
      global $cart;
130
131
      $string = '';
132
133
      if (OSCOM_APP_PAYPAL_GATEWAY == '1') {
134
        if (OSCOM_APP_PAYPAL_EC_CHECKOUT_FLOW == '0') {
135
          if (OSCOM_APP_PAYPAL_EC_CHECKOUT_IMAGE == '1') {
136
            if (OSCOM_APP_PAYPAL_EC_STATUS == '1') {
137
              $image_button = 'https://fpdbs.paypal.com/dynamicimageweb?cmd=_dynamic-image';
138
            } else {
139
              $image_button = 'https://fpdbs.sandbox.paypal.com/dynamicimageweb?cmd=_dynamic-image';
140
            }
141
142
            $params = array('locale=' . $this->_app->getDef('module_ec_button_locale'));
143
144
            if ( $this->_app->hasCredentials('EC') ) {
145
              $response_array = $this->_app->getApiResult('EC', 'GetPalDetails');
146
147
              if ( isset($response_array['PAL']) ) {
148
                $params[] = 'pal=' . $response_array['PAL'];
149
                $params[] = 'ordertotal=' . $this->_app->formatCurrencyRaw($cart->show_total());
150
              }
151
            }
152
153
            if ( !empty($params) ) {
154
              $image_button .= '&' . implode('&', $params);
155
            }
156
          } else {
157
            $image_button = $this->_app->getDef('module_ec_button_url');
158
          }
159
160
          $button_title = tep_output_string_protected($this->_app->getDef('module_ec_button_title'));
161
162
          if ( OSCOM_APP_PAYPAL_EC_STATUS == '0' ) {
163
            $button_title .= ' (' . $this->code . '; Sandbox)';
164
          }
165
166
          $string .= '<a id="ppECButtonClassicLink" href="' . tep_href_link('ext/modules/payment/paypal/express.php', '', 'SSL') . '"><img id="ppECButtonClassic" src="' . $image_button . '" border="0" alt="" title="' . $button_title . '" /></a>';
167
        } else {
168
          $string .= '<script src="https://www.paypalobjects.com/api/checkout.js"></script>';
169
170
          $merchant_id = (OSCOM_APP_PAYPAL_EC_STATUS === '1') ? OSCOM_APP_PAYPAL_LIVE_MERCHANT_ID : OSCOM_APP_PAYPAL_SANDBOX_MERCHANT_ID;
171
          if (empty($merchant_id)) $merchant_id = ' ';
0 ignored issues
show
Unused Code introduced by
$merchant_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
172
173
          $server = (OSCOM_APP_PAYPAL_EC_STATUS === '1') ? 'production' : 'sandbox';
174
175
          $ppecset_url = tep_href_link('ext/modules/payment/paypal/express.php', 'format=json', 'SSL');
176
177
          $ppecerror_url = tep_href_link('ext/modules/payment/paypal/express.php', 'osC_Action=setECError', 'SSL');
178
179 View Code Duplication
          switch (OSCOM_APP_PAYPAL_EC_INCONTEXT_BUTTON_COLOR) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
            case '3':
181
              $button_color = 'silver';
182
              break;
183
184
            case '2':
185
              $button_color = 'blue';
186
              break;
187
188
            case '1':
189
            default:
190
              $button_color = 'gold';
191
              break;
192
          }
193
194 View Code Duplication
          switch (OSCOM_APP_PAYPAL_EC_INCONTEXT_BUTTON_SIZE) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
            case '3':
196
              $button_size = 'medium';
197
              break;
198
199
            case '1':
200
              $button_size = 'tiny';
201
              break;
202
203
            case '2':
204
            default:
205
              $button_size = 'small';
206
              break;
207
          }
208
209
          switch (OSCOM_APP_PAYPAL_EC_INCONTEXT_BUTTON_SHAPE) {
210
            case '2':
211
              $button_shape = 'rect';
212
              break;
213
214
            case '1':
215
            default:
216
              $button_shape = 'pill';
217
              break;
218
          }
219
220
          $string .= <<<EOD
221
<span id="ppECButton"></span>
222
<script>
223
paypal.Button.render({
224
  env: '{$server}',
225
  style: {
226
    size: '${button_size}',
227
    color: '${button_color}',
228
    shape: '${button_shape}'
229
  },
230
  payment: function(resolve, reject) {
231
    paypal.request.post('${ppecset_url}')
232
      .then(function(data) {
233
        if ((data.token !== undefined) && (data.token.length > 0)) {
234
          resolve(data.token);
235
        } else {
236
          window.location = '${ppecerror_url}';
237
        }
238
      })
239
      .catch(function(err) {
240
        reject(err);
241
242
        window.location = '${ppecerror_url}';
243
      });
244
  },
245
  onAuthorize: function(data, actions) {
246
    return actions.redirect();
247
  },
248
  onCancel: function(data, actions) {
249
    return actions.redirect();
250
  }
251
}, '#ppECButton');
252
</script>
253
EOD;
254
        }
255
      } else {
256
        $image_button = $this->_app->getDef('module_ec_button_url');
257
258
        $button_title = tep_output_string_protected($this->_app->getDef('module_ec_button_title'));
259
260
        if (OSCOM_APP_PAYPAL_EC_STATUS == '0') {
261
          $button_title .= ' (' . $this->code . '; Sandbox)';
262
        }
263
264
        $string .= '<a id="ppECButtonPfLink" href="' . tep_href_link('ext/modules/payment/paypal/express.php', '', 'SSL') . '"><img id="ppECButtonPf" src="' . $image_button . '" border="0" alt="" title="' . $button_title . '" /></a>';
265
      }
266
267
      return $string;
268
    }
269
270
    function javascript_validation() {
271
      return false;
272
    }
273
274
    function selection() {
275
      return array('id' => $this->code,
276
                   'module' => $this->public_title);
277
    }
278
279
    function pre_confirmation_check() {
280
      global $appPayPalEcResult, $appPayPalEcSecret, $messageStack, $order;
281
282
      if ( !tep_session_is_registered('appPayPalEcResult') ) {
283
        tep_redirect(tep_href_link('ext/modules/payment/paypal/express.php', '', 'SSL'));
284
      }
285
286
      if ( OSCOM_APP_PAYPAL_GATEWAY == '1' ) { // PayPal
287 View Code Duplication
        if ( !in_array($appPayPalEcResult['ACK'], array('Success', 'SuccessWithWarning')) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
288
          tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes($appPayPalEcResult['L_LONGMESSAGE0']), 'SSL'));
289
        } elseif ( !tep_session_is_registered('appPayPalEcSecret') || ($appPayPalEcResult['PAYMENTREQUEST_0_CUSTOM'] != $appPayPalEcSecret) ) {
290
          tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, '', 'SSL'));
291
        }
292 View Code Duplication
      } else { // Payflow
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
293
        if ($appPayPalEcResult['RESULT'] != '0') {
294
          tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . urlencode($appPayPalEcResult['OSCOM_ERROR_MESSAGE']), 'SSL'));
295
        } elseif ( !tep_session_is_registered('appPayPalEcSecret') || ($appPayPalEcResult['CUSTOM'] != $appPayPalEcSecret) ) {
296
          tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, '', 'SSL'));
297
        }
298
      }
299
300
      $order->info['payment_method'] = '<img src="https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-100px.png" border="0" alt="PayPal Logo" style="padding: 3px;" />';
301
    }
302
303
    function confirmation() {
304
      global $comments;
305
306
      if (!isset($comments)) {
307
        $comments = null;
308
      }
309
310
      $confirmation = false;
311
312
      if (empty($comments)) {
313
        $confirmation = array('fields' => array(array('title' => $this->_app->getDef('module_ec_field_comments'),
314
                                                      'field' => tep_draw_textarea_field('ppecomments', 'soft', '60', '5', $comments))));
315
      }
316
317
      return $confirmation;
318
    }
319
320
    function process_button() {
321
      return false;
322
    }
323
324
    function before_process() {
325
      if ( OSCOM_APP_PAYPAL_GATEWAY == '1' ) {
326
        $this->before_process_paypal();
327
      } else {
328
        $this->before_process_payflow();
329
      }
330
    }
331
332
    function before_process_paypal() {
333
      global $customer_id, $order, $sendto, $appPayPalEcResult, $appPayPalEcSecret, $response_array, $HTTP_POST_VARS, $comments;
334
335
      if ( !tep_session_is_registered('appPayPalEcResult') ) {
336
        tep_redirect(tep_href_link('ext/modules/payment/paypal/express.php', '', 'SSL'));
337
      }
338
339 View Code Duplication
      if ( in_array($appPayPalEcResult['ACK'], array('Success', 'SuccessWithWarning')) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
340
        if ( !tep_session_is_registered('appPayPalEcSecret') || ($appPayPalEcResult['PAYMENTREQUEST_0_CUSTOM'] != $appPayPalEcSecret) ) {
341
          tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, '', 'SSL'));
342
        }
343
      } else {
344
        tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes($appPayPalEcResult['L_LONGMESSAGE0']), 'SSL'));
345
      }
346
347 View Code Duplication
      if (empty($comments)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
348
        if (isset($HTTP_POST_VARS['ppecomments']) && tep_not_null($HTTP_POST_VARS['ppecomments'])) {
349
          $comments = tep_db_prepare_input($HTTP_POST_VARS['ppecomments']);
350
351
          $order->info['comments'] = $comments;
352
        }
353
      }
354
355
      $params = array('TOKEN' => $appPayPalEcResult['TOKEN'],
356
                      'PAYERID' => $appPayPalEcResult['PAYERID'],
357
                      'PAYMENTREQUEST_0_AMT' => $this->_app->formatCurrencyRaw($order->info['total']),
358
                      'PAYMENTREQUEST_0_CURRENCYCODE' => $order->info['currency']);
359
360
      if (is_numeric($sendto) && ($sendto > 0)) {
361
        $params['PAYMENTREQUEST_0_SHIPTONAME'] = $order->delivery['firstname'] . ' ' . $order->delivery['lastname'];
362
        $params['PAYMENTREQUEST_0_SHIPTOSTREET'] = $order->delivery['street_address'];
363
        $params['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $order->delivery['suburb'];
364
        $params['PAYMENTREQUEST_0_SHIPTOCITY'] = $order->delivery['city'];
365
        $params['PAYMENTREQUEST_0_SHIPTOSTATE'] = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);
366
        $params['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $order->delivery['country']['iso_code_2'];
367
        $params['PAYMENTREQUEST_0_SHIPTOZIP'] = $order->delivery['postcode'];
368
      }
369
370
      $response_array = $this->_app->getApiResult('EC', 'DoExpressCheckoutPayment', $params);
371
372
      if ( !in_array($response_array['ACK'], array('Success', 'SuccessWithWarning')) ) {
373
        if ( $response_array['L_ERRORCODE0'] == '10486' ) {
374
          if ( OSCOM_APP_PAYPAL_EC_STATUS == '1' ) {
375
            $paypal_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout';
376
          } else {
377
            $paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout';
378
          }
379
380
          $paypal_url .= '&token=' . $appPayPalEcResult['TOKEN'];
381
382
          tep_redirect($paypal_url);
383
        }
384
385
        tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes($response_array['L_LONGMESSAGE0']), 'SSL'));
386
      }
387
    }
388
389
    function before_process_payflow() {
390
      global $customer_id, $order, $sendto, $appPayPalEcResult, $appPayPalEcSecret, $response_array, $HTTP_POST_VARS, $comments;
391
392
      if ( !tep_session_is_registered('appPayPalEcResult') ) {
393
        tep_redirect(tep_href_link('ext/modules/payment/paypal/express.php', '', 'SSL'));
394
      }
395
396 View Code Duplication
      if ( $appPayPalEcResult['RESULT'] == '0' ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
397
        if ( !tep_session_is_registered('appPayPalEcSecret') || ($appPayPalEcResult['CUSTOM'] != $appPayPalEcSecret) ) {
398
          tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, '', 'SSL'));
399
        }
400
      } else {
401
        tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . urlencode($appPayPalEcResult['OSCOM_ERROR_MESSAGE']), 'SSL'));
402
      }
403
404 View Code Duplication
      if ( empty($comments) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
405
        if ( isset($HTTP_POST_VARS['ppecomments']) && tep_not_null($HTTP_POST_VARS['ppecomments']) ) {
406
          $comments = tep_db_prepare_input($HTTP_POST_VARS['ppecomments']);
407
408
          $order->info['comments'] = $comments;
409
        }
410
      }
411
412
      $params = array('EMAIL' => $order->customer['email_address'],
413
                      'TOKEN' => $appPayPalEcResult['TOKEN'],
414
                      'PAYERID' => $appPayPalEcResult['PAYERID'],
415
                      'AMT' => $this->_app->formatCurrencyRaw($order->info['total']),
416
                      'CURRENCY' => $order->info['currency']);
417
418
      if ( is_numeric($sendto) && ($sendto > 0) ) {
419
        $params['SHIPTONAME'] = $order->delivery['firstname'] . ' ' . $order->delivery['lastname'];
420
        $params['SHIPTOSTREET'] = $order->delivery['street_address'];
421
        $params['SHIPTOSTREET2'] = $order->delivery['suburb'];
422
        $params['SHIPTOCITY'] = $order->delivery['city'];
423
        $params['SHIPTOSTATE'] = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);
424
        $params['SHIPTOCOUNTRY'] = $order->delivery['country']['iso_code_2'];
425
        $params['SHIPTOZIP'] = $order->delivery['postcode'];
426
      }
427
428
      $response_array = $this->_app->getApiResult('EC', 'PayflowDoExpressCheckoutPayment', $params);
429
430
      if ( $response_array['RESULT'] != '0' ) {
431
        tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . urlencode($response_array['OSCOM_ERROR_MESSAGE']), 'SSL'));
432
      }
433
    }
434
435
    function after_process() {
436
      if ( OSCOM_APP_PAYPAL_GATEWAY == '1' ) {
437
        $this->after_process_paypal();
438
      } else {
439
        $this->after_process_payflow();
440
      }
441
    }
442
443
    function after_process_paypal() {
444
      global $response_array, $insert_id, $appPayPalEcResult;
445
446
      $pp_result = 'Transaction ID: ' . tep_output_string_protected($response_array['PAYMENTINFO_0_TRANSACTIONID']) . "\n" .
447
                   'Payer Status: ' . tep_output_string_protected($appPayPalEcResult['PAYERSTATUS']) . "\n" .
448
                   'Address Status: ' . tep_output_string_protected($appPayPalEcResult['ADDRESSSTATUS']) . "\n" .
449
                   'Payment Status: ' . tep_output_string_protected($response_array['PAYMENTINFO_0_PAYMENTSTATUS']) . "\n" .
450
                   'Payment Type: ' . tep_output_string_protected($response_array['PAYMENTINFO_0_PAYMENTTYPE']) . "\n" .
451
                   'Pending Reason: ' . tep_output_string_protected($response_array['PAYMENTINFO_0_PENDINGREASON']);
452
453
      $sql_data_array = array('orders_id' => $insert_id,
454
                              'orders_status_id' => OSCOM_APP_PAYPAL_TRANSACTIONS_ORDER_STATUS_ID,
455
                              'date_added' => 'now()',
456
                              'customer_notified' => '0',
457
                              'comments' => $pp_result);
458
459
      tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
460
461
      tep_session_unregister('appPayPalEcResult');
462
      tep_session_unregister('appPayPalEcSecret');
463
    }
464
465
    function after_process_payflow() {
466
      global $response_array, $insert_id, $appPayPalEcResult;
467
468
      $pp_result = 'Transaction ID: ' . tep_output_string_protected($response_array['PNREF']) . "\n" .
469
                   'Gateway: Payflow' . "\n" .
470
                   'PayPal ID: ' . tep_output_string_protected($response_array['PPREF']) . "\n" .
471
                   'Payer Status: ' . tep_output_string_protected($appPayPalEcResult['PAYERSTATUS']) . "\n" .
472
                   'Address Status: ' . tep_output_string_protected($appPayPalEcResult['ADDRESSSTATUS']) . "\n" .
473
                   'Payment Status: ' . tep_output_string_protected($response_array['PENDINGREASON']) . "\n" .
474
                   'Payment Type: ' . tep_output_string_protected($response_array['PAYMENTTYPE']) . "\n" .
475
                   'Response: ' . tep_output_string_protected($response_array['RESPMSG']) . "\n";
476
477
      $sql_data_array = array('orders_id' => $insert_id,
478
                              'orders_status_id' => OSCOM_APP_PAYPAL_TRANSACTIONS_ORDER_STATUS_ID,
479
                              'date_added' => 'now()',
480
                              'customer_notified' => '0',
481
                              'comments' => $pp_result);
482
483
      tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
484
485
      tep_session_unregister('appPayPalEcResult');
486
      tep_session_unregister('appPayPalEcSecret');
487
488
// Manually call PayflowInquiry to retrieve more details about the transaction and to allow admin post-transaction actions
489
      $response = $this->_app->getApiResult('APP', 'PayflowInquiry', array('ORIGID' => $response_array['PNREF']));
490
491
      if ( isset($response['RESULT']) && ($response['RESULT'] == '0') ) {
492
        $result = 'Transaction ID: ' . tep_output_string_protected($response['ORIGPNREF']) . "\n" .
493
                  'Gateway: Payflow' . "\n";
494
495
        $pending_reason = $response['TRANSSTATE'];
496
        $payment_status = null;
497
498 View Code Duplication
        switch ( $response['TRANSSTATE'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
499
          case '3':
500
            $pending_reason = 'authorization';
501
            $payment_status = 'Pending';
502
            break;
503
504
          case '4':
505
            $pending_reason = 'other';
506
            $payment_status = 'In-Progress';
507
            break;
508
509
          case '6':
510
            $pending_reason = 'scheduled';
511
            $payment_status = 'Pending';
512
            break;
513
514
          case '8':
515
          case '9':
516
            $pending_reason = 'None';
517
            $payment_status = 'Completed';
518
            break;
519
        }
520
521
        if ( isset($payment_status) ) {
522
          $result .= 'Payment Status: ' . tep_output_string_protected($payment_status) . "\n";
523
        }
524
525
        $result .= 'Pending Reason: ' . tep_output_string_protected($pending_reason) . "\n";
526
527
        switch ( $response['AVSADDR'] ) {
528
          case 'Y':
529
            $result .= 'AVS Address: Match' . "\n";
530
            break;
531
532
          case 'N':
533
            $result .= 'AVS Address: No Match' . "\n";
534
            break;
535
        }
536
537 View Code Duplication
        switch ( $response['AVSZIP'] ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
538
          case 'Y':
539
            $result .= 'AVS ZIP: Match' . "\n";
540
            break;
541
542
          case 'N':
543
            $result .= 'AVS ZIP: No Match' . "\n";
544
            break;
545
        }
546
547
        switch ( $response['IAVS'] ) {
548
          case 'Y':
549
            $result .= 'IAVS: International' . "\n";
550
            break;
551
552
          case 'N':
553
            $result .= 'IAVS: USA' . "\n";
554
            break;
555
        }
556
557
        switch ( $response['CVV2MATCH'] ) {
558
          case 'Y':
559
            $result .= 'CVV2: Match' . "\n";
560
            break;
561
562
          case 'N':
563
            $result .= 'CVV2: No Match' . "\n";
564
            break;
565
        }
566
567
        $sql_data_array = array('orders_id' => $insert_id,
568
                                'orders_status_id' => OSCOM_APP_PAYPAL_TRANSACTIONS_ORDER_STATUS_ID,
569
                                'date_added' => 'now()',
570
                                'customer_notified' => '0',
571
                                'comments' => $result);
572
573
        tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
574
      }
575
    }
576
577
    function get_error() {
578
      return false;
579
    }
580
581 View Code Duplication
    function check() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
582
      $check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'OSCOM_APP_PAYPAL_EC_STATUS'");
583
      if ( tep_db_num_rows($check_query) ) {
584
        $check = tep_db_fetch_array($check_query);
585
586
        return tep_not_null($check['configuration_value']);
587
      }
588
589
      return false;
590
    }
591
592
    function install() {
593
      tep_redirect(tep_href_link('paypal.php', 'action=configure&subaction=install&module=EC'));
594
    }
595
596
    function remove() {
597
      tep_redirect(tep_href_link('paypal.php', 'action=configure&subaction=uninstall&module=EC'));
598
    }
599
600
    function keys() {
601
      return array('OSCOM_APP_PAYPAL_EC_SORT_ORDER');
602
    }
603
604
    function getProductType($id, $attributes) {
605
      foreach ( $attributes as $a ) {
606
        $virtual_check_query = tep_db_query("select pad.products_attributes_id from " . TABLE_PRODUCTS_ATTRIBUTES . " pa, " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad where pa.products_id = '" . (int)$id . "' and pa.options_values_id = '" . (int)$a['value_id'] . "' and pa.products_attributes_id = pad.products_attributes_id limit 1");
607
608
        if ( tep_db_num_rows($virtual_check_query) == 1 ) {
609
          return 'Digital';
610
        }
611
      }
612
613
      return 'Physical';
614
    }
615
616
    function templateClassExists() {
617
      return class_exists('oscTemplate') && isset($GLOBALS['oscTemplate']) && is_object($GLOBALS['oscTemplate']) && (get_class($GLOBALS['oscTemplate']) == 'oscTemplate');
618
    }
619
  }
620
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
621