Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Document;
4
 
5
use DateTime;
6
use PhpOffice\PhpSpreadsheet\Shared\IntOrFloat;
7
 
8
class Properties
9
{
10
    /** constants */
11
    public const PROPERTY_TYPE_BOOLEAN = 'b';
12
    public const PROPERTY_TYPE_INTEGER = 'i';
13
    public const PROPERTY_TYPE_FLOAT = 'f';
14
    public const PROPERTY_TYPE_DATE = 'd';
15
    public const PROPERTY_TYPE_STRING = 's';
16
    public const PROPERTY_TYPE_UNKNOWN = 'u';
17
 
18
    private const VALID_PROPERTY_TYPE_LIST = [
19
        self::PROPERTY_TYPE_BOOLEAN,
20
        self::PROPERTY_TYPE_INTEGER,
21
        self::PROPERTY_TYPE_FLOAT,
22
        self::PROPERTY_TYPE_DATE,
23
        self::PROPERTY_TYPE_STRING,
24
    ];
25
 
26
    /**
27
     * Creator.
28
     *
29
     * @var string
30
     */
31
    private $creator = 'Unknown Creator';
32
 
33
    /**
34
     * LastModifiedBy.
35
     *
36
     * @var string
37
     */
38
    private $lastModifiedBy;
39
 
40
    /**
41
     * Created.
42
     *
43
     * @var float|int
44
     */
45
    private $created;
46
 
47
    /**
48
     * Modified.
49
     *
50
     * @var float|int
51
     */
52
    private $modified;
53
 
54
    /**
55
     * Title.
56
     *
57
     * @var string
58
     */
59
    private $title = 'Untitled Spreadsheet';
60
 
61
    /**
62
     * Description.
63
     *
64
     * @var string
65
     */
66
    private $description = '';
67
 
68
    /**
69
     * Subject.
70
     *
71
     * @var string
72
     */
73
    private $subject = '';
74
 
75
    /**
76
     * Keywords.
77
     *
78
     * @var string
79
     */
80
    private $keywords = '';
81
 
82
    /**
83
     * Category.
84
     *
85
     * @var string
86
     */
87
    private $category = '';
88
 
89
    /**
90
     * Manager.
91
     *
92
     * @var string
93
     */
94
    private $manager = '';
95
 
96
    /**
97
     * Company.
98
     *
99
     * @var string
100
     */
101
    private $company = '';
102
 
103
    /**
104
     * Custom Properties.
105
     *
106
     * @var array{value: mixed, type: string}[]
107
     */
108
    private $customProperties = [];
109
 
110
    private string $hyperlinkBase = '';
111
 
112
    /**
113
     * Create a new Document Properties instance.
114
     */
115
    public function __construct()
116
    {
117
        // Initialise values
118
        $this->lastModifiedBy = $this->creator;
119
        $this->created = self::intOrFloatTimestamp(null);
120
        $this->modified = $this->created;
121
    }
122
 
123
    /**
124
     * Get Creator.
125
     */
126
    public function getCreator(): string
127
    {
128
        return $this->creator;
129
    }
130
 
131
    /**
132
     * Set Creator.
133
     *
134
     * @return $this
135
     */
136
    public function setCreator(string $creator): self
137
    {
138
        $this->creator = $creator;
139
 
140
        return $this;
141
    }
142
 
143
    /**
144
     * Get Last Modified By.
145
     */
146
    public function getLastModifiedBy(): string
147
    {
148
        return $this->lastModifiedBy;
149
    }
150
 
151
    /**
152
     * Set Last Modified By.
153
     *
154
     * @return $this
155
     */
156
    public function setLastModifiedBy(string $modifiedBy): self
157
    {
158
        $this->lastModifiedBy = $modifiedBy;
159
 
160
        return $this;
161
    }
162
 
163
    /**
164
     * @param null|float|int|string $timestamp
165
     *
166
     * @return float|int
167
     */
168
    private static function intOrFloatTimestamp($timestamp)
169
    {
170
        if ($timestamp === null) {
171
            $timestamp = (float) (new DateTime())->format('U');
172
        } elseif (is_string($timestamp)) {
173
            if (is_numeric($timestamp)) {
174
                $timestamp = (float) $timestamp;
175
            } else {
176
                $timestamp = (string) preg_replace('/[.][0-9]*$/', '', $timestamp);
177
                $timestamp = (string) preg_replace('/^(\\d{4})- (\\d)/', '$1-0$2', $timestamp);
178
                $timestamp = (string) preg_replace('/^(\\d{4}-\\d{2})- (\\d)/', '$1-0$2', $timestamp);
179
                $timestamp = (float) (new DateTime($timestamp))->format('U');
180
            }
181
        }
182
 
183
        return IntOrFloat::evaluate($timestamp);
184
    }
185
 
186
    /**
187
     * Get Created.
188
     *
189
     * @return float|int
190
     */
191
    public function getCreated()
192
    {
193
        return $this->created;
194
    }
195
 
196
    /**
197
     * Set Created.
198
     *
199
     * @param null|float|int|string $timestamp
200
     *
201
     * @return $this
202
     */
203
    public function setCreated($timestamp): self
204
    {
205
        $this->created = self::intOrFloatTimestamp($timestamp);
206
 
207
        return $this;
208
    }
209
 
210
    /**
211
     * Get Modified.
212
     *
213
     * @return float|int
214
     */
215
    public function getModified()
216
    {
217
        return $this->modified;
218
    }
219
 
220
    /**
221
     * Set Modified.
222
     *
223
     * @param null|float|int|string $timestamp
224
     *
225
     * @return $this
226
     */
227
    public function setModified($timestamp): self
228
    {
229
        $this->modified = self::intOrFloatTimestamp($timestamp);
230
 
231
        return $this;
232
    }
233
 
234
    /**
235
     * Get Title.
236
     */
237
    public function getTitle(): string
238
    {
239
        return $this->title;
240
    }
241
 
242
    /**
243
     * Set Title.
244
     *
245
     * @return $this
246
     */
247
    public function setTitle(string $title): self
248
    {
249
        $this->title = $title;
250
 
251
        return $this;
252
    }
253
 
254
    /**
255
     * Get Description.
256
     */
257
    public function getDescription(): string
258
    {
259
        return $this->description;
260
    }
261
 
262
    /**
263
     * Set Description.
264
     *
265
     * @return $this
266
     */
267
    public function setDescription(string $description): self
268
    {
269
        $this->description = $description;
270
 
271
        return $this;
272
    }
273
 
274
    /**
275
     * Get Subject.
276
     */
277
    public function getSubject(): string
278
    {
279
        return $this->subject;
280
    }
281
 
282
    /**
283
     * Set Subject.
284
     *
285
     * @return $this
286
     */
287
    public function setSubject(string $subject): self
288
    {
289
        $this->subject = $subject;
290
 
291
        return $this;
292
    }
293
 
294
    /**
295
     * Get Keywords.
296
     */
297
    public function getKeywords(): string
298
    {
299
        return $this->keywords;
300
    }
301
 
302
    /**
303
     * Set Keywords.
304
     *
305
     * @return $this
306
     */
307
    public function setKeywords(string $keywords): self
308
    {
309
        $this->keywords = $keywords;
310
 
311
        return $this;
312
    }
313
 
314
    /**
315
     * Get Category.
316
     */
317
    public function getCategory(): string
318
    {
319
        return $this->category;
320
    }
321
 
322
    /**
323
     * Set Category.
324
     *
325
     * @return $this
326
     */
327
    public function setCategory(string $category): self
328
    {
329
        $this->category = $category;
330
 
331
        return $this;
332
    }
333
 
334
    /**
335
     * Get Company.
336
     */
337
    public function getCompany(): string
338
    {
339
        return $this->company;
340
    }
341
 
342
    /**
343
     * Set Company.
344
     *
345
     * @return $this
346
     */
347
    public function setCompany(string $company): self
348
    {
349
        $this->company = $company;
350
 
351
        return $this;
352
    }
353
 
354
    /**
355
     * Get Manager.
356
     */
357
    public function getManager(): string
358
    {
359
        return $this->manager;
360
    }
361
 
362
    /**
363
     * Set Manager.
364
     *
365
     * @return $this
366
     */
367
    public function setManager(string $manager): self
368
    {
369
        $this->manager = $manager;
370
 
371
        return $this;
372
    }
373
 
374
    /**
375
     * Get a List of Custom Property Names.
376
     *
377
     * @return string[]
378
     */
379
    public function getCustomProperties(): array
380
    {
381
        return array_keys($this->customProperties);
382
    }
383
 
384
    /**
385
     * Check if a Custom Property is defined.
386
     */
387
    public function isCustomPropertySet(string $propertyName): bool
388
    {
389
        return array_key_exists($propertyName, $this->customProperties);
390
    }
391
 
392
    /**
393
     * Get a Custom Property Value.
394
     *
395
     * @return mixed
396
     */
397
    public function getCustomPropertyValue(string $propertyName)
398
    {
399
        if (isset($this->customProperties[$propertyName])) {
400
            return $this->customProperties[$propertyName]['value'];
401
        }
402
 
403
        return null;
404
    }
405
 
406
    /**
407
     * Get a Custom Property Type.
408
     *
409
     * @return null|string
410
     */
411
    public function getCustomPropertyType(string $propertyName)
412
    {
413
        return $this->customProperties[$propertyName]['type'] ?? null;
414
    }
415
 
416
    /**
417
     * @param mixed $propertyValue
418
     */
419
    private function identifyPropertyType($propertyValue): string
420
    {
421
        if (is_float($propertyValue)) {
422
            return self::PROPERTY_TYPE_FLOAT;
423
        }
424
        if (is_int($propertyValue)) {
425
            return self::PROPERTY_TYPE_INTEGER;
426
        }
427
        if (is_bool($propertyValue)) {
428
            return self::PROPERTY_TYPE_BOOLEAN;
429
        }
430
 
431
        return self::PROPERTY_TYPE_STRING;
432
    }
433
 
434
    /**
435
     * Set a Custom Property.
436
     *
437
     * @param mixed $propertyValue
438
     * @param string $propertyType
439
     *   'i' : Integer
440
     *   'f' : Floating Point
441
     *   's' : String
442
     *   'd' : Date/Time
443
     *   'b' : Boolean
444
     *
445
     * @return $this
446
     */
447
    public function setCustomProperty(string $propertyName, $propertyValue = '', $propertyType = null): self
448
    {
449
        if (($propertyType === null) || (!in_array($propertyType, self::VALID_PROPERTY_TYPE_LIST))) {
450
            $propertyType = $this->identifyPropertyType($propertyValue);
451
        }
452
 
453
        if (!is_object($propertyValue)) {
454
            $this->customProperties[$propertyName] = [
455
                'value' => self::convertProperty($propertyValue, $propertyType),
456
                'type' => $propertyType,
457
            ];
458
        }
459
 
460
        return $this;
461
    }
462
 
463
    private const PROPERTY_TYPE_ARRAY = [
464
        'i' => self::PROPERTY_TYPE_INTEGER,      //    Integer
465
        'i1' => self::PROPERTY_TYPE_INTEGER,     //    1-Byte Signed Integer
466
        'i2' => self::PROPERTY_TYPE_INTEGER,     //    2-Byte Signed Integer
467
        'i4' => self::PROPERTY_TYPE_INTEGER,     //    4-Byte Signed Integer
468
        'i8' => self::PROPERTY_TYPE_INTEGER,     //    8-Byte Signed Integer
469
        'int' => self::PROPERTY_TYPE_INTEGER,    //    Integer
470
        'ui1' => self::PROPERTY_TYPE_INTEGER,    //    1-Byte Unsigned Integer
471
        'ui2' => self::PROPERTY_TYPE_INTEGER,    //    2-Byte Unsigned Integer
472
        'ui4' => self::PROPERTY_TYPE_INTEGER,    //    4-Byte Unsigned Integer
473
        'ui8' => self::PROPERTY_TYPE_INTEGER,    //    8-Byte Unsigned Integer
474
        'uint' => self::PROPERTY_TYPE_INTEGER,   //    Unsigned Integer
475
        'f' => self::PROPERTY_TYPE_FLOAT,        //    Real Number
476
        'r4' => self::PROPERTY_TYPE_FLOAT,       //    4-Byte Real Number
477
        'r8' => self::PROPERTY_TYPE_FLOAT,       //    8-Byte Real Number
478
        'decimal' => self::PROPERTY_TYPE_FLOAT,  //    Decimal
479
        's' => self::PROPERTY_TYPE_STRING,       //    String
480
        'empty' => self::PROPERTY_TYPE_STRING,   //    Empty
481
        'null' => self::PROPERTY_TYPE_STRING,    //    Null
482
        'lpstr' => self::PROPERTY_TYPE_STRING,   //    LPSTR
483
        'lpwstr' => self::PROPERTY_TYPE_STRING,  //    LPWSTR
484
        'bstr' => self::PROPERTY_TYPE_STRING,    //    Basic String
485
        'd' => self::PROPERTY_TYPE_DATE,         //    Date and Time
486
        'date' => self::PROPERTY_TYPE_DATE,      //    Date and Time
487
        'filetime' => self::PROPERTY_TYPE_DATE,  //    File Time
488
        'b' => self::PROPERTY_TYPE_BOOLEAN,      //    Boolean
489
        'bool' => self::PROPERTY_TYPE_BOOLEAN,   //    Boolean
490
    ];
491
 
492
    private const SPECIAL_TYPES = [
493
        'empty' => '',
494
        'null' => null,
495
    ];
496
 
497
    /**
498
     * Convert property to form desired by Excel.
499
     *
500
     * @param mixed $propertyValue
501
     *
502
     * @return mixed
503
     */
504
    public static function convertProperty($propertyValue, string $propertyType)
505
    {
506
        return self::SPECIAL_TYPES[$propertyType] ?? self::convertProperty2($propertyValue, $propertyType);
507
    }
508
 
509
    /**
510
     * Convert property to form desired by Excel.
511
     *
512
     * @param mixed $propertyValue
513
     *
514
     * @return mixed
515
     */
516
    private static function convertProperty2($propertyValue, string $type)
517
    {
518
        $propertyType = self::convertPropertyType($type);
519
        switch ($propertyType) {
520
            case self::PROPERTY_TYPE_INTEGER:
521
                $intValue = (int) $propertyValue;
522
 
523
                return ($type[0] === 'u') ? abs($intValue) : $intValue;
524
            case self::PROPERTY_TYPE_FLOAT:
525
                return (float) $propertyValue;
526
            case self::PROPERTY_TYPE_DATE:
527
                return self::intOrFloatTimestamp($propertyValue);
528
            case self::PROPERTY_TYPE_BOOLEAN:
529
                return is_bool($propertyValue) ? $propertyValue : ($propertyValue === 'true');
530
            default: // includes string
531
                return $propertyValue;
532
        }
533
    }
534
 
535
    public static function convertPropertyType(string $propertyType): string
536
    {
537
        return self::PROPERTY_TYPE_ARRAY[$propertyType] ?? self::PROPERTY_TYPE_UNKNOWN;
538
    }
539
 
540
    public function getHyperlinkBase(): string
541
    {
542
        return $this->hyperlinkBase;
543
    }
544
 
545
    public function setHyperlinkBase(string $hyperlinkBase): self
546
    {
547
        $this->hyperlinkBase = $hyperlinkBase;
548
 
549
        return $this;
550
    }
551
}