Dbupdater::renameTable()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
1
<?php namespace XoopsModules\Smartobject;
2
3
/*
4
 * You may not change or alter any portion of this comment or credits
5
 * of supporting developers from this source code or any supporting source code
6
 * which is considered copyrighted (c) material of the original comment or credit authors.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/**
14
 * @copyright    XOOPS Project https://xoops.org/
15
 * @license      GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
16
 * @link    http://www.smartfactory.ca The SmartFactory
17
 * @package SmartObject
18
 * @author  marcan <[email protected]>
19
 * @author     XOOPS Development Team
20
 */
21
22
use XoopsModules\Smartobject;
23
24
/**
25
 * Contains the classes for updating database tables
26
 *
27
 * @license GNU
28
29
 */
30
/**
31
 * SmartDbTable class
32
 *
33
 * Information about an individual table
34
 *
35
 * @package SmartObject
36
 * @author  marcan <[email protected]>
37
 * @link    http://www.smartfactory.ca The SmartFactory
38
 */
39
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
40
if (!defined('SMARTOBJECT_ROOT_PATH')) {
41
    require_once XOOPS_ROOT_PATH . '/modules/smartobject/include/common.php';
42
}
43
/**
44
 * Include the language constants for the SmartObjectDBUpdater
45
 */
46
global $xoopsConfig;
47
$common_file = SMARTOBJECT_ROOT_PATH . 'language/' . $xoopsConfig['language'] . '/smartdbupdater.php';
48
if (!file_exists($common_file)) {
49
    $common_file = SMARTOBJECT_ROOT_PATH . 'language/english/smartdbupdater.php';
50
}
51
include $common_file;
52
53
54
/**
55
 * SmartobjectDbupdater class
56
 *
57
 * Class performing the database update for the module
58
 *
59
 * @package SmartObject
60
 * @author  marcan <[email protected]>
61
 * @link    http://www.smartfactory.ca The SmartFactory
62
 */
63
class Dbupdater
64
{
65
    public $_dbTypesArray;
66
67
    /**
68
     * SmartobjectDbupdater constructor.
69
     */
70
    public function __construct()
71
    {
72
        $this->_dbTypesArray[XOBJ_DTYPE_TXTBOX]       = 'varchar(255)';
73
        $this->_dbTypesArray[XOBJ_DTYPE_TXTAREA]      = 'text';
74
        $this->_dbTypesArray[XOBJ_DTYPE_INT]          = 'int(11)';
75
        $this->_dbTypesArray[XOBJ_DTYPE_URL]          = 'varchar(255)';
76
        $this->_dbTypesArray[XOBJ_DTYPE_EMAIL]        = 'varchar(255)';
77
        $this->_dbTypesArray[XOBJ_DTYPE_ARRAY]        = 'text';
78
        $this->_dbTypesArray[XOBJ_DTYPE_OTHER]        = 'text';
79
        $this->_dbTypesArray[XOBJ_DTYPE_SOURCE]       = 'text';
80
        $this->_dbTypesArray[XOBJ_DTYPE_STIME]        = 'int(11)';
81
        $this->_dbTypesArray[XOBJ_DTYPE_MTIME]        = 'int(11)';
82
        $this->_dbTypesArray[XOBJ_DTYPE_LTIME]        = 'int(11)';
83
        $this->_dbTypesArray[XOBJ_DTYPE_SIMPLE_ARRAY] = 'text';
84
        $this->_dbTypesArray[XOBJ_DTYPE_CURRENCY]     = 'text';
85
        $this->_dbTypesArray[XOBJ_DTYPE_FLOAT]        = 'float';
86
        $this->_dbTypesArray[XOBJ_DTYPE_TIME_ONLY]    = 'int(11)';
87
        $this->_dbTypesArray[XOBJ_DTYPE_URLLINK]      = 'int(11)';
88
        $this->_dbTypesArray[XOBJ_DTYPE_FILE]         = 'int(11)';
89
        $this->_dbTypesArray[XOBJ_DTYPE_IMAGE]        = 'varchar(255)';
90
    }
91
92
    /**
93
     * Use to execute a general query
94
     *
95
     * @param string $query   query that will be executed
96
     * @param string $goodmsg message displayed on success
97
     * @param string $badmsg  message displayed on error
98
     *
99
     * @return bool true if success, false if an error occured
100
     *
101
     */
102
    public function runQuery($query, $goodmsg, $badmsg)
103
    {
104
        global $xoopsDB;
105
        $ret = $xoopsDB->query($query);
106
        if (!$ret) {
107
            echo "&nbsp;&nbsp;$badmsg<br>";
108
109
            return false;
110
        } else {
111
            echo "&nbsp;&nbsp;$goodmsg<br>";
112
113
            return true;
114
        }
115
    }
116
117
    /**
118
     * Use to rename a table
119
     *
120
     * @param string $from name of the table to rename
121
     * @param string $to   new name of the renamed table
122
     *
123
     * @return bool true if success, false if an error occured
124
     */
125
    public function renameTable($from, $to)
126
    {
127
        global $xoopsDB;
128
        $from  = $xoopsDB->prefix($from);
129
        $to    = $xoopsDB->prefix($to);
130
        $query = sprintf('ALTER TABLE %s RENAME %s', $from, $to);
131
        $ret   = $xoopsDB->query($query);
132
        if (!$ret) {
133
            echo '&nbsp;&nbsp;' . sprintf(_SDU_MSG_RENAME_TABLE_ERR, $from) . '<br>';
134
135
            return false;
136
        } else {
137
            echo '&nbsp;&nbsp;' . sprintf(_SDU_MSG_RENAME_TABLE, $from, $to) . '<br>';
138
139
            return true;
140
        }
141
    }
142
143
    /**
144
     * Use to update a table
145
     *
146
     * @param object $table {@link SmartDbTable} that will be updated
147
     *
148
     * @see DbTable
149
     *
150
     * @return bool true if success, false if an error occured
151
     */
152
    public function updateTable($table)
153
    {
154
        global $xoopsDB;
155
        $ret = true;
156
        // If table has a structure, create the table
157
        if ($table->getStructure()) {
158
            $ret = $table->createTable() && $ret;
159
        }
160
        // If table is flag for drop, drop it
161
        if ($table->_flagForDrop) {
162
            $ret = $table->dropTable() && $ret;
163
        }
164
        // If table has data, insert it
165
        if ($table->getData()) {
166
            $ret = $table->addData() && $ret;
167
        }
168
        // If table has new fields to be added, add them
169
        if ($table->getNewFields()) {
170
            $ret = $table->addNewFields() && $ret;
171
        }
172
        // If table has altered field, alter the table
173
        if ($table->getAlteredFields()) {
174
            $ret = $table->alterTable() && $ret;
175
        }
176
        // If table has updated field values, update the table
177
        if ($table->getUpdatedFields()) {
178
            $ret = $table->updateFieldsValues($table) && $ret;
179
        }
180
        // If table has dropped field, alter the table
181
        if ($table->getDroppedFields()) {
182
            $ret = $table->dropFields($table) && $ret;
183
        }
184
        //felix
185
        // If table has updated field values, update the table
186
        if ($table->getUpdatedWhere()) {
187
            $ret = $table->UpdateWhereValues($table) && $ret;
188
        }
189
190
        return $ret;
191
    }
192
193
    /**
194
     * @param $module
195
     * @param $item
196
     */
197
    public function automaticUpgrade($module, $item)
198
    {
199
        if (is_array($item)) {
200
            foreach ($item as $v) {
201
                $this->upgradeObjectItem($module, $v);
202
            }
203
        } else {
204
            $this->upgradeObjectItem($module, $item);
205
        }
206
    }
207
208
    /**
209
     * @param $var
210
     * @return string
211
     */
212
    public function getFieldTypeFromVar($var)
213
    {
214
        $ret = isset($this->_dbTypesArray[$var['data_type']]) ? $this->_dbTypesArray[$var['data_type']] : 'text';
215
216
        return $ret;
217
    }
218
219
    /**
220
     * @param         $var
221
     * @param  bool   $key
222
     * @return string
223
     */
224
    public function getFieldDefaultFromVar($var, $key = false)
0 ignored issues
show
Unused Code introduced by
The parameter $key 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...
225
    {
226
        if ($var['value']) {
227
            return $var['value'];
228
        } else {
229
            if (in_array($var['data_type'], [
230
                XOBJ_DTYPE_INT,
231
                XOBJ_DTYPE_STIME,
232
                XOBJ_DTYPE_MTIME,
233
                XOBJ_DTYPE_LTIME,
234
                XOBJ_DTYPE_TIME_ONLY,
235
                XOBJ_DTYPE_URLLINK,
236
                XOBJ_DTYPE_FILE
237
            ])) {
238
                return '0';
239
            } else {
240
                return '';
241
            }
242
        }
243
    }
244
245
    /**
246
     * @param $module
247
     * @param $item
248
     * @return bool
249
     */
250
    public function upgradeObjectItem($module, $item)
251
    {
252
        $moduleHandler = xoops_getModuleHandler($item, $module);
253
        if (!$moduleHandler) {
254
            return false;
255
        }
256
257
        $table      = new DbTable($module . '_' . $item);
258
        $object     = $moduleHandler->create();
259
        $objectVars = $object->getVars();
260
261
        if (!$table->exists()) {
262
            // table was never created, let's do it
263
            $structure = '';
264
            foreach ($objectVars as $key => $var) {
265
                if ($var['persistent']) {
266
                    $type = $this->getFieldTypeFromVar($var);
267 View Code Duplication
                    if ($key == $moduleHandler->keyName) {
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...
268
                        $extra = 'auto_increment';
269
                    } else {
270
                        $default = $this->getFieldDefaultFromVar($var);
271
                        $extra   = "default '$default'
272
";
273
                    }
274
                    $structure .= "`$key` $type not null $extra,
275
";
276
                }
277
            }
278
            $structure .= 'PRIMARY KEY  (`' . $moduleHandler->keyName . '`)
279
';
280
            $table->setStructure($structure);
281
            if (!$this->updateTable($table)) {
282
                /**
283
                 * @todo trap the errors
284
                 */
285
            }
286
        } else {
287
            $existingFieldsArray = $table->getExistingFieldsArray();
288
            foreach ($objectVars as $key => $var) {
289
                if ($var['persistent']) {
290
                    if (!isset($existingFieldsArray[$key])) {
291
                        // the fiels does not exist, let's create it
292
                        $type    = $this->getFieldTypeFromVar($var);
293
                        $default = $this->getFieldDefaultFromVar($var);
294
                        $table->addNewField($key, "$type not null default '$default'");
295
                    } else {
296
                        // if field already exists, let's check if the definition is correct
297
                        $definition = strtolower($existingFieldsArray[$key]);
298
                        $type       = $this->getFieldTypeFromVar($var);
299 View Code Duplication
                        if ($key == $moduleHandler->keyName) {
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...
300
                            $extra = 'auto_increment';
301
                        } else {
302
                            $default = $this->getFieldDefaultFromVar($var, $key);
0 ignored issues
show
Documentation introduced by
$key is of type integer|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
303
                            $extra   = "default '$default'";
304
                        }
305
                        $actual_definition = "$type not null $extra";
306
                        if ($definition != $actual_definition) {
307
                            $table->addAlteredField($key, $actual_definition);
308
                        }
309
                    }
310
                }
311
            }
312
313
            // check to see if there are some unused fields left in the table
314
            foreach ($existingFieldsArray as $key => $v) {
315
                if (!isset($objectVars[$key]) || !$objectVars[$key]['persistent']) {
316
                    $table->addDroppedField($key);
317
                }
318
            }
319
320
            if (!$this->updateTable($table)) {
321
                /**
322
                 * @todo trap the errors
323
                 */
324
            }
325
        }
326
    }
327
328
    /**
329
     * @param $module
330
     * @return bool
331
     */
332
    public function moduleUpgrade(\XoopsModule $module)
333
    {
334
        $dirname = $module->getVar('dirname');
335
336
        ob_start();
337
338
        $table = new DbTable($dirname . '_meta');
339
        if (!$table->exists()) {
340
            $table->setStructure("
341
              `metakey` varchar(50) NOT NULL default '',
342
              `metavalue` varchar(255) NOT NULL default '',
343
              PRIMARY KEY (`metakey`)");
344
            $table->setData("'version',0");
345
            if (!$this->updateTable($table)) {
346
                /**
347
                 * @todo trap the errors
348
                 */
349
            }
350
        }
351
352
        $dbVersion = Smartobject\Utility::getMeta('version', $dirname);
353
        if (!$dbVersion) {
354
            $dbVersion = 0;
355
        }
356
        $newDbVersion = constant(strtoupper($dirname . '_db_version')) ?: 0;
357
        echo 'Database version: ' . $dbVersion . '<br>';
358
        echo 'New database version: ' . $newDbVersion . '<br>';
359
360
        if ($newDbVersion > $dbVersion) {
361
            for ($i = $dbVersion + 1; $i <= $newDbVersion; ++$i) {
362
                $upgrade_function = $dirname . '_db_upgrade_' . $i;
363
                if (function_exists($upgrade_function)) {
364
                    $upgrade_function();
365
                }
366
            }
367
        }
368
369
        echo '<code>' . _SDU_UPDATE_UPDATING_DATABASE . '<br>';
370
371
        // if there is a function to execute for this DB version, let's do it
372
        //$function_
373
374
        $module_info = Smartobject\Utility::getModuleInfo($dirname);
375
        $this->automaticUpgrade($dirname, $module_info->modinfo['object_items']);
376
377
        echo '</code>';
378
379
        $feedback = ob_get_clean();
380
        if (method_exists($module, 'setMessage')) {
381
            $module->setMessage($feedback);
382
        } else {
383
            echo $feedback;
384
        }
385
        Smartobject\Utility::setMeta('version', $newDbVersion, $dirname); //Set meta version to current
386
387
        return true;
388
    }
389
}
390