Completed
Push — master ( 4a0bdf...a7a78b )
by Harald
05:18 queued 02:35
created

product_notification::choose_audience()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 85
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 30
nc 2
nop 0
dl 0
loc 85
rs 8.6875
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
  * osCommerce Online Merchant
4
  *
5
  * @copyright (c) 2016 osCommerce; https://www.oscommerce.com
6
  * @license MIT; https://www.oscommerce.com/license/mit.txt
7
  */
8
9
  use OSC\OM\HTML;
10
  use OSC\OM\Mail;
11
  use OSC\OM\OSCOM;
12
  use OSC\OM\Registry;
13
14
  class product_notification {
15
    var $show_choose_audience, $title, $content, $content_html;
16
17 View Code Duplication
    function __construct($title, $content, $content_html = null) {
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...
18
      $this->show_choose_audience = true;
19
      $this->title = $title;
20
      $this->content = $content;
21
      $this->content_html = $content_html;
22
    }
23
24
    function choose_audience() {
25
      $OSCOM_Db = Registry::get('Db');
26
      $OSCOM_Language = Registry::get('Language');
27
28
      $products_array = [];
29
30
      $Qproducts = $OSCOM_Db->get([
31
        'products p',
32
        'products_description pd'
33
      ], [
34
        'pd.products_id',
35
        'pd.products_name'
36
      ], [
37
        'pd.language_id' => $OSCOM_Language->getId(),
38
        'pd.products_id' => [
39
          'rel' => 'p.products_id'
40
        ],
41
        'p.products_status' => '1'
42
      ], 'pd.products_name');
43
44
      while ($Qproducts->fetch()) {
45
        $products_array[] = [
46
          'id' => $Qproducts->valueInt('products_id'),
47
          'text' => $Qproducts->value('products_name')
48
        ];
49
      }
50
51
$choose_audience_string = '<script type="text/javascript"><!--
52
function mover(move) {
53
  if (move == \'remove\') {
54
    for (x=0; x<(document.notifications.products.length); x++) {
55
      if (document.notifications.products.options[x].selected) {
56
        with(document.notifications.elements[\'chosen[]\']) {
57
          options[options.length] = new Option(document.notifications.products.options[x].text,document.notifications.products.options[x].value);
58
        }
59
        document.notifications.products.options[x] = null;
60
        x = -1;
61
      }
62
    }
63
  }
64
  if (move == \'add\') {
65
    for (x=0; x<(document.notifications.elements[\'chosen[]\'].length); x++) {
66
      if (document.notifications.elements[\'chosen[]\'].options[x].selected) {
67
        with(document.notifications.products) {
68
          options[options.length] = new Option(document.notifications.elements[\'chosen[]\'].options[x].text,document.notifications.elements[\'chosen[]\'].options[x].value);
69
        }
70
        document.notifications.elements[\'chosen[]\'].options[x] = null;
71
        x = -1;
72
      }
73
    }
74
  }
75
  return true;
76
}
77
78
function selectAll(FormName, SelectBox) {
79
  temp = "document." + FormName + ".elements[\'" + SelectBox + "\']";
80
  Source = eval(temp);
81
82
  for (x=0; x<(Source.length); x++) {
83
    Source.options[x].selected = "true";
84
  }
85
86
  if (x<1) {
87
    alert(\'' . OSCOM::getDef('js_please_select_products') . '\');
88
    return false;
89
  } else {
90
    return true;
91
  }
92
}
93
//--></script>';
94
95
      $global_button = HTML::button(OSCOM::getDef('button_global'), 'fa fa-globe', OSCOM::link(FILENAME_NEWSLETTERS, 'page=' . $_GET['page'] . '&nID=' . $_GET['nID'] . '&action=confirm&global=true'));
96
97
      $cancel_button = HTML::button(OSCOM::getDef('image_cancel'), 'fa fa-close', OSCOM::link(FILENAME_NEWSLETTERS, 'page=' . $_GET['page'] . '&nID=' . $_GET['nID']));
98
99
      $choose_audience_string .= '<form name="notifications" action="' . OSCOM::link(FILENAME_NEWSLETTERS, 'page=' . $_GET['page'] . '&nID=' . $_GET['nID'] . '&action=confirm') . '" method="post" onsubmit="return selectAll(\'notifications\', \'chosen[]\')"><table border="0" width="100%" cellspacing="0" cellpadding="2">' . "\n" .
100
                                 '  <tr>' . "\n" .
101
                                 '    <td align="center" class="smallText"><strong>' . OSCOM::getDef('text_products') . '</strong><br />' . HTML::selectField('products', $products_array, '', 'size="20" style="width: 20em;" multiple') . '</td>' . "\n" .
102
                                 '    <td align="center" class="smallText">&nbsp;<br />' . $global_button . '<br /><br /><br /><input type="button" value="' . OSCOM::getDef('button_select') . '" style="width: 8em;" onClick="mover(\'remove\');"><br /><br /><input type="button" value="' . OSCOM::getDef('button_unselect') . '" style="width: 8em;" onClick="mover(\'add\');"><br /><br /><br />' . HTML::button(OSCOM::getDef('image_send'), 'fa fa-envelope') . '<br /><br />' . $cancel_button . '</td>' . "\n" .
103
                                 '    <td align="center" class="smallText"><strong>' . OSCOM::getDef('text_selected_products') . '</strong><br />' . HTML::selectField('chosen[]', array(), '', 'size="20" style="width: 20em;" multiple') . '</td>' . "\n" .
104
                                 '  </tr>' . "\n" .
105
                                 '</table></form>';
106
107
      return $choose_audience_string;
108
    }
109
110
    function confirm() {
111
      $OSCOM_Db = Registry::get('Db');
112
113
      $audience = array();
114
115
      if (isset($_GET['global']) && ($_GET['global'] == 'true')) {
116
        $Qproducts = $OSCOM_Db->get('products_notifications', 'distinct customers_id');
117
118
        while ($Qproducts->fetch()) {
119
          $audience[$Qproducts->valueInt('customers_id')] = '1';
120
        }
121
122
        $Qcustomers = $OSCOM_Db->get('customers_info', 'customers_info_id', ['global_product_notifications' => '1']);
123
124
        while ($Qcustomers->fetch()) {
125
          $audience[$Qcustomers->valueInt('customers_info_id')] = '1';
126
        }
127
      } else {
128
        $chosen = [];
129
130 View Code Duplication
        foreach ($_POST['chosen'] as $id) {
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...
131
          if (is_numeric($id) && !in_array($id, $chosen)) {
132
            $chosen[] = $id;
133
          }
134
        }
135
136
        $ids = array_map(function($k) {
137
          return ':products_id_' . $k;
138
        }, array_keys($chosen));
139
140
        $Qproducts = $OSCOM_Db->prepare('select distinct customers_id from :table_products_notifications where products_id in (' . implode(', ', $ids) . ')');
141
142
        foreach ($chosen as $k => $v) {
143
          $Qproducts->bindInt(':products_id_' . $k, $v);
144
        }
145
146
        $Qproducts->execute();
147
148
        while ($Qproducts->fetch()) {
149
          $audience[$Qproducts->valueInt('customers_id')] = '1';
150
        }
151
152
        $Qcustomers = $OSCOM_Db->get('customers_info', 'customers_info_id', ['global_product_notifications' => '1']);
153
154
        while ($Qcustomers->fetch()) {
155
          $audience[$Qcustomers->valueInt('customers_info_id')] = '1';
156
        }
157
      }
158
159
      $confirm_string =  HTML::form('confirm', OSCOM::link(FILENAME_NEWSLETTERS, 'page=' . $_GET['page'] . '&nID=' . $_GET['nID'] . '&action=confirm_send')) . "\n" .
160
                        '<table border="0" cellspacing="0" cellpadding="2">' . "\n" .
161
                        '  <tr>' . "\n" .
162
                        '    <td class="main"><font color="#ff0000"><strong>' . OSCOM::getDef('text_count_customers', ['audience' => sizeof($audience)]) . '</strong></font></td>' . "\n" .
163
                        '  </tr>' . "\n" .
164
                        '  <tr>' . "\n" .
165
                        '    <td>&nbsp;</td>' . "\n" .
166
                        '  </tr>' . "\n" .
167
                        '  <tr>' . "\n" .
168
                        '    <td class="main"><strong>' . $this->title . '</strong></td>' . "\n" .
169
                        '  </tr>' . "\n" .
170
                        '  <tr>' . "\n" .
171
                        '    <td>&nbsp;</td>' . "\n" .
172
                        '  </tr>' . "\n" .
173
                        '  <tr>' . "\n" .
174
                        '    <td class="main">' . "\n" .
175
                        '      <ul class="nav nav-tabs" role="tablist">' . "\n" .
176
                        '        <li role="presentation" class="active"><a href="#html_preview" aria-controls="html_preview" role="tab" data-toggle="tab">' . OSCOM::getDef('email_type_html') . '</a></li>' . "\n" .
177
                        '        <li role="presentation"><a href="#plain_preview" aria-controls="plain_preview" role="tab" data-toggle="tab">' . OSCOM::getDef('email_type_plain') . '</a></li>' . "\n" .
178
                        '      </ul>' . "\n" .
179
                        '      <div class="tab-content">' . "\n" .
180
                        '        <div role="tabpanel" class="tab-pane active" id="html_preview">' . "\n" .
181
                        '          <iframe id="emailHtmlPreviewContent" style="width: 100%; height: 400px; border: 0;"></iframe>' . "\n" .
182
                        '          <script id="emailHtmlPreview" type="x-tmpl-mustache">' . "\n" .
183
                        '            ' . HTML::outputProtected($this->content_html) . "\n" .
184
                        '          </script>' . "\n" .
185
                        '          <script>' . "\n" .
186
                        '            $(function() {' . "\n" .
187
                        '              var content = $(\'<div />\').html($(\'#emailHtmlPreview\').html()).text();' . "\n" .
188
                        '              $(\'#emailHtmlPreviewContent\').contents().find(\'html\').html(content);' . "\n" .
189
                        '            });' . "\n" .
190
                        '          </script>' . "\n" .
191
                        '        </div>' . "\n" .
192
                        '        <div role="tabpanel" class="tab-pane" id="plain_preview">' . "\n" .
193
                        '          ' . nl2br(HTML::outputProtected($this->content)) . "\n" .
194
                        '        </div>' . "\n" .
195
                        '      </div>' . "\n" .
196
                        '    </td>' . "\n" .
197
                        '  </tr>' . "\n" .
198
                        '  <tr>' . "\n" .
199
                        '    <td>&nbsp;</td>' . "\n" .
200
                        '  </tr>' . "\n" .
201
                        '  <tr>' . "\n" .
202
                        '    <td class="smallText" align="right">';
203
      if (sizeof($audience) > 0) {
204
        if (isset($_GET['global']) && ($_GET['global'] == 'true')) {
205
          $confirm_string .= HTML::hiddenField('global', 'true');
206
        } else {
207
          for ($i = 0, $n = sizeof($chosen); $i < $n; $i++) {
0 ignored issues
show
Bug introduced by
The variable $chosen does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
208
            $confirm_string .= HTML::hiddenField('chosen[]', $chosen[$i]);
209
          }
210
        }
211
        $confirm_string .= HTML::button(OSCOM::getDef('image_send'), 'fa fa-envelope');
212
      }
213
      $confirm_string .= HTML::button(OSCOM::getDef('image_cancel'), 'fa fa-close', OSCOM::link(FILENAME_NEWSLETTERS, 'page=' . $_GET['page'] . '&nID=' . $_GET['nID'] . '&action=send')) . '</td>' . "\n" .
214
                         '  </tr>' . "\n" .
215
                         '</table>' . "\n" .
216
                         '</form>';
217
218
      return $confirm_string;
219
    }
220
221
    function send($newsletter_id) {
222
      $OSCOM_Db = Registry::get('Db');
223
224
      $audience = array();
225
226
      if (isset($_POST['global']) && ($_POST['global'] == 'true')) {
227
        $Qproducts = $OSCOM_Db->get([
228
          'customers c',
229
          'products_notifications pn'
230
        ], [
231
          'distinct pn.customers_id',
232
          'c.customers_firstname',
233
          'c.customers_lastname',
234
          'c.customers_email_address'
235
        ], [
236
          'c.customers_id' => [
237
            'rel' => 'pn.customers_id'
238
          ]
239
        ]);
240
241 View Code Duplication
        while ($Qproducts->fetch()) {
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...
242
          $audience[$Qproducts->valueInt('customers_id')] = [
243
            'firstname' => $Qproducts->value('customers_firstname'),
244
            'lastname' => $Qproducts->value('customers_lastname'),
245
            'email_address' => $Qproducts->value('customers_email_address')
246
          ];
247
        }
248
249
        $Qcustomers = $OSCOM_Db->get([
250
          'customers c',
251
          'customers_info ci'
252
        ], [
253
          'c.customers_id',
254
          'c.customers_firstname',
255
          'c.customers_lastname',
256
          'c.customers_email_address'
257
        ], [
258
          'c.customers_id' => [
259
            'rel' => 'ci.customers_info_id'
260
          ],
261
          'ci.global_product_notifications' => '1'
262
        ]);
263
264 View Code Duplication
        while ($Qcustomers->fetch()) {
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...
265
          $audience[$Qcustomers->valueInt('customers_id')] = [
266
            'firstname' => $Qcustomers->value('customers_firstname'),
267
            'lastname' => $Qcustomers->value('customers_lastname'),
268
            'email_address' => $Qcustomers->value('customers_email_address')
269
          ];
270
        }
271
      } else {
272
        $chosen = [];
273
274 View Code Duplication
        foreach ($_POST['chosen'] as $id) {
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...
275
          if (is_numeric($id) && !in_array($id, $chosen)) {
276
            $chosen[] = $id;
277
          }
278
        }
279
280
        $ids = array_map(function($k) {
281
          return ':products_id_' . $k;
282
        }, array_keys($chosen));
283
284
        $Qproducts = $OSCOM_Db->prepare('select distinct pn.customers_id, c.customers_firstname, c.customers_lastname, c.customers_email_address from :table_customers c, :table_products_notifications pn where c.customers_id = pn.customers_id and pn.products_id in (' . implode(', ', $ids) . ')');
285
286
        foreach ($chosen as $k => $v) {
287
          $Qproducts->bindInt(':products_id_' . $k, $v);
288
        }
289
290
        $Qproducts->execute();
291
292 View Code Duplication
        while ($Qproducts->fetch()) {
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
          $audience[$Qproducts->valueInt('customers_id')] = [
294
            'firstname' => $Qproducts->value('customers_firstname'),
295
            'lastname' => $Qproducts->value('customers_lastname'),
296
            'email_address' => $Qproducts->value('customers_email_address')
297
          ];
298
        }
299
300
        $Qcustomers = $OSCOM_Db->get([
301
          'customers c',
302
          'customers_info ci'
303
        ], [
304
          'c.customers_id',
305
          'c.customers_firstname',
306
          'c.customers_lastname',
307
          'c.customers_email_address'
308
        ], [
309
          'c.customers_id' => [
310
            'rel' => 'ci.customers_info_id'
311
          ],
312
          'ci.global_product_notifications' => '1'
313
        ]);
314
315 View Code Duplication
        while ($Qcustomers->fetch()) {
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...
316
          $audience[$Qcustomers->valueInt('customers_id')] = [
317
            'firstname' => $Qcustomers->value('customers_firstname'),
318
            'lastname' => $Qcustomers->value('customers_lastname'),
319
            'email_address' => $Qcustomers->value('customers_email_address')
320
          ];
321
        }
322
      }
323
324
      $notificationEmail = new Mail();
325
      $notificationEmail->setFrom(STORE_OWNER_EMAIL_ADDRESS, STORE_OWNER);
326
      $notificationEmail->setSubject($this->title);
327
328
      if (!empty($this->content)) {
329
        $notificationEmail->setBodyPlain($this->content);
330
      }
331
332
      if (!empty($this->content_html)) {
333
        $notificationEmail->setBodyHTML($this->content_html);
334
      }
335
336
      foreach ( $audience as $key => $value ) {
337
        $notificationEmail->clearTo();
338
339
        $notificationEmail->addTo($value['email_address'], $value['firstname'] . ' ' . $value['lastname']);
340
341
        $notificationEmail->send();
342
      }
343
344
      $OSCOM_Db->save('newsletters', [
345
        'date_sent' => 'now()',
346
        'status' => '1'
347
      ], [
348
        'newsletters_id' => (int)$newsletter_id
349
      ]);
350
    }
351
  }
352
?>
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...
353