Passed
Push — master ( 164e41...836fbe )
by Michael
05:36 queued 01:25
created

Upgrade_2511::copyFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 10
rs 10
1
<?php
2
3
use Xmf\Database\Tables;
4
5
/**
6
 * Upgrade from 2.5.10 to 2.5.11
7
 *
8
 * @copyright    (c) 2000-2021 XOOPS Project (https://xoops.org)
9
 * @license          GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
10
 * @package          Upgrade
11
 * @since            2.5.11
12
 * @author           XOOPS Team
13
 */
14
class Upgrade_2511 extends XoopsUpgrade
15
{
16
    /**
17
     * __construct
18
     */
19
    public function __construct()
20
    {
21
        parent::__construct(basename(__DIR__));
22
        $this->tasks = array(
23
            'bannerintsize',
24
            'captchadata',
25
            'qmail',
26
            'textsanitizer',
27
            'xoopsconfig',
28
        );
29
        $this->usedFiles = array();
30
    }
31
32
33
    /**
34
     * Determine if columns are declared mediumint, and if
35
     * so, queue ddl to alter to int.
36
     *
37
     * @param $migrate           \Xmf\Database\Tables
38
     * @param $bannerTableName   string
39
     * @param $bannerColumnNames string[] array of columns to check
40
     *
41
     * @return integer count of queue items added
42
     */
43
    protected function fromMediumToInt(Tables $migrate, $bannerTableName, $bannerColumnNames)
44
    {
45
        $migrate->useTable($bannerTableName);
46
        $count = 0;
47
        foreach ($bannerColumnNames as $column) {
48
            $attributes = $migrate->getColumnAttributes($bannerTableName, $column);
49
            if (0 === strpos(trim($attributes), 'mediumint')) {
0 ignored issues
show
Bug introduced by
It seems like $attributes can also be of type boolean; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
            if (0 === strpos(trim(/** @scrutinizer ignore-type */ $attributes), 'mediumint')) {
Loading history...
50
                $count++;
51
                $migrate->alterColumn($bannerTableName, $column, 'int(10) UNSIGNED NOT NULL DEFAULT \'0\'');
52
            }
53
        }
54
        return $count;
55
    }
56
57
    private $bannerTableName = 'banner';
58
    private $bannerColumnNames = array('impmade', 'clicks');
59
60
    /**
61
     * Increase count columns from mediumint to int
62
     *
63
     * @return bool true if patch IS applied, false if NOT applied
64
     */
65
    public function check_bannerintsize()
66
    {
67
        $migrate = new Tables();
68
        $count = $this->fromMediumToInt($migrate, $this->bannerTableName, $this->bannerColumnNames);
69
70
        return $count==0;
71
    }
72
73
    /**
74
     * Increase count columns from mediumint to int (Think BIG!)
75
     *
76
     * @return bool true if applied, false if failed
77
     */
78
    public function apply_bannerintsize()
79
    {
80
        $migrate = new \Xmf\Database\Tables();
81
82
        $count = $this->fromMediumToInt($migrate, $this->bannerTableName, $this->bannerColumnNames);
83
84
        $result = $migrate->executeQueue(true);
85
        if (false === $result) {
86
            $this->logs[] = sprintf('Migration of %s table failed. Error: %s - %s' .
87
                $this->bannerTableName,
88
                $migrate->getLastErrNo(),
89
                $migrate->getLastError()
90
            );
91
            return false;
92
        }
93
94
        return $count!==0;
95
    }
96
97
    /**
98
     * Add qmail as valid mailmethod
99
     *
100
     * @return bool
101
     */
102
    public function check_qmail()
103
    {
104
        /* @var XoopsMySQLDatabase $db */
105
        $db = XoopsDatabaseFactory::getDatabaseConnection();
106
107
        $table = $db->prefix('configoption');
108
109
        $sql = sprintf(
110
            'SELECT count(*) FROM `%s` '
111
            . "WHERE `conf_id` = 64 AND `confop_name` = 'qmail'",
112
            $db->escape($table)
113
        );
114
115
        /** @var mysqli_result $result */
116
        $result = $db->query($sql);
117
        if ($result) {
0 ignored issues
show
introduced by
$result is of type mysqli_result, thus it always evaluated to true.
Loading history...
118
            $row = $db->fetchRow($result);
119
            if ($row) {
120
                $count = $row[0];
121
                return (0 === (int) $count) ? false : true;
122
            }
123
        }
124
        return false;
125
    }
126
127
    /**
128
     * Add qmail as valid mailmethod
129
     *
130
     * phpMailer has qmail support, similar to but slightly different than sendmail
131
     * This will allow webmasters to utilize qmail if it is provisioned on server.
132
     *
133
     * @return bool
134
     */
135
    public function apply_qmail()
136
    {
137
        $migrate = new Tables();
138
        $migrate->useTable('configoption');
139
        $migrate->insert(
140
            'configoption',
141
            array('confop_name' => 'qmail', 'confop_value' => 'qmail', 'conf_id' => 64)
142
        );
143
        return $migrate->executeQueue(true);
144
    }
145
146
    /**
147
     * Do we need to move captcha writable data?
148
     *
149
     * @return bool
150
     */
151
    public function check_captchadata()
152
    {
153
        $captchaConfigFile = XOOPS_VAR_PATH . '/configs/captcha/config.php';
154
        return file_exists($captchaConfigFile);
155
    }
156
157
    /**
158
     * Attempt to make the supplied path
159
     * @param $newPath string
160
     *
161
     * @return bool
162
     */
163
    private function makeDirectory($newPath)
164
    {
165
        if (!mkdir($newPath) && !is_dir($newPath)) {
166
            $this->logs[] = sprintf('Captcha config directory %s was not created', $newPath);
167
            return false;
168
        }
169
        return true;
170
    }
171
172
    /**
173
     * Copy file $source to $destination
174
     *
175
     * @param $source      string
176
     * @param $destination string
177
     *
178
     * @return bool true if successful, false on error
179
     */
180
    private function copyFile($source, $destination)
181
    {
182
        if (!file_exists($destination)) { // don't overwrite anything
183
            $result = copy($source, $destination);
184
            if (false === $result) {
185
                $this->logs[] = sprintf('Captcha config file copy %s failed', basename($source));
186
                return false;
187
            }
188
        }
189
        return true;
190
    }
191
192
    /**
193
     * Move captcha configs to xoops_data to segregate writable data
194
     *
195
     * @return bool
196
     */
197
    public function apply_captchadata()
198
    {
199
        $returnResult = false;
200
        $sourcePath = XOOPS_ROOT_PATH . '/class/captcha/';
201
        $destinationPath = XOOPS_VAR_PATH . '/configs/captcha/';
202
203
        if (!file_exists($destinationPath)) {
204
            $this->makeDirectory($destinationPath);
205
        }
206
        $directory = dir($sourcePath);
207
        if (false === $directory) {
208
            $this->logs[] = sprintf('Failed to read source %s', $sourcePath);
209
            return false;
210
        }
211
        while (false !== ($entry = $directory->read())) {
212
            if (false === strpos($entry, '.dist.')
213
                && strpos($entry, 'config.') === 0 && '.php' === substr($entry, -4)) {
214
                $src = $sourcePath . $entry;
215
                $dest = $destinationPath . $entry;
216
                $status = $this->copyFile($src, $dest);
217
                if (false === $status) {
218
                    $returnResult = false;
219
                }
220
            }
221
        }
222
        $directory->close();
223
224
        return $returnResult;
225
    }
226
227
    /**
228
     * Do we need to create a xoops_data/configs/xoopsconfig.php?
229
     *
230
     * @return bool true if patch IS applied, false if NOT applied
231
     */
232
    public function check_xoopsconfig()
233
    {
234
        $xoopsConfigFile = XOOPS_VAR_PATH . '/configs/xoopsconfig.php';
235
        return file_exists($xoopsConfigFile);
236
    }
237
238
    /**
239
     * Create xoops_data/configs/xoopsconfig.php from xoopsconfig.dist.php
240
     *
241
     * @return bool true if applied, false if failed
242
     */
243
    public function apply_xoopsconfig()
244
    {
245
        $source = XOOPS_VAR_PATH . '/configs/xoopsconfig.dist.php';
246
        $destination = XOOPS_VAR_PATH . '/configs/xoopsconfig.php';
247
        if (!file_exists($destination)) { // don't overwrite anything
248
            $result = copy($source, $destination);
249
            if (false === $result) {
250
                $this->logs[] = 'xoopsconfig.php file copy failed';
251
                return false;
252
            }
253
        }
254
        return true;
255
    }
256
257
    /**
258
     * This is a default list based on extensions as supplied by XOOPS.
259
     * If possible, we will build a list based on contents of class/textsanitizer/
260
     * key is file path relative to XOOPS_ROOT_PATH . '/class/textsanitizer/
261
     * value is file path relative to XOOPS_VAR_PATH . '/configs/textsanitizer/'
262
     *
263
     * @var string[]
264
     */
265
    protected $textsanitizerConfigFiles = array(
266
        'config.php' => 'config.php',
267
        'censor/config.php' => 'config.censor.php',
268
        'flash/config.php' => 'config.flash.php',
269
        'image/config.php' => 'config.image.php',
270
        'mms/config.php' => 'config.mms.php',
271
        'rtsp/config.php' => 'config.rtsp.php',
272
        'syntaxhighlight/config.php' => 'config.syntaxhighlight.php',
273
        'textfilter/config.php' => 'config.textfilter.php',
274
        'wiki/config.php' => 'config.wiki.php',
275
        'wmp/config.php' => 'config.wmp.php',
276
    );
277
278
    /**
279
     * Build a list of config files using the existing textsanitizer/config.php
280
     * This should prevent some issues with customized systems.
281
     *
282
     * @return string[] array of existing ts and extension config files
283
     *                  each as source name => destination name
284
     */
285
    protected function buildListTSConfigs()
286
    {
287
        if (file_exists(XOOPS_ROOT_PATH . '/class/textsanitizer/config.php')) {
288
            $config = include XOOPS_ROOT_PATH . '/class/textsanitizer/config.php';
289
            if (is_array($config) && array_key_exists('extentions')) {
0 ignored issues
show
Bug introduced by
The call to array_key_exists() has too few arguments starting with array. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

289
            if (is_array($config) && /** @scrutinizer ignore-call */ array_key_exists('extentions')) {

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
290
                $this->textsanitizerConfigFiles = array(
291
                    'config.php' => 'config.php',
292
                );
293
                foreach ($config['extentions'] as $module => $enabled) {
294
                    $source = "{$module}/config.php";
295
                    if (file_exists(XOOPS_ROOT_PATH . '/class/textsanitizer/' . $source)) {
296
                        $destination = "{$module}/config.{$module}.php";
297
                        $this->textsanitizerConfigFiles[$source] = $destination;
298
                    }
299
                }
300
            }
301
        }
302
        return;
303
    }
304
305
    /**
306
     * Do we need to move any existing files to xoops_data/configs/textsanitizer/ ?
307
     *
308
     * @return bool true if patch IS applied, false if NOT applied
309
     */
310
    public function check_textsanitizer()
311
    {
312
        $this->buildListTSConfigs();
313
        foreach ($this->textsanitizerConfigFiles as $source => $destination) {
314
            $src  = XOOPS_ROOT_PATH . '/class/textsanitizer/' . $source;
315
            $dest = XOOPS_VAR_PATH . '/configs/textsanitizer/' . $destination;
316
            if (!file_exists($dest) && file_exists($src)) {
317
                return false;
318
            }
319
        }
320
        return true;
321
    }
322
323
    /**
324
     * Copy and rename any existing class/textsanitizer/ config files to xoops_data/configs/textsanitizer/
325
     *
326
     * @return bool true if applied, false if failed
327
     */
328
    public function apply_textsanitizer()
329
    {
330
        $this->buildListTSConfigs();
331
        $return = true;
332
        foreach ($this->textsanitizerConfigFiles as $source => $destination) {
333
            $src  = XOOPS_ROOT_PATH . '/class/textsanitizer/' . $source;
334
            $dest = XOOPS_VAR_PATH . '/configs/textsanitizer/' . $destination;
335
            if (!file_exists($dest) && file_exists($src)) {
336
                $result = copy($src, $dest);
337
                if (false === $result) {
338
                    $this->logs[] = sprintf('textsanitizer file copy to %s failed', $destination);
339
                    $return = false;
340
                }
341
            }
342
        }
343
        return $return;
344
    }
345
}
346
347
return new Upgrade_2511();
348