Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * This class represent one XMLDB Key
19
 *
20
 * @package    core_xmldb
21
 * @copyright  1999 onwards Martin Dougiamas     http://dougiamas.com
22
 *             2001-3001 Eloy Lafuente (stronk7) http://contiento.com
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
 
29
class xmldb_key extends xmldb_object {
30
 
31
    /** @var int type of key */
32
    protected $type;
33
 
34
    /** @var array of fields */
35
    protected $fields;
36
 
37
    /** @var string referenced table */
38
    protected $reftable;
39
 
40
    /** @var array referenced fields */
41
    protected $reffields;
42
 
43
    /**
44
     * Creates one new xmldb_key
45
     * @param string $name
46
     * @param string $type XMLDB_KEY_[PRIMARY|UNIQUE|FOREIGN|FOREIGN_UNIQUE]
47
     * @param array $fields an array of fieldnames to build the key over
48
     * @param string $reftable name of the table the FK points to or null
49
     * @param array $reffields an array of fieldnames in the FK table or null
50
     */
51
    public function __construct($name, $type=null, $fields=array(), $reftable=null, $reffields=null) {
52
        $this->type = null;
53
        $this->fields = array();
54
        $this->reftable = null;
55
        $this->reffields = array();
56
        parent::__construct($name);
57
        $this->set_attributes($type, $fields, $reftable, $reffields);
58
    }
59
 
60
    /**
61
     * Set all the attributes of one xmldb_key
62
     *
63
     * @param string $type XMLDB_KEY_[PRIMARY|UNIQUE|FOREIGN|FOREIGN_UNIQUE]
64
     * @param array $fields an array of fieldnames to build the key over
65
     * @param string $reftable name of the table the FK points to or null
66
     * @param array $reffields an array of fieldnames in the FK table or null
67
     */
68
    public function set_attributes($type, $fields, $reftable=null, $reffields=null) {
69
        $this->type = $type;
70
        $this->fields = $fields;
71
        $this->reftable = $reftable;
72
        $this->reffields = empty($reffields) ? array() : $reffields;
73
    }
74
 
75
    /**
76
     * Get the key type
77
     * @return int
78
     */
79
    public function getType() {
80
        return $this->type;
81
    }
82
 
83
    /**
84
     * Set the key type
85
     * @param int $type
86
     */
87
    public function setType($type) {
88
        $this->type = $type;
89
    }
90
 
91
    /**
92
     * Set the key fields
93
     * @param array $fields
94
     */
95
    public function setFields($fields) {
96
        $this->fields = $fields;
97
    }
98
 
99
    /**
100
     * Set the key reftable
101
     * @param string $reftable
102
     */
103
    public function setRefTable($reftable) {
104
        $this->reftable = $reftable;
105
    }
106
 
107
    /**
108
     * Set the key reffields
109
     * @param array $reffields
110
     */
111
    public function setRefFields($reffields) {
112
        $this->reffields = $reffields;
113
    }
114
 
115
    /**
116
     * Get the key fields
117
     * @return array
118
     */
119
    public function getFields() {
120
        return $this->fields;
121
    }
122
 
123
    /**
124
     * Get the key reftable
125
     * @return string
126
     */
127
    public function getRefTable() {
128
        return $this->reftable;
129
    }
130
 
131
    /**
132
     * Get the key reffields
133
     * @return array reference to ref fields
134
     */
135
    public function getRefFields() {
136
        return $this->reffields;
137
    }
138
 
139
    /**
140
     * Load data from XML to the key
141
     * @param array $xmlarr
142
     * @return bool success
143
     */
144
    public function arr2xmldb_key($xmlarr) {
145
 
146
        $result = true;
147
 
148
        // Debug the table
149
        // traverse_xmlize($xmlarr);                   //Debug
150
        // print_object ($GLOBALS['traverse_array']);  //Debug
151
        // $GLOBALS['traverse_array']="";              //Debug
152
 
153
        // Process key attributes (name, type, fields, reftable,
154
        // reffields, comment, previous, next)
155
        if (isset($xmlarr['@']['NAME'])) {
156
            $this->name = trim($xmlarr['@']['NAME']);
157
        } else {
158
            $this->errormsg = 'Missing NAME attribute';
159
            $this->debug($this->errormsg);
160
            $result = false;
161
        }
162
 
163
        if (isset($xmlarr['@']['TYPE'])) {
164
            // Check for valid type
165
            $type = $this->getXMLDBKeyType(trim($xmlarr['@']['TYPE']));
166
            if ($type) {
167
                $this->type = $type;
168
            } else {
169
                $this->errormsg = 'Invalid TYPE attribute';
170
                $this->debug($this->errormsg);
171
                $result = false;
172
            }
173
        } else {
174
            $this->errormsg = 'Missing TYPE attribute';
175
            $this->debug($this->errormsg);
176
            $result = false;
177
        }
178
 
179
        if (isset($xmlarr['@']['FIELDS'])) {
180
            $fields = strtolower(trim($xmlarr['@']['FIELDS']));
181
            if ($fields) {
182
                $fieldsarr = explode(',',$fields);
183
                if ($fieldsarr) {
184
                    foreach ($fieldsarr as $key => $element) {
185
                        $fieldsarr [$key] = trim($element);
186
                    }
187
                } else {
188
                    $this->errormsg = 'Incorrect FIELDS attribute (comma separated of fields)';
189
                    $this->debug($this->errormsg);
190
                    $result = false;
191
                }
192
            } else {
193
                $this->errormsg = 'Empty FIELDS attribute';
194
                $this->debug($this->errormsg);
195
                $result = false;
196
            }
197
        } else {
198
            $this->errormsg = 'Missing FIELDS attribute';
199
            $this->debug($this->errormsg);
200
            $result = false;
201
        }
202
        // Finally, set the array of fields
203
        $this->fields = $fieldsarr;
204
 
205
        if (isset($xmlarr['@']['REFTABLE'])) {
206
            // Check we are in a FK
207
            if ($this->type == XMLDB_KEY_FOREIGN ||
208
                $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
209
                $reftable = strtolower(trim($xmlarr['@']['REFTABLE']));
210
                if (!$reftable) {
211
                    $this->errormsg = 'Empty REFTABLE attribute';
212
                    $this->debug($this->errormsg);
213
                    $result = false;
214
                }
215
            } else {
216
                $this->errormsg = 'Wrong REFTABLE attribute (only FK can have it)';
217
                $this->debug($this->errormsg);
218
                $result = false;
219
            }
220
        } else if ($this->type == XMLDB_KEY_FOREIGN ||
221
                   $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
222
            $this->errormsg = 'Missing REFTABLE attribute';
223
            $this->debug($this->errormsg);
224
            $result = false;
225
        }
226
        // Finally, set the reftable
227
        if ($this->type == XMLDB_KEY_FOREIGN ||
228
            $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
229
            $this->reftable = $reftable;
230
        }
231
 
232
        if (isset($xmlarr['@']['REFFIELDS'])) {
233
            // Check we are in a FK
234
            if ($this->type == XMLDB_KEY_FOREIGN ||
235
                $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
236
                $reffields = strtolower(trim($xmlarr['@']['REFFIELDS']));
237
                if ($reffields) {
238
                    $reffieldsarr = explode(',',$reffields);
239
                    if ($reffieldsarr) {
240
                        foreach ($reffieldsarr as $key => $element) {
241
                            $reffieldsarr [$key] = trim($element);
242
                        }
243
                    } else {
244
                        $this->errormsg = 'Incorrect REFFIELDS attribute (comma separated of fields)';
245
                        $this->debug($this->errormsg);
246
                        $result = false;
247
                    }
248
                } else {
249
                    $this->errormsg = 'Empty REFFIELDS attribute';
250
                    $this->debug($this->errormsg);
251
                    $result = false;
252
                }
253
            } else {
254
                $this->errormsg = 'Wrong REFFIELDS attribute (only FK can have it)';
255
                $this->debug($this->errormsg);
256
                $result = false;
257
            }
258
        } else if ($this->type == XMLDB_KEY_FOREIGN ||
259
                   $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
260
            $this->errormsg = 'Missing REFFIELDS attribute';
261
            $this->debug($this->errormsg);
262
            $result = false;
263
        }
264
        // Finally, set the array of reffields
265
        if ($this->type == XMLDB_KEY_FOREIGN ||
266
            $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
267
            $this->reffields = $reffieldsarr;
268
        }
269
 
270
        if (isset($xmlarr['@']['COMMENT'])) {
271
            $this->comment = trim($xmlarr['@']['COMMENT']);
272
        }
273
 
274
        // Set some attributes
275
        if ($result) {
276
            $this->loaded = true;
277
        }
278
        $this->calculateHash();
279
        return $result;
280
    }
281
 
282
    /**
283
     * This function returns the correct XMLDB_KEY_XXX value for the
284
     * string passed as argument
285
     * @param string $type
286
     * @return int
287
     */
288
    public function getXMLDBKeyType($type) {
289
 
290
        $result = XMLDB_KEY_INCORRECT;
291
 
292
        switch (strtolower($type)) {
293
            case 'primary':
294
                $result = XMLDB_KEY_PRIMARY;
295
                break;
296
            case 'unique':
297
                $result = XMLDB_KEY_UNIQUE;
298
                break;
299
            case 'foreign':
300
                $result = XMLDB_KEY_FOREIGN;
301
                break;
302
            case 'foreign-unique':
303
                $result = XMLDB_KEY_FOREIGN_UNIQUE;
304
                break;
305
            // case 'check':  //Not supported
306
            //     $result = XMLDB_KEY_CHECK;
307
            //     break;
308
        }
309
        // Return the normalized XMLDB_KEY
310
        return $result;
311
    }
312
 
313
    /**
314
     * This function returns the correct name value for the
315
     * XMLDB_KEY_XXX passed as argument
316
     * @param int $type
317
     * @return string
318
     */
319
    public function getXMLDBKeyName($type) {
320
 
321
        $result = '';
322
 
323
        switch ($type) {
324
            case XMLDB_KEY_PRIMARY:
325
                $result = 'primary';
326
                break;
327
            case XMLDB_KEY_UNIQUE:
328
                $result = 'unique';
329
                break;
330
            case XMLDB_KEY_FOREIGN:
331
                $result = 'foreign';
332
                break;
333
            case XMLDB_KEY_FOREIGN_UNIQUE:
334
                $result = 'foreign-unique';
335
                break;
336
            // case XMLDB_KEY_CHECK:  //Not supported
337
            //     $result = 'check';
338
            //     break;
339
        }
340
        // Return the normalized name
341
        return $result;
342
    }
343
 
344
    /**
345
     * This function calculate and set the hash of one xmldb_key
346
     * @param bool $recursive
347
     */
348
     public function calculateHash($recursive = false) {
349
        if (!$this->loaded) {
350
            $this->hash = null;
351
        } else {
352
            $key = $this->type . implode(', ', $this->fields);
353
            if ($this->type == XMLDB_KEY_FOREIGN ||
354
                $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
355
                $key .= $this->reftable . implode(', ', $this->reffields);
356
            }
357
                    ;
358
            $this->hash = md5($key);
359
        }
360
    }
361
 
362
    /**
363
     *This function will output the XML text for one key
364
     * @return string
365
     */
366
    public function xmlOutput() {
367
        $o = '';
368
        $o.= '        <KEY NAME="' . $this->name . '"';
369
        $o.= ' TYPE="' . $this->getXMLDBKeyName($this->type) . '"';
370
        $o.= ' FIELDS="' . implode(', ', $this->fields) . '"';
371
        if ($this->type == XMLDB_KEY_FOREIGN ||
372
            $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
373
            $o.= ' REFTABLE="' . $this->reftable . '"';
374
            $o.= ' REFFIELDS="' . implode(', ', $this->reffields) . '"';
375
        }
376
        if ($this->comment) {
377
            $o.= ' COMMENT="' . htmlspecialchars($this->comment, ENT_COMPAT) . '"';
378
        }
379
        $o.= '/>' . "\n";
380
 
381
        return $o;
382
    }
383
 
384
    /**
385
     * This function will set all the attributes of the xmldb_key object
386
     * based on information passed in one ADOkey
387
     * @oaram array $adokey
388
     */
389
    public function setFromADOKey($adokey) {
390
 
391
        // Calculate the XMLDB_KEY
392
        switch (strtolower($adokey['name'])) {
393
            case 'primary':
394
                $this->type = XMLDB_KEY_PRIMARY;
395
                break;
396
            default:
397
                $this->type = XMLDB_KEY_UNIQUE;
398
        }
399
        // Set the fields, converting all them to lowercase
400
        $fields = array_flip(array_change_key_case(array_flip($adokey['columns'])));
401
        $this->fields = $fields;
402
        // Some more fields
403
        $this->loaded = true;
404
        $this->changed = true;
405
    }
406
 
407
    /**
408
     * Returns the PHP code needed to define one xmldb_key
409
     * @return string
410
     */
411
    public function getPHP() {
412
 
413
        $result = '';
414
 
415
        // The type
416
        switch ($this->getType()) {
417
            case XMLDB_KEY_PRIMARY:
418
                $result .= 'XMLDB_KEY_PRIMARY' . ', ';
419
                break;
420
            case XMLDB_KEY_UNIQUE:
421
                $result .= 'XMLDB_KEY_UNIQUE' . ', ';
422
                break;
423
            case XMLDB_KEY_FOREIGN:
424
                $result .= 'XMLDB_KEY_FOREIGN' . ', ';
425
                break;
426
            case XMLDB_KEY_FOREIGN_UNIQUE:
427
                $result .= 'XMLDB_KEY_FOREIGN_UNIQUE' . ', ';
428
                break;
429
        }
430
        // The fields
431
        $keyfields = $this->getFields();
432
        if (!empty($keyfields)) {
433
            $result .= "['".  implode("', '", $keyfields) . "']";
434
        } else {
435
            $result .= 'null';
436
        }
437
        // The FKs attributes
438
        if ($this->getType() == XMLDB_KEY_FOREIGN ||
439
            $this->getType() == XMLDB_KEY_FOREIGN_UNIQUE) {
440
            // The reftable
441
            $reftable = $this->getRefTable();
442
            if (!empty($reftable)) {
443
                $result .= ", '" . $reftable . "', ";
444
            } else {
445
                $result .= 'null, ';
446
            }
447
            // The reffields
448
            $reffields = $this->getRefFields();
449
            if (!empty($reffields)) {
450
                $result .= "['".  implode("', '", $reffields) . "']";
451
            } else {
452
                $result .= 'null';
453
            }
454
        }
455
        // Return result
456
        return $result;
457
    }
458
 
459
    /**
460
     * Shows info in a readable format
461
     * @return string
462
     */
463
    public function readableInfo() {
464
        $o = '';
465
        // type
466
        $o .= $this->getXMLDBKeyName($this->type);
467
        // fields
468
        $o .= ' (' . implode(', ', $this->fields) . ')';
469
        // foreign key
470
        if ($this->type == XMLDB_KEY_FOREIGN ||
471
            $this->type == XMLDB_KEY_FOREIGN_UNIQUE) {
472
            $o .= ' references ' . $this->reftable . ' (' . implode(', ', $this->reffields) . ')';
473
        }
474
 
475
        return $o;
476
    }
477
}