Completed
Push — master ( 00e474...9d3fbd )
by Michael
04:26
created

Oledrion_utils::createMetaKeywords()   F

Complexity

Conditions 13
Paths 240

Size

Total Lines 123
Code Lines 107

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 107
nc 240
nop 1
dl 0
loc 123
rs 3.951
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
/**
13
 * oledrion
14
 *
15
 * @copyright   {@link http://xoops.org/ XOOPS Project}
16
 * @license     {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
17
 * @author      Hervé Thouzard (http://www.herve-thouzard.com/)
18
 */
19
20
/**
21
 * A set of useful and common functions
22
 *
23
 * @package       oledrion
24
 * @author        Hervé Thouzard - Instant Zero (http://xoops.instant-zero.com)
25
 * @copyright (c) Instant Zero
26
 *
27
 * Note: You should be able to use it without the need to instanciate it.
28
 *
29
 */
30
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
31
32
use WideImage\WideImage;
33
34
/**
35
 * Class Oledrion_utils
36
 */
37
class Oledrion_utils
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
38
{
39
    const MODULE_NAME = 'oledrion';
40
41
    /**
42
     * Access the only instance of this class
43
     *
44
     * @return object
45
     *
46
     * @static
47
     * @staticvar   object
48
     */
49
    public function getInstance()
50
    {
51
        static $instance;
52
        if (null === $instance) {
53
            $instance = new static();
54
        }
55
56
        return $instance;
57
    }
58
59
    /**
60
     * Returns a module's option (with cache)
61
     *
62
     * @param  string  $option    module option's name
63
     * @param  boolean $withCache Do we have to use some cache ?
64
     * @return mixed   option's value
65
     */
66
    public static function getModuleOption($option, $withCache = true)
67
    {
68
        global $xoopsModuleConfig, $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
69
        $repmodule = static::MODULE_NAME;
70
        static $options = array();
71
        if (is_array($options) && array_key_exists($option, $options) && $withCache) {
72
            return $options[$option];
73
        }
74
75
        $retval = false;
76
        if (isset($xoopsModuleConfig)
77
            && (is_object($xoopsModule) && $xoopsModule->getVar('dirname') == $repmodule
78
                && $xoopsModule->getVar('isactive'))
79
        ) {
80
            if (isset($xoopsModuleConfig[$option])) {
81
                $retval = $xoopsModuleConfig[$option];
82
            }
83
        } else {
84
            /** @var XoopsModuleHandler $moduleHandler */
85
            $moduleHandler = xoops_getHandler('module');
86
            $module         = $moduleHandler->getByDirname($repmodule);
87
            $configHandler = xoops_getHandler('config');
88
            if ($module) {
89
                $moduleConfig = $configHandler->getConfigsByCat(0, $module->getVar('mid'));
90
                if (isset($moduleConfig[$option])) {
91
                    $retval = $moduleConfig[$option];
92
                }
93
            }
94
        }
95
        $options[$option] = $retval;
96
97
        return $retval;
98
    }
99
100
    /**
101
     * Is Xoops 2.3.x ?
102
     *
103
     * @return boolean
104
     */
105 View Code Duplication
    public static function isX23()
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...
106
    {
107
        $x23 = false;
108
        $xv  = str_replace('XOOPS ', '', XOOPS_VERSION);
109
        if ((int)substr($xv, 2, 1) >= 3) {
110
            $x23 = true;
111
        }
112
113
        return $x23;
114
    }
115
116
    /**
117
     * Is Xoops 2.0.x ?
118
     *
119
     * @return boolean
120
     */
121 View Code Duplication
    public static function isX20()
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...
122
    {
123
        $x20 = false;
124
        $xv  = str_replace('XOOPS ', '', XOOPS_VERSION);
125
        if (substr($xv, 2, 1) == '0') {
126
            $x20 = true;
127
        }
128
129
        return $x20;
130
    }
131
132
    /**
133
     * Retreive an editor according to the module's option "form_options"
134
     *
135
     * @param  string $caption Caption to give to the editor
136
     * @param  string $name    Editor's name
137
     * @param  string $value   Editor's value
138
     * @param  string $width   Editor's width
139
     * @param  string $height  Editor's height
140
     * @param  string $supplemental
141
     * @return object The editor to use
0 ignored issues
show
Documentation introduced by
Should the return type not be XoopsFormEditor|XoopsFor...oopsFormWysiwygTextArea?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
142
     */
143
    public static function getWysiwygForm(
144
        $caption,
145
        $name,
146
        $value = '',
147
        $width = '100%',
148
        $height = '400px',
149
        $supplemental = ''
150
    ) {
151
        $editor                   = false;
152
        $editor_configs           = array();
153
        $editor_configs['name']   = $name;
154
        $editor_configs['value']  = $value;
155
        $editor_configs['rows']   = 35;
156
        $editor_configs['cols']   = 60;
157
        $editor_configs['width']  = '100%';
158
        $editor_configs['height'] = '400px';
159
160
        $editor_option = strtolower(static::getModuleOption('bl_form_options'));
161
162
        if (static::isX23()) {
163
            $editor = new XoopsFormEditor($caption, $editor_option, $editor_configs);
164
165
            return $editor;
166
        }
167
168
        // Only for Xoops 2.0.x
169
        switch ($editor_option) {
170 View Code Duplication
            case 'fckeditor':
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...
171
                if (is_readable(XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php')) {
172
                    require_once XOOPS_ROOT_PATH . '/class/fckeditor/formfckeditor.php';
173
                    $editor = new XoopsFormFckeditor($caption, $name, $value);
174
                }
175
                break;
176
177 View Code Duplication
            case 'htmlarea':
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...
178
                if (is_readable(XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php')) {
179
                    require_once XOOPS_ROOT_PATH . '/class/htmlarea/formhtmlarea.php';
180
                    $editor = new XoopsFormHtmlarea($caption, $name, $value);
181
                }
182
                break;
183
184
            case 'dhtmltextarea':
185
                $editor = new XoopsFormDhtmlTextArea($caption, $name, $value, 10, 50, $supplemental);
186
                break;
187
188
            case 'textarea':
189
                $editor = new XoopsFormTextArea($caption, $name, $value);
190
                break;
191
192
            case 'tinyeditor':
193
            case 'tinymce':
194
                if (is_readable(XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php')) {
195
                    require_once XOOPS_ROOT_PATH . '/class/xoopseditor/tinyeditor/formtinyeditortextarea.php';
196
                    $editor = new XoopsFormTinyeditorTextArea(array(
197
                                                                  'caption' => $caption,
198
                                                                  'name'    => $name,
199
                                                                  'value'   => $value,
200
                                                                  'width'   => '100%',
201
                                                                  'height'  => '400px'
202
                                                              ));
203
                }
204
                break;
205
206 View Code Duplication
            case 'koivi':
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...
207
                if (is_readable(XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php')) {
208
                    require_once XOOPS_ROOT_PATH . '/class/wysiwyg/formwysiwygtextarea.php';
209
                    $editor = new XoopsFormWysiwygTextArea($caption, $name, $value, $width, $height, '');
210
                }
211
                break;
212
        }
213
214
        return $editor;
215
    }
216
217
    /**
218
     * Create (in a link) a javascript confirmation's box
219
     *
220
     * @param  string  $message Message to display
221
     * @param  boolean $form    Is this a confirmation for a form ?
222
     * @return string  the javascript code to insert in the link (or in the form)
223
     */
224
    public static function javascriptLinkConfirm($message, $form = false)
225
    {
226
        if (!$form) {
227
            return "onclick=\"javascript:return confirm('" . str_replace("'", ' ', $message) . "')\"";
228
        } else {
229
            return "onSubmit=\"javascript:return confirm('" . str_replace("'", ' ', $message) . "')\"";
230
        }
231
    }
232
233
    /**
234
     * Get current user IP
235
     *
236
     * @return string IP address (format Ipv4)
237
     */
238
    public static function IP()
0 ignored issues
show
Coding Style introduced by
IP uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
239
    {
240
        $proxy_ip = '';
241
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
242
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
243
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
244
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED'];
245
        } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
246
            $proxy_ip = $_SERVER['HTTP_FORWARDED_FOR'];
247
        } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
248
            $proxy_ip = $_SERVER['HTTP_FORWARDED'];
249
        } elseif (!empty($_SERVER['HTTP_VIA'])) {
250
            $proxy_ip = $_SERVER['HTTP_VIA'];
251
        } elseif (!empty($_SERVER['HTTP_X_COMING_FROM'])) {
252
            $proxy_ip = $_SERVER['HTTP_X_COMING_FROM'];
253
        } elseif (!empty($_SERVER['HTTP_COMING_FROM'])) {
254
            $proxy_ip = $_SERVER['HTTP_COMING_FROM'];
255
        }
256
        $regs = array();
257
        //if (!empty($proxy_ip) && $is_ip = ereg('^([0-9]{1,3}\.){3,3}[0-9]{1,3}', $proxy_ip, $regs) && count($regs) > 0) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
258
        if (!empty($proxy_ip) && filter_var($proxy_ip, FILTER_VALIDATE_IP) && count($regs) > 0) {
259
            $the_IP = $regs[0];
260
        } else {
261
            $the_IP = $_SERVER['REMOTE_ADDR'];
262
        }
263
264
        return $the_IP;
265
    }
266
267
    /**
268
     * Set the page's title, meta description and meta keywords
269
     * Datas are supposed to be sanitized
270
     *
271
     * @param  string $pageTitle       Page's Title
272
     * @param  string $metaDescription Page's meta description
273
     * @param  string $metaKeywords    Page's meta keywords
274
     * @return void
275
     */
276
    public static function setMetas($pageTitle = '', $metaDescription = '', $metaKeywords = '')
277
    {
278
        global $xoTheme, $xoTheme, $xoopsTpl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
279
        $xoopsTpl->assign('xoops_pagetitle', $pageTitle);
280
        if (isset($xoTheme) && is_object($xoTheme)) {
281
            if (!empty($metaKeywords)) {
282
                $xoTheme->addMeta('meta', 'keywords', $metaKeywords);
283
            }
284
            if (!empty($metaDescription)) {
285
                $xoTheme->addMeta('meta', 'description', $metaDescription);
286
            }
287
        } elseif (isset($xoopsTpl) && is_object($xoopsTpl)) { // Compatibility for old Xoops versions
288
            if (!empty($metaKeywords)) {
289
                $xoopsTpl->assign('xoops_meta_keywords', $metaKeywords);
290
            }
291
            if (!empty($metaDescription)) {
292
                $xoopsTpl->assign('xoops_meta_description', $metaDescription);
293
            }
294
        }
295
    }
296
297
    /**
298
     * Send an email from a template to a list of recipients
299
     *
300
     * @param         $tplName
301
     * @param  array  $recipients List of recipients
302
     * @param  string $subject    Email's subject
303
     * @param  array  $variables  Varirables to give to the template
304
     * @return bool   Result of the send
305
     * @internal param string $tpl_name Template's name
306
     */
307
    public static function sendEmailFromTpl($tplName, $recipients, $subject, $variables)
308
    {
309
        global $xoopsConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
310
        require_once XOOPS_ROOT_PATH . '/class/xoopsmailer.php';
311
        if (!is_array($recipients)) {
312
            if (trim($recipients) == '') {
313
                return false;
314
            }
315
        } else {
316
            if (count($recipients) == 0) {
317
                return false;
318
            }
319
        }
320
        if (function_exists('xoops_getMailer')) {
321
            $xoopsMailer = xoops_getMailer();
322
        } else {
323
            $xoopsMailer =& getMailer();
324
        }
325
326
        $xoopsMailer->useMail();
327
        $templateDir = XOOPS_ROOT_PATH . '/modules/' . static::MODULE_NAME . '/language/' . $xoopsConfig['language'] . '/mail_template';
328
        if (!is_dir($templateDir)) {
329
            $templateDir = XOOPS_ROOT_PATH . '/modules/' . static::MODULE_NAME . '/language/english/mail_template';
330
        }
331
        $xoopsMailer->setTemplateDir($templateDir);
332
        $xoopsMailer->setTemplate($tplName);
333
        $xoopsMailer->setToEmails($recipients);
334
        // TODO: Change !
335
        // $xoopsMailer->setFromEmail('[email protected]');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
336
        //$xoopsMailer->setFromName('MonSite');
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
337
        $xoopsMailer->setSubject($subject);
338
        foreach ($variables as $key => $value) {
339
            $xoopsMailer->assign($key, $value);
340
        }
341
        $res = $xoopsMailer->send();
342
        unset($xoopsMailer);
343
        $filename = XOOPS_UPLOAD_PATH . '/logmail_' . static::MODULE_NAME . '.php';
344
        if (!file_exists($filename)) {
345
            $fp = @fopen($filename, 'a');
346
            if ($fp) {
347
                fwrite($fp, "<?php exit(); ?>\n");
348
                fclose($fp);
349
            }
350
        }
351
        $fp = @fopen($filename, 'a');
352
353
        if ($fp) {
354
            fwrite($fp, str_repeat('-', 120) . "\n");
355
            fwrite($fp, date('d/m/Y H:i:s') . "\n");
356
            fwrite($fp, 'Template name : ' . $tplName . "\n");
357
            fwrite($fp, 'Email subject : ' . $subject . "\n");
358
            if (is_array($recipients)) {
359
                fwrite($fp, 'Recipient(s) : ' . implode(',', $recipients) . "\n");
360
            } else {
361
                fwrite($fp, 'Recipient(s) : ' . $recipients . "\n");
362
            }
363
            fwrite($fp, 'Transmited variables : ' . implode(',', $variables) . "\n");
364
            fclose($fp);
365
        }
366
367
        return $res;
368
    }
369
370
    /**
371
     * Remove module's cache
372
     */
373
    public static function updateCache()
374
    {
375
        global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
376
        $folder  = $xoopsModule->getVar('dirname');
377
        $tpllist = array();
0 ignored issues
show
Unused Code introduced by
$tpllist 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...
378
        require_once XOOPS_ROOT_PATH . '/class/xoopsblock.php';
379
        require_once XOOPS_ROOT_PATH . '/class/template.php';
380
        $tplfileHandler = xoops_getHandler('tplfile');
381
        $tpllist         = $tplfileHandler->find(null, null, null, $folder);
382
        xoops_template_clear_module_cache($xoopsModule->getVar('mid')); // Clear module's blocks cache
383
384
        foreach ($tpllist as $onetemplate) { // Remove cache for each page.
385
            if ($onetemplate->getVar('tpl_type') === 'module') {
386
                //  Note, I've been testing all the other methods (like the one of Smarty) and none of them run, that's why I have used this code
387
                $files_del = array();
0 ignored issues
show
Unused Code introduced by
$files_del 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...
388
                $files_del = glob(XOOPS_CACHE_PATH . '/*' . $onetemplate->getVar('tpl_file') . '*');
389
                if (count($files_del) > 0 && is_array($files_del)) {
390
                    foreach ($files_del as $one_file) {
391
                        if (is_file($one_file)) {
392
                            unlink($one_file);
393
                        }
394
                    }
395
                }
396
            }
397
        }
398
    }
399
400
    /**
401
     * Redirect user with a message
402
     *
403
     * @param string $message message to display
404
     * @param string $url     The place where to go
405
     * @param        integer  timeout Time to wait before to redirect
406
     */
407
    public static function redirect($message = '', $url = 'index.php', $time = 2)
408
    {
409
        redirect_header($url, $time, $message);
410
    }
411
412
    /**
413
     * Internal function used to get the handler of the current module
414
     *
415
     * @return object The module
416
     */
417
    protected static function _getModule()
418
    {
419
        static $mymodule;
420
        if (!isset($mymodule)) {
421
            global $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
422
            if (isset($xoopsModule) && is_object($xoopsModule) && $xoopsModule->getVar('dirname') == OLEDRION_DIRNAME) {
423
                $mymodule = $xoopsModule;
424
            } else {
425
                $hModule  = xoops_getHandler('module');
426
                $mymodule = $hModule->getByDirname(OLEDRION_DIRNAME);
427
            }
428
        }
429
430
        return $mymodule;
431
    }
432
433
    /**
434
     * Returns the module's name (as defined by the user in the module manager) with cache
435
     * @return string Module's name
436
     */
437
    public static function getModuleName()
438
    {
439
        static $moduleName;
440
        if (!isset($moduleName)) {
441
            $mymodule   = static::_getModule();
442
            $moduleName = $mymodule->getVar('name');
443
        }
444
445
        return $moduleName;
446
    }
447
448
    /**
449
     * Create a title for the href tags inside html links
450
     *
451
     * @param  string $title Text to use
452
     * @return string Formated text
453
     */
454
    public static function makeHrefTitle($title)
455
    {
456
        $s = "\"'";
457
        $r = '  ';
458
459
        return strtr($title, $s, $r);
460
    }
461
462
    /**
463
     * Retourne la liste des utilisateurs appartenants à un groupe
464
     *
465
     * @param  int $groupId Searched group
466
     * @return array Array of XoopsUsers
467
     */
468
    public static function getUsersFromGroup($groupId)
469
    {
470
        $users          = array();
0 ignored issues
show
Unused Code introduced by
$users 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...
471
        $memberHandler = xoops_getHandler('member');
472
        $users          = $memberHandler->getUsersByGroup($groupId, true);
473
474
        return $users;
475
    }
476
477
    /**
478
     * Retourne la liste des emails des utilisateurs membres d'un groupe
479
     *
480
     * @param $groupId
481
     * @return array Emails list
482
     * @internal param int $group_id Group's number
483
     */
484
    public static function getEmailsFromGroup($groupId)
485
    {
486
        $ret   = array();
487
        $users = static::getUsersFromGroup($groupId);
488
        foreach ($users as $user) {
489
            $ret[] = $user->getVar('email');
490
        }
491
492
        return $ret;
493
    }
494
495
    /**
496
     * Vérifie que l'utilisateur courant fait partie du groupe des administrateurs
497
     *
498
     * @return booleean Admin or not
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
499
     */
500
    public static function isAdmin()
501
    {
502
        global $xoopsUser, $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
503
        if (is_object($xoopsUser)) {
504
            if (in_array(XOOPS_GROUP_ADMIN, $xoopsUser->getGroups())) {
505
                return true;
506
            } elseif (isset($xoopsModule) && $xoopsUser->isAdmin($xoopsModule->getVar('mid'))) {
507
                return true;
508
            }
509
        }
510
511
        return false;
512
    }
513
514
    /**
515
     * Returns the current date in the Mysql format
516
     *
517
     * @return string Date in the Mysql format
518
     */
519
    public static function getCurrentSQLDate()
520
    {
521
        return date('Y-m-d'); // 2007-05-02
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
522
    }
523
524
    /**
525
     * @return bool|string
526
     */
527
    public function getCurrentSQLDateTime()
528
    {
529
        return date('Y-m-d H:i:s'); // 2007-05-02
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
530
    }
531
532
    /**
533
     * Convert a Mysql date to the human's format
534
     *
535
     * @param  string $date The date to convert
536
     * @param  string $format
537
     * @return string The date in a human form
538
     */
539
    public function SQLDateToHuman($date, $format = 'l')
540
    {
541
        if ($date != '0000-00-00' && xoops_trim($date) != '') {
542
            return formatTimestamp(strtotime($date), $format);
543
        } else {
544
            return '';
545
        }
546
    }
547
548
    /**
549
     * Convert a timestamp to a Mysql date
550
     *
551
     * @param  integer $timestamp The timestamp to use
552
     * @return string  The date in the Mysql format
553
     */
554
    public function timestampToMysqlDate($timestamp)
555
    {
556
        return date('Y-m-d', (int)$timestamp);
557
    }
558
559
    /**
560
     * Conversion d'un dateTime Mysql en date lisible en français
561
     * @param $dateTime
562
     * @return bool|string
563
     */
564
    public function sqlDateTimeToFrench($dateTime)
565
    {
566
        return date('d/m/Y H:i:s', strtotime($dateTime));
567
    }
568
569
    /**
570
     * Convert a timestamp to a Mysql datetime form
571
     * @param  integer $timestamp The timestamp to use
572
     * @return string  The date and time in the Mysql format
573
     */
574
    public function timestampToMysqlDateTime($timestamp)
575
    {
576
        return date('Y-m-d H:i:s', $timestamp);
577
    }
578
579
    /**
580
     * This function indicates if the current Xoops version needs to add asterisks to required fields in forms
581
     *
582
     * @return boolean Yes = we need to add them, false = no
583
     */
584
    public static function needsAsterisk()
585
    {
586
        if (static::isX23()) {
587
            return false;
588
        }
589
        if (strpos(strtolower(XOOPS_VERSION), 'impresscms') !== false) {
590
            return false;
591
        }
592
        if (strpos(strtolower(XOOPS_VERSION), 'legacy') === false) {
593
            $xv = xoops_trim(str_replace('XOOPS ', '', XOOPS_VERSION));
594
            if ((int)substr($xv, 4, 2) >= 17) {
595
                return false;
596
            }
597
        }
598
599
        return true;
600
    }
601
602
    /**
603
     * Mark the mandatory fields of a form with a star
604
     *
605
     * @param  object $sform The form to modify
606
     * @return object The modified form
607
     * @internal param string $caracter The character to use to mark fields
608
     */
609
    public static function formMarkRequiredFields($sform)
610
    {
611
        if (static::needsAsterisk()) {
612
            $required = array();
613
            foreach ($sform->getRequired() as $item) {
614
                $required[] = $item->_name;
615
            }
616
            $elements = array();
0 ignored issues
show
Unused Code introduced by
$elements 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...
617
            $elements = $sform->getElements();
618
            $cnt      = count($elements);
619
            for ($i = 0; $i < $cnt; ++$i) {
620
                if (is_object($elements[$i]) && in_array($elements[$i]->_name, $required)) {
621
                    $elements[$i]->_caption .= ' *';
622
                }
623
            }
624
        }
625
626
        return $sform;
627
    }
628
629
    /**
630
     * Create an html heading (from h1 to h6)
631
     *
632
     * @param  string  $title The text to use
633
     * @param  integer $level Level to return
634
     * @return string  The heading
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
635
     */
636
    public static function htitle($title = '', $level = 1)
637
    {
638
        printf('<h%01d>%s</h%01d>', $level, $title, $level);
639
    }
640
641
    /**
642
     * Create a unique upload filename
643
     *
644
     * @param  string  $folder   The folder where the file will be saved
645
     * @param  string  $fileName Original filename (coming from the user)
646
     * @param  boolean $trimName Do we need to create a "short" unique name ?
647
     * @return string  The unique filename to use (with its extension)
648
     */
649
    public static function createUploadName($folder, $fileName, $trimName = false)
0 ignored issues
show
Coding Style introduced by
createUploadName uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
650
    {
651
        $workingfolder = $folder;
652
        if (xoops_substr($workingfolder, strlen($workingfolder) - 1, 1) !== '/') {
653
            $workingfolder .= '/';
654
        }
655
        $ext  = basename($fileName);
656
        $ext  = explode('.', $ext);
657
        $ext  = '.' . $ext[count($ext) - 1];
658
        $true = true;
659
        while ($true) {
660
            $ipbits = explode('.', $_SERVER['REMOTE_ADDR']);
661
            list($usec, $sec) = explode(' ', microtime());
662
            $usec = (integer)($usec * 65536);
663
            $sec  = ((integer)$sec) & 0xFFFF;
664
665
            if ($trimName) {
666
                $uid = sprintf('%06x%04x%04x', ($ipbits[0] << 24) | ($ipbits[1] << 16) | ($ipbits[2] << 8) | $ipbits[3], $sec, $usec);
667
            } else {
668
                $uid = sprintf('%08x-%04x-%04x', ($ipbits[0] << 24) | ($ipbits[1] << 16) | ($ipbits[2] << 8) | $ipbits[3], $sec, $usec);
669
            }
670
            if (!file_exists($workingfolder . $uid . $ext)) {
671
                $true = false;
672
            }
673
        }
674
675
        return $uid . $ext;
0 ignored issues
show
Bug introduced by
The variable $uid 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...
676
    }
677
678
    /**
679
     * Replace html entities with their ASCII equivalent
680
     *
681
     * @param  string $chaine The string undecode
682
     * @return string The undecoded string
683
     */
684
    public static function unhtml($chaine)
685
    {
686
        $search = $replace = array();
687
        $chaine = html_entity_decode($chaine);
688
689
        for ($i = 0; $i <= 255; ++$i) {
690
            $search[]  = '&#' . $i . ';';
691
            $replace[] = chr($i);
692
        }
693
        $replace[] = '...';
694
        $search[]  = '…';
695
        $replace[] = "'";
696
        $search[]  = '‘';
697
        $replace[] = "'";
698
        $search[]  = '’';
699
        $replace[] = '-';
700
        $search[]  = '&bull;'; // $replace[] = '•';
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
701
        $replace[] = '—';
702
        $search[]  = '&mdash;';
703
        $replace[] = '-';
704
        $search[]  = '&ndash;';
705
        $replace[] = '-';
706
        $search[]  = '&shy;';
707
        $replace[] = '"';
708
        $search[]  = '&quot;';
709
        $replace[] = '&';
710
        $search[]  = '&amp;';
711
        $replace[] = 'ˆ';
712
        $search[]  = '&circ;';
713
        $replace[] = '¡';
714
        $search[]  = '&iexcl;';
715
        $replace[] = '¦';
716
        $search[]  = '&brvbar;';
717
        $replace[] = '¨';
718
        $search[]  = '&uml;';
719
        $replace[] = '¯';
720
        $search[]  = '&macr;';
721
        $replace[] = '´';
722
        $search[]  = '&acute;';
723
        $replace[] = '¸';
724
        $search[]  = '&cedil;';
725
        $replace[] = '¿';
726
        $search[]  = '&iquest;';
727
        $replace[] = '˜';
728
        $search[]  = '&tilde;';
729
        $replace[] = "'";
730
        $search[]  = '&lsquo;'; // $replace[]='‘';
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
731
        $replace[] = "'";
732
        $search[]  = '&rsquo;'; // $replace[]='’';
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
733
        $replace[] = '‚';
734
        $search[]  = '&sbquo;';
735
        $replace[] = "'";
736
        $search[]  = '&ldquo;'; // $replace[]='“';
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
737
        $replace[] = "'";
738
        $search[]  = '&rdquo;'; // $replace[]='”';
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
739
        $replace[] = '„';
740
        $search[]  = '&bdquo;';
741
        $replace[] = '‹';
742
        $search[]  = '&lsaquo;';
743
        $replace[] = '›';
744
        $search[]  = '&rsaquo;';
745
        $replace[] = '<';
746
        $search[]  = '&lt;';
747
        $replace[] = '>';
748
        $search[]  = '&gt;';
749
        $replace[] = '±';
750
        $search[]  = '&plusmn;';
751
        $replace[] = '«';
752
        $search[]  = '&laquo;';
753
        $replace[] = '»';
754
        $search[]  = '&raquo;';
755
        $replace[] = '×';
756
        $search[]  = '&times;';
757
        $replace[] = '÷';
758
        $search[]  = '&divide;';
759
        $replace[] = '¢';
760
        $search[]  = '&cent;';
761
        $replace[] = '£';
762
        $search[]  = '&pound;';
763
        $replace[] = '¤';
764
        $search[]  = '&curren;';
765
        $replace[] = '¥';
766
        $search[]  = '&yen;';
767
        $replace[] = '§';
768
        $search[]  = '&sect;';
769
        $replace[] = '©';
770
        $search[]  = '&copy;';
771
        $replace[] = '¬';
772
        $search[]  = '&not;';
773
        $replace[] = '®';
774
        $search[]  = '&reg;';
775
        $replace[] = '°';
776
        $search[]  = '&deg;';
777
        $replace[] = 'µ';
778
        $search[]  = '&micro;';
779
        $replace[] = '¶';
780
        $search[]  = '&para;';
781
        $replace[] = '·';
782
        $search[]  = '&middot;';
783
        $replace[] = '†';
784
        $search[]  = '&dagger;';
785
        $replace[] = '‡';
786
        $search[]  = '&Dagger;';
787
        $replace[] = '‰';
788
        $search[]  = '&permil;';
789
        $replace[] = 'Euro';
790
        $search[]  = '&euro;'; // $replace[]='€'
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
791
        $replace[] = '¼';
792
        $search[]  = '&frac14;';
793
        $replace[] = '½';
794
        $search[]  = '&frac12;';
795
        $replace[] = '¾';
796
        $search[]  = '&frac34;';
797
        $replace[] = '¹';
798
        $search[]  = '&sup1;';
799
        $replace[] = '²';
800
        $search[]  = '&sup2;';
801
        $replace[] = '³';
802
        $search[]  = '&sup3;';
803
        $replace[] = 'á';
804
        $search[]  = '&aacute;';
805
        $replace[] = 'Á';
806
        $search[]  = '&Aacute;';
807
        $replace[] = 'â';
808
        $search[]  = '&acirc;';
809
        $replace[] = 'Â';
810
        $search[]  = '&Acirc;';
811
        $replace[] = 'à';
812
        $search[]  = '&agrave;';
813
        $replace[] = 'À';
814
        $search[]  = '&Agrave;';
815
        $replace[] = 'å';
816
        $search[]  = '&aring;';
817
        $replace[] = 'Å';
818
        $search[]  = '&Aring;';
819
        $replace[] = 'ã';
820
        $search[]  = '&atilde;';
821
        $replace[] = 'Ã';
822
        $search[]  = '&Atilde;';
823
        $replace[] = 'ä';
824
        $search[]  = '&auml;';
825
        $replace[] = 'Ä';
826
        $search[]  = '&Auml;';
827
        $replace[] = 'ª';
828
        $search[]  = '&ordf;';
829
        $replace[] = 'æ';
830
        $search[]  = '&aelig;';
831
        $replace[] = 'Æ';
832
        $search[]  = '&AElig;';
833
        $replace[] = 'ç';
834
        $search[]  = '&ccedil;';
835
        $replace[] = 'Ç';
836
        $search[]  = '&Ccedil;';
837
        $replace[] = 'ð';
838
        $search[]  = '&eth;';
839
        $replace[] = 'Ð';
840
        $search[]  = '&ETH;';
841
        $replace[] = 'é';
842
        $search[]  = '&eacute;';
843
        $replace[] = 'É';
844
        $search[]  = '&Eacute;';
845
        $replace[] = 'ê';
846
        $search[]  = '&ecirc;';
847
        $replace[] = 'Ê';
848
        $search[]  = '&Ecirc;';
849
        $replace[] = 'è';
850
        $search[]  = '&egrave;';
851
        $replace[] = 'È';
852
        $search[]  = '&Egrave;';
853
        $replace[] = 'ë';
854
        $search[]  = '&euml;';
855
        $replace[] = 'Ë';
856
        $search[]  = '&Euml;';
857
        $replace[] = 'ƒ';
858
        $search[]  = '&fnof;';
859
        $replace[] = 'í';
860
        $search[]  = '&iacute;';
861
        $replace[] = 'Í';
862
        $search[]  = '&Iacute;';
863
        $replace[] = 'î';
864
        $search[]  = '&icirc;';
865
        $replace[] = 'Î';
866
        $search[]  = '&Icirc;';
867
        $replace[] = 'ì';
868
        $search[]  = '&igrave;';
869
        $replace[] = 'Ì';
870
        $search[]  = '&Igrave;';
871
        $replace[] = 'ï';
872
        $search[]  = '&iuml;';
873
        $replace[] = 'Ï';
874
        $search[]  = '&Iuml;';
875
        $replace[] = 'ñ';
876
        $search[]  = '&ntilde;';
877
        $replace[] = 'Ñ';
878
        $search[]  = '&Ntilde;';
879
        $replace[] = 'ó';
880
        $search[]  = '&oacute;';
881
        $replace[] = 'Ó';
882
        $search[]  = '&Oacute;';
883
        $replace[] = 'ô';
884
        $search[]  = '&ocirc;';
885
        $replace[] = 'Ô';
886
        $search[]  = '&Ocirc;';
887
        $replace[] = 'ò';
888
        $search[]  = '&ograve;';
889
        $replace[] = 'Ò';
890
        $search[]  = '&Ograve;';
891
        $replace[] = 'º';
892
        $search[]  = '&ordm;';
893
        $replace[] = 'ø';
894
        $search[]  = '&oslash;';
895
        $replace[] = 'Ø';
896
        $search[]  = '&Oslash;';
897
        $replace[] = 'õ';
898
        $search[]  = '&otilde;';
899
        $replace[] = 'Õ';
900
        $search[]  = '&Otilde;';
901
        $replace[] = 'ö';
902
        $search[]  = '&ouml;';
903
        $replace[] = 'Ö';
904
        $search[]  = '&Ouml;';
905
        $replace[] = 'œ';
906
        $search[]  = '&oelig;';
907
        $replace[] = 'Œ';
908
        $search[]  = '&OElig;';
909
        $replace[] = 'š';
910
        $search[]  = '&scaron;';
911
        $replace[] = 'Š';
912
        $search[]  = '&Scaron;';
913
        $replace[] = 'ß';
914
        $search[]  = '&szlig;';
915
        $replace[] = 'þ';
916
        $search[]  = '&thorn;';
917
        $replace[] = 'Þ';
918
        $search[]  = '&THORN;';
919
        $replace[] = 'ú';
920
        $search[]  = '&uacute;';
921
        $replace[] = 'Ú';
922
        $search[]  = '&Uacute;';
923
        $replace[] = 'û';
924
        $search[]  = '&ucirc;';
925
        $replace[] = 'Û';
926
        $search[]  = '&Ucirc;';
927
        $replace[] = 'ù';
928
        $search[]  = '&ugrave;';
929
        $replace[] = 'Ù';
930
        $search[]  = '&Ugrave;';
931
        $replace[] = 'ü';
932
        $search[]  = '&uuml;';
933
        $replace[] = 'Ü';
934
        $search[]  = '&Uuml;';
935
        $replace[] = 'ý';
936
        $search[]  = '&yacute;';
937
        $replace[] = 'Ý';
938
        $search[]  = '&Yacute;';
939
        $replace[] = 'ÿ';
940
        $search[]  = '&yuml;';
941
        $replace[] = 'Ÿ';
942
        $search[]  = '&Yuml;';
943
        $chaine    = str_replace($search, $replace, $chaine);
944
945
        return $chaine;
946
    }
947
948
    /**
949
     * Création d'une titre pour être utilisé par l'url rewriting
950
     *
951
     * @param  string  $content Le texte à utiliser pour créer l'url
952
     * @param  integer $urw     La limite basse pour créer les mots
953
     * @return string  Le texte à utiliser pour l'url
954
     *                          Note, some parts are from Solo's code
955
     */
956
    public static function makeSeoUrl($content, $urw = 1)
957
    {
958
        $s       = "ÀÁÂÃÄÅÒÓÔÕÖØÈÉÊËÇÌÍÎÏÙÚÛܟÑàáâãäåòóôõöøèéêëçìíîïùúûüÿñ '()";
959
        $r       = 'AAAAAAOOOOOOEEEECIIIIUUUUYNaaaaaaooooooeeeeciiiiuuuuyn----';
960
        $content = static::unhtml($content); // First, remove html entities
961
        $content = strtr($content, $s, $r);
962
        $content = strip_tags($content);
963
        $content = strtolower($content);
964
        $content = htmlentities($content); // TODO: Vérifier
965
        $content = preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/', '$1', $content);
966
        $content = html_entity_decode($content);
967
        $content = preg_replace('/quot/i', ' ', $content);
968
        $content = preg_replace("/'/i", ' ', $content);
969
        $content = preg_replace('/-/i', ' ', $content);
970
        $content = preg_replace('/[[:punct:]]/i', '', $content);
971
972
        // Selon option mais attention au fichier .htaccess !
973
        // $content = eregi_replace('[[:digit:]]','', $content);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
974
        $content = preg_replace('/[^a-z|A-Z|0-9]/', '-', $content);
975
976
        $words    = explode(' ', $content);
977
        $keywords = '';
978
        foreach ($words as $word) {
979
            if (strlen($word) >= $urw) {
980
                $keywords .= '-' . trim($word);
981
            }
982
        }
983
        if (!$keywords) {
984
            $keywords = '-';
985
        }
986
        // Supprime les tirets en double
987
        $keywords = str_replace('---', '-', $keywords);
988
        $keywords = str_replace('--', '-', $keywords);
989
        // Supprime un éventuel tiret à la fin de la chaine
990
        if (substr($keywords, strlen($keywords) - 1, 1) == '-') {
991
            $keywords = substr($keywords, 0, strlen($keywords) - 1);
992
        }
993
994
        return $keywords;
995
    }
996
997
    /**
998
     * Create the meta keywords based on the content
999
     *
1000
     * @param  string $content Content from which we have to create metakeywords
1001
     * @return string The list of meta keywords
1002
     */
1003
    public static function createMetaKeywords($content)
0 ignored issues
show
Coding Style introduced by
createMetaKeywords uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1004
    {
1005
        $keywordscount = static::getModuleOption('metagen_maxwords');
1006
        $keywordsorder = static::getModuleOption('metagen_order');
1007
1008
        $tmp = array();
1009
        // Search for the "Minimum keyword length"
1010
        if (isset($_SESSION['oledrion_keywords_limit'])) {
1011
            $limit = $_SESSION['oledrion_keywords_limit'];
1012
        } else {
1013
            $configHandler                      = xoops_getHandler('config');
1014
            $xoopsConfigSearch                   = $configHandler->getConfigsByCat(XOOPS_CONF_SEARCH);
1015
            $limit                               = $xoopsConfigSearch['keyword_min'];
1016
            $_SESSION['oledrion_keywords_limit'] = $limit;
1017
        }
1018
        $myts            = MyTextSanitizer::getInstance();
1019
        $content         = str_replace('<br>', ' ', $content);
1020
        $content         = $myts->undoHtmlSpecialChars($content);
1021
        $content         = strip_tags($content);
1022
        $content         = strtolower($content);
1023
        $search_pattern  = array(
1024
            '&nbsp;',
1025
            "\t",
1026
            "\r\n",
1027
            "\r",
1028
            "\n",
1029
            ',',
1030
            '.',
1031
            "'",
1032
            ';',
1033
            ':',
1034
            ')',
1035
            '(',
1036
            '"',
1037
            '?',
1038
            '!',
1039
            '{',
1040
            '}',
1041
            '[',
1042
            ']',
1043
            '<',
1044
            '>',
1045
            '/',
1046
            '+',
1047
            '-',
1048
            '_',
1049
            '\\',
1050
            '*'
1051
        );
1052
        $replace_pattern = array(
1053
            ' ',
1054
            ' ',
1055
            ' ',
1056
            ' ',
1057
            ' ',
1058
            ' ',
1059
            ' ',
1060
            ' ',
1061
            '',
1062
            '',
1063
            '',
1064
            '',
1065
            '',
1066
            '',
1067
            '',
1068
            '',
1069
            '',
1070
            '',
1071
            '',
1072
            '',
1073
            '',
1074
            '',
1075
            '',
1076
            '',
1077
            '',
1078
            '',
1079
            ''
1080
        );
1081
        $content         = str_replace($search_pattern, $replace_pattern, $content);
1082
        $keywords        = explode(' ', $content);
1083
        switch ($keywordsorder) {
1084
            case 0: // Ordre d'apparition dans le texte
1085
                $keywords = array_unique($keywords);
1086
                break;
1087
            case 1: // Ordre de fréquence des mots
1088
                $keywords = array_count_values($keywords);
1089
                asort($keywords);
1090
                $keywords = array_keys($keywords);
1091
                break;
1092
            case 2: // Ordre inverse de la fréquence des mots
1093
                $keywords = array_count_values($keywords);
1094
                arsort($keywords);
1095
                $keywords = array_keys($keywords);
1096
                break;
1097
        }
1098
        // Remove black listed words
1099
        if (xoops_trim(static::getModuleOption('metagen_blacklist')) != '') {
1100
            $metagen_blacklist = str_replace("\r", '', static::getModuleOption('metagen_blacklist'));
1101
            $metablack         = explode("\n", $metagen_blacklist);
1102
            array_walk($metablack, 'trim');
1103
            $keywords = array_diff($keywords, $metablack);
1104
        }
1105
1106
        foreach ($keywords as $keyword) {
1107
            if (strlen($keyword) >= $limit && !is_numeric($keyword)) {
1108
                $tmp[] = $keyword;
1109
            }
1110
        }
1111
        $tmp = array_slice($tmp, 0, $keywordscount);
1112
        if (count($tmp) > 0) {
1113
            return implode(',', $tmp);
1114
        } else {
1115
            if (!isset($configHandler) || !is_object($configHandler)) {
1116
                $configHandler = xoops_getHandler('config');
1117
            }
1118
            $xoopsConfigMetaFooter = $configHandler->getConfigsByCat(XOOPS_CONF_METAFOOTER);
1119
            if (isset($xoopsConfigMetaFooter['meta_keywords'])) {
1120
                return $xoopsConfigMetaFooter['meta_keywords'];
1121
            } else {
1122
                return '';
1123
            }
1124
        }
1125
    }
1126
1127
    /**
1128
     * Fonction chargée de gérer l'upload
1129
     *
1130
     * @param  integer $indice L'indice du fichier à télécharger
1131
     * @param  string  $dstpath
1132
     * @param  null    $mimeTypes
1133
     * @param  null    $uploadMaxSize
1134
     * @param  null    $maxWidth
1135
     * @param  null    $maxHeight
1136
     * @return mixed   True si l'upload s'est bien déroulé sinon le message d'erreur correspondant
1137
     */
1138
    public static function uploadFile(
0 ignored issues
show
Coding Style introduced by
uploadFile uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
uploadFile uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1139
        $indice,
1140
        $dstpath = XOOPS_UPLOAD_PATH,
1141
        $mimeTypes = null,
1142
        $uploadMaxSize = null,
1143
        $maxWidth = null,
1144
        $maxHeight = null
1145
    ) {
1146
        require_once XOOPS_ROOT_PATH . '/class/uploader.php';
1147
        global $destname;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1148
        if (isset($_POST['xoops_upload_file'])) {
1149
            require_once XOOPS_ROOT_PATH . '/class/uploader.php';
1150
            $fldname = '';
0 ignored issues
show
Unused Code introduced by
$fldname 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...
1151
            $fldname = $_FILES[$_POST['xoops_upload_file'][$indice]];
1152
            $fldname = get_magic_quotes_gpc() ? stripslashes($fldname['name']) : $fldname['name'];
1153
            if (xoops_trim($fldname != '')) {
1154
                $destname = static::createUploadName($dstpath, $fldname, true);
1155
                if ($mimeTypes === null) {
1156
                    $permittedtypes = explode("\n", str_replace("\r", '', static::getModuleOption('mimetypes')));
1157
                    array_walk($permittedtypes, 'trim');
1158
                } else {
1159
                    $permittedtypes = $mimeTypes;
1160
                }
1161
                if ($uploadMaxSize === null) {
1162
                    $uploadSize = static::getModuleOption('maxuploadsize');
1163
                } else {
1164
                    $uploadSize = $uploadMaxSize;
1165
                }
1166
                $uploader = new XoopsMediaUploader($dstpath, $permittedtypes, $uploadSize, $maxWidth, $maxHeight);
1167
                //$uploader->allowUnknownTypes = true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1168
                $uploader->setTargetFileName($destname);
1169
                if ($uploader->fetchMedia($_POST['xoops_upload_file'][$indice])) {
1170
                    if ($uploader->upload()) {
1171
                        return true;
1172
                    } else {
1173
                        return _ERRORS . ' ' . htmlentities($uploader->getErrors());
1174
                    }
1175
                } else {
1176
                    return htmlentities($uploader->getErrors());
1177
                }
1178
            } else {
1179
                return false;
1180
            }
1181
        } else {
1182
            return false;
1183
        }
1184
    }
1185
1186
    /**
1187
     * Resize a Picture to some given dimensions (using the wideImage library)
1188
     *
1189
     * @param  string  $src_path      Picture's source
1190
     * @param  string  $dst_path      Picture's destination
1191
     * @param  integer $param_width   Maximum picture's width
1192
     * @param  integer $param_height  Maximum picture's height
1193
     * @param  boolean $keep_original Do we have to keep the original picture ?
1194
     * @param  string  $fit           Resize mode (see the wideImage library for more information)
1195
     * @return bool
1196
     */
1197
    public function resizePicture(
1198
        $src_path,
1199
        $dst_path,
1200
        $param_width,
1201
        $param_height,
1202
        $keep_original = false,
1203
        $fit = 'inside'
1204
    ) {
1205
        //        require_once OLEDRION_PATH . 'class/wideimage/WideImage.inc.php';
1206
        $resize = true;
1207
        if (OLEDRION_DONT_RESIZE_IF_SMALLER) {
1208
            $pictureDimensions = getimagesize($src_path);
1209
            if (is_array($pictureDimensions)) {
1210
                $width  = $pictureDimensions[0];
1211
                $height = $pictureDimensions[1];
1212
                if ($width < $param_width && $height < $param_height) {
1213
                    $resize = false;
1214
                }
1215
            }
1216
        }
1217
1218
        $img = WideImage::load($src_path);
1219
        if ($resize) {
1220
            $result = $img->resize($param_width, $param_height, $fit);
1221
            $result->saveToFile($dst_path);
1222
        } else {
1223
            @copy($src_path, $dst_path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1224
        }
1225
1226
        if (!$keep_original) {
1227
            @unlink($src_path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1228
        }
1229
1230
        return true;
1231
    }
1232
1233
    /**
1234
     * Déclenchement d'une alerte Xoops suite à un évènement
1235
     *
1236
     * @param string       $category La catégorie de l'évènement
1237
     * @param integer      $itemId   L'ID de l'élément (trop général pour être décris précisément)
1238
     * @param unknown_type $event    L'évènement qui est déclencé
1239
     * @param unknown_type $tags     Les variables à passer au template
1240
     */
1241
    public function notify($category, $itemId, $event, $tags)
1242
    {
1243
        $notificationHandler = xoops_getHandler('notification');
1244
        $tags['X_MODULE_URL'] = OLEDRION_URL;
1245
        $notificationHandler->triggerEvent($category, $itemId, $event, $tags);
1246
    }
1247
1248
    /**
1249
     * Ajoute des jours à une date et retourne la nouvelle date au format Date de Mysql
1250
     *
1251
     * @param  int     $duration
1252
     * @param  integer $startingDate Date de départ (timestamp)
1253
     * @return bool|string
1254
     * @internal param int $durations Durée en jours
1255
     */
1256
    public function addDaysToDate($duration = 1, $startingDate = 0)
1257
    {
1258
        if ($startingDate == 0) {
1259
            $startingDate = time();
1260
        }
1261
        $endingDate = $startingDate + ($duration * 86400);
1262
1263
        return date('Y-m-d', $endingDate);
1264
    }
1265
1266
    /**
1267
     * Retourne un breadcrumb en fonction des paramètres passés et en partant (d'office) de la racine du module
1268
     *
1269
     * @param  array  $path  Le chemin complet (excepté la racine) du breadcrumb sous la forme clé=url valeur=titre
1270
     * @param  string $raquo Le séparateur par défaut à utiliser
1271
     * @return string le breadcrumb
1272
     */
1273
    public static function breadcrumb($path, $raquo = ' &raquo; ')
1274
    {
1275
        $breadcrumb        = '';
1276
        $workingBreadcrumb = array();
1277
        if (is_array($path)) {
1278
            $moduleName          = static::getModuleName();
1279
            $workingBreadcrumb[] = "<a href='" . OLEDRION_URL . "' title='" . static::makeHrefTitle($moduleName) . "'>" . $moduleName . '</a>';
1280
            foreach ($path as $url => $title) {
1281
                $workingBreadcrumb[] = "<a href='" . $url . "'>" . $title . '</a>';
1282
            }
1283
            $cnt = count($workingBreadcrumb);
1284
            for ($i = 0; $i < $cnt; ++$i) {
1285
                if ($i == $cnt - 1) {
1286
                    $workingBreadcrumb[$i] = strip_tags($workingBreadcrumb[$i]);
1287
                }
1288
            }
1289
            $breadcrumb = implode($raquo, $workingBreadcrumb);
1290
        }
1291
1292
        return $breadcrumb;
1293
    }
1294
1295
    /**
1296
     * @param $string
1297
     * @return string
1298
     */
1299
    public static function close_tags($string)
1300
    {
1301
        // match opened tags
1302
        if (preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $start_tags)) {
1303
            $start_tags = $start_tags[1];
1304
1305
            // match closed tags
1306
            if (preg_match_all('/<\/([a-z]+)>/', $string, $end_tags)) {
1307
                $complete_tags = array();
1308
                $end_tags      = $end_tags[1];
1309
1310
                foreach ($start_tags as $key => $val) {
1311
                    $posb = array_search($val, $end_tags);
1312
                    if (is_int($posb)) {
1313
                        unset($end_tags[$posb]);
1314
                    } else {
1315
                        $complete_tags[] = $val;
1316
                    }
1317
                }
1318
            } else {
1319
                $complete_tags = $start_tags;
1320
            }
1321
1322
            $complete_tags = array_reverse($complete_tags);
1323
            for ($i = 0, $iMax = count($complete_tags); $i < $iMax; ++$i) {
1324
                $string .= '</' . $complete_tags[$i] . '>';
1325
            }
1326
        }
1327
1328
        return $string;
1329
    }
1330
1331
    /**
1332
     * @param               $string
1333
     * @param  int          $length
1334
     * @param  string       $etc
1335
     * @param  bool         $break_words
1336
     * @return mixed|string
1337
     */
1338
    public static function truncate_tagsafe($string, $length = 80, $etc = '...', $break_words = false)
1339
    {
1340
        if ($length == 0) {
1341
            return '';
1342
        }
1343
1344
        if (strlen($string) > $length) {
1345
            $length -= strlen($etc);
1346
            if (!$break_words) {
1347
                $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
1348
                $string = preg_replace('/<[^>]*$/', '', $string);
1349
                $string = static::close_tags($string);
1350
            }
1351
1352
            return $string . $etc;
1353
        } else {
1354
            return $string;
1355
        }
1356
    }
1357
1358
    /**
1359
     * Create an infotip
1360
     * @param $text
1361
     * @return string
1362
     */
1363
    public static function makeInfotips($text)
1364
    {
1365
        $ret      = '';
1366
        $infotips = static::getModuleOption('infotips');
1367
        if ($infotips > 0) {
1368
            $myts = MyTextSanitizer::getInstance();
1369
            $ret  = $myts->htmlSpecialChars(xoops_substr(strip_tags($text), 0, $infotips));
1370
        }
1371
1372
        return $ret;
1373
    }
1374
1375
    /**
1376
     * Mise en place de l'appel à la feuille de style du module dans le template
1377
     * @param string $url
1378
     */
1379 View Code Duplication
    public static function setCSS($url = '')
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...
1380
    {
1381
        global $xoopsTpl, $xoTheme;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1382
        if ($url == '') {
1383
            $url = OLEDRION_URL . 'assets/css/oledrion.css';
1384
        }
1385
1386
        if (!is_object($xoTheme)) {
1387
            $xoopsTpl->assign('xoops_module_header', $xoopsTpl->get_template_vars('xoops_module_header') . "<link rel=\"stylesheet\" type=\"text/css\" href=\"$url\" />");
1388
        } else {
1389
            $xoTheme->addStylesheet($url);
1390
        }
1391
    }
1392
1393
    /**
1394
     * Mise en place de l'appel à la feuille de style du module dans le template
1395
     * @param string $language
1396
     */
1397 View Code Duplication
    public static function setLocalCSS($language = 'english')
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...
1398
    {
1399
        global $xoopsTpl, $xoTheme;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1400
1401
        $localcss = OLEDRION_URL . 'language/' . $language . '/style.css';
1402
1403
        if (!is_object($xoTheme)) {
1404
            $xoopsTpl->assign('xoops_module_header', $xoopsTpl->get_template_vars('xoops_module_header') . "<link rel=\"stylesheet\" type=\"text/css\" href=\"$localcss\" />");
1405
        } else {
1406
            $xoTheme->addStylesheet($localcss);
1407
        }
1408
    }
1409
1410
    /**
1411
     * Calcul du TTC à partir du HT et de la TVA
1412
     *
1413
     * @param  float   $ht     Montant HT
1414
     * @param  float   $vat    Taux de TVA
1415
     * @param  boolean $edit   Si faux alors le montant est formaté pour affichage sinon il reste tel quel
1416
     * @param  string  $format Format d'affichage du résultat (long ou court)
1417
     * @return mixed   Soit une chaine soit un flottant
1418
     */
1419
    public static function getTTC($ht, $vat, $edit = false, $format = 's')
1420
    {
1421
        $oledrion_Currency = Oledrion_Currency::getInstance();
1422
        $ttc               = $ht * (1 + ($vat / 100));
1423
        if (!$edit) {
1424
            return $oledrion_Currency->amountForDisplay($ttc, $format);
1425
        } else {
1426
            return $ttc;
1427
        }
1428
    }
1429
1430
    /**
1431
     * Renvoie le montant de la tva à partir du montant HT
1432
     * @param $ht
1433
     * @param $vat
1434
     * @return float
1435
     */
1436
    public function getVAT($ht, $vat)
1437
    {
1438
        return (float)(($ht * $vat) / 100);
1439
    }
1440
1441
    /**
1442
     * Retourne le montant TTC
1443
     *
1444
     * @param  floatval $product_price Le montant du produit
1445
     * @param  integer  $vat_id        Le numéro de TVA
1446
     * @return floatval Le montant TTC si on a trouvé sa TVA sinon
1447
     */
1448
    public static function getAmountWithVat($product_price, $vat_id)
1449
    {
1450
        static $vats = array();
1451
        $vat_rate = null;
1452
        if (is_array($vats) && in_array($vat_id, $vats)) {
1453
            $vat_rate = $vats[$vat_id];
1454
        } else {
1455
            $handlers = OledrionHandler::getInstance();
1456
            $vat      = null;
0 ignored issues
show
Unused Code introduced by
$vat 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...
1457
            $vat      = $handlers->h_oledrion_vat->get($vat_id);
0 ignored issues
show
Documentation introduced by
The property h_oledrion_vat does not exist on object<OledrionHandler>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1458
            if (is_object($vat)) {
1459
                $vat_rate      = $vat->getVar('vat_rate', 'e');
1460
                $vats[$vat_id] = $vat_rate;
1461
            }
1462
        }
1463
1464
        if (null !== $vat_rate) {
1465
            return ((float)$product_price * (float)$vat_rate / 100) + (float)$product_price;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return (double) $product...double) $product_price; (double) is incompatible with the return type documented by Oledrion_utils::getAmountWithVat of type floatval.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1466
        } else {
1467
            return $product_price;
1468
        }
1469
    }
1470
1471
    /**
1472
     * @param $datastream
1473
     * @param $url
1474
     * @return string
1475
     */
1476
    public function postIt($datastream, $url)
1477
    {
1478
        $url     = preg_replace('@^http://@i', '', $url);
1479
        $host    = substr($url, 0, strpos($url, '/'));
1480
        $uri     = strstr($url, '/');
1481
        $reqbody = '';
1482
        foreach ($datastream as $key => $val) {
1483
            if (!empty($reqbody)) {
1484
                $reqbody .= '&';
1485
            }
1486
            $reqbody .= $key . '=' . urlencode($val);
1487
        }
1488
        $contentlength = strlen($reqbody);
1489
        $reqheader     = "POST $uri HTTP/1.1\r\n" . "Host: $host\n" . "Content-Type: application/x-www-form-urlencoded\r\n" . "Content-Length: $contentlength\r\n\r\n" . "$reqbody\r\n";
1490
1491
        return $reqheader;
1492
    }
1493
1494
    /**
1495
     * Retourne le type Mime d'un fichier en utilisant d'abord finfo puis mime_content
1496
     *
1497
     * @param  string $filename Le fichier (avec son chemin d'accès complet) dont on veut connaître le type mime
1498
     * @return string
1499
     */
1500
    public static function getMimeType($filename)
1501
    {
1502
        if (function_exists('finfo_open')) {
1503
            $finfo    = finfo_open();
1504
            $mimetype = finfo_file($finfo, $filename, FILEINFO_MIME_TYPE);
1505
            finfo_close($finfo);
1506
1507
            return $mimetype;
1508
        } else {
1509
            if (function_exists('mime_content_type')) {
1510
                return mime_content_type($filename);
1511
            } else {
1512
                return '';
1513
            }
1514
        }
1515
    }
1516
1517
    /**
1518
     * Retourne un criteria compo qui permet de filtrer les produits sur le mois courant
1519
     *
1520
     * @return object
1521
     */
1522
    public function getThisMonthCriteria()
1523
    {
1524
        $start             = mktime(0, 1, 0, date('n'), date('j'), date('Y'));
1525
        $end               = mktime(0, 0, 0, date('n'), date('t'), date('Y'));
1526
        $criteriaThisMonth = new CriteriaCompo();
1527
        $criteriaThisMonth->add(new Criteria('product_submitted', $start, '>='));
1528
        $criteriaThisMonth->add(new Criteria('product_submitted', $end, '<='));
1529
1530
        return $criteriaThisMonth;
1531
    }
1532
1533
    /**
1534
     * Retourne une liste d'objets XoopsUsers à partir d'une liste d'identifiants
1535
     *
1536
     * @param  array $xoopsUsersIDs La liste des ID
1537
     * @return array Les objets XoopsUsers
1538
     */
1539
    public static function getUsersFromIds($xoopsUsersIDs)
1540
    {
1541
        $users = array();
1542
        if (is_array($xoopsUsersIDs) && count($xoopsUsersIDs) > 0) {
1543
            $xoopsUsersIDs = array_unique($xoopsUsersIDs);
1544
            sort($xoopsUsersIDs);
1545
            if (count($xoopsUsersIDs) > 0) {
1546
                $memberHandler = xoops_getHandler('user');
1547
                $criteria       = new Criteria('uid', '(' . implode(',', $xoopsUsersIDs) . ')', 'IN');
1548
                $criteria->setSort('uid');
1549
                $users = $memberHandler->getObjects($criteria, true);
1550
            }
1551
        }
1552
1553
        return $users;
1554
    }
1555
1556
    /**
1557
     * Retourne l'ID de l'utilisateur courant (s'il est connecté)
1558
     * @return integer L'uid ou 0
1559
     */
1560
    public static function getCurrentUserID()
1561
    {
1562
        global $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1563
        $uid = is_object($xoopsUser) ? $xoopsUser->getVar('uid') : 0;
1564
1565
        return $uid;
1566
    }
1567
1568
    /**
1569
     * Retourne la liste des groupes de l'utilisateur courant (avec cache)
1570
     * @param  int $uid
1571
     * @return array Les ID des groupes auquel l'utilisateur courant appartient
1572
     */
1573
    public function getMemberGroups($uid = 0)
1574
    {
1575
        static $buffer = array();
1576
        if ($uid == 0) {
1577
            $uid = static::getCurrentUserID();
1578
        }
1579
1580
        if (is_array($buffer) && count($buffer) > 0 && isset($buffer[$uid])) {
1581
            return $buffer[$uid];
1582
        } else {
1583
            if ($uid > 0) {
1584
                $memberHandler = xoops_getHandler('member');
1585
                $buffer[$uid]   = $memberHandler->getGroupsByUser($uid, false); // Renvoie un tableau d'ID (de groupes)
1586
            } else {
1587
                $buffer[$uid] = array(XOOPS_GROUP_ANONYMOUS);
1588
            }
1589
        }
1590
1591
        return $buffer[$uid];
1592
    }
1593
1594
    /**
1595
     * Indique si l'utilisateur courant fait partie d'une groupe donné (avec gestion de cache)
1596
     *
1597
     * @param  integer $group Groupe recherché
1598
     * @param  int     $uid
1599
     * @return bool    vrai si l'utilisateur fait partie du groupe, faux sinon
1600
     */
1601
    public static function isMemberOfGroup($group = 0, $uid = 0)
1602
    {
1603
        static $buffer = array();
1604
        $retval = false;
0 ignored issues
show
Unused Code introduced by
$retval 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...
1605
        if ($uid == 0) {
1606
            $uid = static::getCurrentUserID();
1607
        }
1608
        if (is_array($buffer) && array_key_exists($group, $buffer)) {
1609
            $retval = $buffer[$group];
1610
        } else {
1611
            $memberHandler = xoops_getHandler('member');
1612
            $groups         = $memberHandler->getGroupsByUser($uid, false); // Renvoie un tableau d'ID (de groupes)
1613
            $retval         = in_array($group, $groups);
1614
            $buffer[$group] = $retval;
1615
        }
1616
1617
        return $retval;
1618
    }
1619
1620
    /**
1621
     * Fonction chargée de vérifier qu'un répertoire existe, qu'on peut écrire dedans et création d'un fichier index.html
1622
     *
1623
     * @param  string $folder Le chemin complet du répertoire à vérifier
1624
     * @return void
1625
     */
1626
    public static function prepareFolder($folder)
1627
    {
1628
        if (!is_dir($folder)) {
1629
            mkdir($folder, 0777);
1630
            file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
1631
        }
1632
        chmod($folder, 0777);
1633
    }
1634
1635
    /**
1636
     * Duplicate a file in local
1637
     *
1638
     * @param  string $path     The file's path
1639
     * @param  string $filename The filename
1640
     * @return mixed  If the copy succeed, the new filename else false
1641
     * @since 2.1
1642
     */
1643
    public function duplicateFile($path, $filename)
1644
    {
1645
        $newName = static::createUploadName($path, $filename);
1646
        if (copy($path . '/' . $filename, $path . '/' . $newName)) {
1647
            return $newName;
1648
        } else {
1649
            return false;
1650
        }
1651
    }
1652
1653
    /**
1654
     * Load a language file
1655
     *
1656
     * @param string $languageFile     The required language file
1657
     * @param string $defaultExtension Default extension to use
1658
     * @since 2.2.2009.02.13
1659
     */
1660
    public static function loadLanguageFile($languageFile, $defaultExtension = '.php')
1661
    {
1662
        global $xoopsConfig;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1663
        $root = OLEDRION_PATH;
1664
        if (false === strpos($languageFile, $defaultExtension)) {
1665
            $languageFile .= $defaultExtension;
1666
        }
1667
        if (file_exists($root . 'language/' . $xoopsConfig['language'] . '/' . $languageFile)) {
1668
            require_once $root . 'language/' . $xoopsConfig['language'] . '/' . $languageFile;
1669
        } else { // Fallback
1670
            require_once $root . 'language/english' . '/' . $languageFile;
1671
        }
1672
    }
1673
1674
    /**
1675
     * Formatage d'un floattant pour la base de données
1676
     *
1677
     * @param float    Le montant à formater
1678
     * @return string le montant formaté
1679
     * @since 2.2.2009.02.25
1680
     */
1681
    public static function formatFloatForDB($amount)
1682
    {
1683
        return number_format($amount, 2, '.', '');
1684
    }
1685
1686
    /**
1687
     * Appelle un fichier Javascript à la manière de Xoops
1688
     *
1689
     * @note, l'url complète ne doit pas être fournie, la méthode se charge d'ajouter
1690
     * le chemin vers le répertoire js en fonction de la requête, c'est à dire que si
1691
     * on appelle un fichier de langue, la méthode ajoute l'url vers le répertoire de
1692
     * langue, dans le cas contraire on ajoute l'url vers le répertoire JS du module.
1693
     *
1694
     * @param string $javascriptFile
1695
     * @param bool   $inLanguageFolder
1696
     * @param bool   $oldWay
1697
     * @since 2.3.2009.03.14
1698
     */
1699
    public static function callJavascriptFile($javascriptFile, $inLanguageFolder = false, $oldWay = false)
0 ignored issues
show
Unused Code introduced by
The parameter $oldWay is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1700
    {
1701
        global $xoopsConfig, $xoTheme;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1702
        $fileToCall = $javascriptFile;
0 ignored issues
show
Unused Code introduced by
$fileToCall 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...
1703
        if ($inLanguageFolder) {
1704
            $root    = OLEDRION_PATH;
1705
            $rootUrl = OLEDRION_URL;
1706
            if (file_exists($root . 'language/' . $xoopsConfig['language'] . '/' . $javascriptFile)) {
1707
                $fileToCall = $rootUrl . 'language/' . $xoopsConfig['language'] . '/' . $javascriptFile;
1708
            } else { // Fallback
1709
                $fileToCall = $rootUrl . 'language/english/' . $javascriptFile;
1710
            }
1711
        } else {
1712
            $fileToCall = OLEDRION_JS_URL . $javascriptFile;
1713
        }
1714
1715
        $xoTheme->addScript('browse.php?Frameworks/jquery/jquery.js');
1716
        $xoTheme->addScript($fileToCall);
1717
    }
1718
1719
    /**
1720
     * Create the <option> of an html select
1721
     *
1722
     * @param  array $array   Array of index and labels
1723
     * @param  mixed $default the default value
1724
     * @param  bool  $withNull
1725
     * @return string
1726
     * @since 2.3.2009.03.13
1727
     */
1728
    public static function htmlSelectOptions($array, $default = 0, $withNull = true)
1729
    {
1730
        $ret      = array();
1731
        $selected = '';
1732
        if ($withNull) {
1733
            if ($default === 0) {
1734
                $selected = " selected = 'selected'";
1735
            }
1736
            $ret[] = '<option value=0' . $selected . '>---</option>';
1737
        }
1738
1739
        foreach ($array as $index => $label) {
1740
            $selected = '';
1741
            if ($index == $default) {
1742
                $selected = " selected = 'selected'";
1743
            }
1744
            $ret[] = "<option value=\"" . $index . "\"" . $selected . '>' . $label . '</option>';
1745
        }
1746
1747
        return implode("\n", $ret);
1748
    }
1749
1750
    /**
1751
     * Creates an html select
1752
     *
1753
     * @param  string  $selectName Selector's name
1754
     * @param  array   $array      Options
1755
     * @param  mixed   $default    Default's value
1756
     * @param  boolean $withNull   Do we include a null option ?
1757
     * @return string
1758
     * @since 2.3.2009.03.13
1759
     */
1760
    public static function htmlSelect($selectName, $array, $default, $withNull = true)
1761
    {
1762
        $ret = '';
1763
        $ret .= "<select name='" . $selectName . "' id='" . $selectName . "'>\n";
1764
        $ret .= static::htmlSelectOptions($array, $default, $withNull);
1765
        $ret .= "</select>\n";
1766
1767
        return $ret;
1768
    }
1769
1770
    /**
1771
     * Extrait l'id d'une chaine formatée sous la forme xxxx-99 (duquel on récupère 99)
1772
     *
1773
     * @note: utilisé par les attributs produits
1774
     * @param  string $string    La chaine de travail
1775
     * @param  string $separator Le séparateur
1776
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1777
     */
1778 View Code Duplication
    public function getId($string, $separator = '_')
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...
1779
    {
1780
        $pos = strrpos($string, $separator);
1781
        if ($pos === false) {
1782
            return $string;
1783
        } else {
1784
            return (int)substr($string, $pos + 1);
1785
        }
1786
    }
1787
1788
    /**
1789
     * Fonction "inverse" de getId (depuis xxxx-99 on récupère xxxx)
1790
     *
1791
     * @note: utilisé par les attributs produits
1792
     * @param  string $string    La chaine de travail
1793
     * @param  string $separator Le séparateur
1794
     * @return string
1795
     */
1796 View Code Duplication
    public function getName($string, $separator = '_')
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...
1797
    {
1798
        $pos = strrpos($string, $separator);
1799
        if ($pos === false) {
1800
            return $string;
1801
        } else {
1802
            return substr($string, 0, $pos);
1803
        }
1804
    }
1805
1806
    /**
1807
     * Renvoie un montant nul si le montant est négatif
1808
     *
1809
     * @param  float $amount
1810
     * @return float
0 ignored issues
show
Documentation introduced by
Should the return type not be double|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1811
     */
1812
    public static function doNotAcceptNegativeAmounts(&$amount)
1813
    {
1814
        if ($amount < 0) {
1815
            $amount = 0;
1816
        }
1817
    }
1818
1819
    /**
1820
     * Returns a string from the request
1821
     *
1822
     * @param  string $valueName    Name of the parameter you want to get
1823
     * @param  mixed  $defaultValue Default value to return if the parameter is not set in the request
1824
     * @return mixed
1825
     */
1826
    public function getFromRequest($valueName, $defaultValue = '')
0 ignored issues
show
Coding Style introduced by
getFromRequest uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
1827
    {
1828
        return isset($_REQUEST[$valueName]) ? $_REQUEST[$valueName] : $defaultValue;
1829
    }
1830
1831
    /**
1832
     * Verify that a mysql table exists
1833
     *
1834
     * @package       Oledrion
1835
     * @author        Instant Zero (http://xoops.instant-zero.com)
1836
     * @copyright (c) Instant Zero
1837
     * @param $tablename
1838
     * @return bool
1839
     */
1840
    public static function tableExists($tablename)
1841
    {
1842
        global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1843
        $result = $xoopsDB->queryF("SHOW TABLES LIKE '$tablename'");
1844
1845
        return ($xoopsDB->getRowsNum($result) > 0);
1846
    }
1847
1848
    /**
1849
     * Verify that a field exists inside a mysql table
1850
     *
1851
     * @package       Oledrion
1852
     * @author        Instant Zero (http://xoops.instant-zero.com)
1853
     * @copyright (c) Instant Zero
1854
     * @param $fieldname
1855
     * @param $table
1856
     * @return bool
1857
     */
1858
    public static function fieldExists($fieldname, $table)
1859
    {
1860
        global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1861
        $result = $xoopsDB->queryF("SHOW COLUMNS FROM $table LIKE '$fieldname'");
1862
1863
        return ($xoopsDB->getRowsNum($result) > 0);
1864
    }
1865
1866
    /**
1867
     * Retourne la définition d'un champ
1868
     *
1869
     * @param  string $fieldname
1870
     * @param  string $table
1871
     * @return array
1872
     */
1873
    public function getFieldDefinition($fieldname, $table)
1874
    {
1875
        global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1876
        $result = $xoopsDB->queryF("SHOW COLUMNS FROM $table LIKE '$fieldname'");
1877
        if ($result) {
1878
            return $xoopsDB->fetchArray($result);
1879
        }
1880
1881
        return '';
0 ignored issues
show
Bug Best Practice introduced by
The return type of return ''; (string) is incompatible with the return type documented by Oledrion_utils::getFieldDefinition of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1882
    }
1883
1884
    /**
1885
     * Add a field to a mysql table
1886
     *
1887
     * @package       Oledrion
1888
     * @author        Instant Zero (http://xoops.instant-zero.com)
1889
     * @copyright (c) Instant Zero
1890
     * @param $field
1891
     * @param $table
1892
     * @return
1893
     */
1894
    public static function addField($field, $table)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
1895
    {
1896
        global $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1897
        $result = $xoopsDB->queryF("ALTER TABLE $table ADD $field;");
1898
1899
        return $result;
1900
    }
1901
1902
    /**
1903
     * @param $info
1904
     * @return string
1905
     */
1906
    public function packingHtmlSelect($info)
1907
    {
1908
        $ret = '';
1909
        $ret .= '<div class="oledrion_htmlform">';
1910
        $ret .= '<img class="oledrion_htmlimage" src="' . $info['packing_image_url'] . '" alt="' . $info['packing_title'] . '" />';
1911
        $ret .= '<h3>' . $info['packing_title'] . '</h3>';
1912 View Code Duplication
        if ($info['packing_price'] > 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...
1913
            $ret .= '<p><span class="bold">' . _OLEDRION_PRICE . '</span> : ' . $info['packing_price_fordisplay'] . '</p>';
1914
        } else {
1915
            $ret .= '<p><span class="bold">' . _OLEDRION_PRICE . '</span> : ' . _OLEDRION_FREE . '</p>';
1916
        }
1917
        $ret .= '<p>' . $info['packing_description'] . '</p>';
1918
        $ret .= '</div>';
1919
1920
        return $ret;
1921
    }
1922
1923
    /**
1924
     * @param $info
1925
     * @return string
1926
     */
1927
    public function deliveryHtmlSelect($info)
1928
    {
1929
        $ret = '';
1930
        $ret .= '<div class="oledrion_htmlform">';
1931
        $ret .= '<img class="oledrion_htmlimage" src="' . $info['delivery_image_url'] . '" alt="' . $info['delivery_title'] . '" />';
1932
        $ret .= '<h3>' . $info['delivery_title'] . '</h3>';
1933 View Code Duplication
        if ($info['delivery_price'] > 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...
1934
            $ret .= '<p><span class="bold">' . _OLEDRION_PRICE . '</span> : ' . $info['delivery_price_fordisplay'] . '</p>';
1935
        } else {
1936
            $ret .= '<p><span class="bold">' . _OLEDRION_PRICE . '</span> : ' . _OLEDRION_FREE . '</p>';
1937
        }
1938
        $ret .= '<p><span class="bold">' . _OLEDRION_DELIVERY_TIME . '</span> : ' . $info['delivery_time'] . _OLEDRION_DELIVERY_DAY . '</p>';
1939
        $ret .= '<p>' . $info['delivery_description'] . '</p>';
1940
        $ret .= '</div>';
1941
1942
        return $ret;
1943
    }
1944
1945
    /**
1946
     * @param $info
1947
     * @return string
1948
     */
1949
    public function paymentHtmlSelect($info)
1950
    {
1951
        $ret = '';
1952
        $ret .= '<div class="oledrion_htmlform">';
1953
        $ret .= '<img class="oledrion_htmlimage" src="' . $info['payment_image_url'] . '" alt="' . $info['payment_title'] . '" />';
1954
        $ret .= '<h3>' . $info['payment_title'] . '</h3>';
1955
        $ret .= '<p>' . $info['payment_description'] . '</p>';
1956
        $ret .= '</div>';
1957
1958
        return $ret;
1959
    }
1960
1961
    /**
1962
     * @return array
1963
     */
1964
    public function getCountriesList()
1965
    {
1966
        require_once XOOPS_ROOT_PATH . '/class/xoopslists.php';
1967
1968
        return XoopsLists::getCountryList();
1969
    }
1970
}
1971