Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
119 / 119
100.00% covered (success)
100.00%
32 / 32
CRAP
100.00% covered (success)
100.00%
1 / 1
DocInfo
100.00% covered (success)
100.00%
119 / 119
100.00% covered (success)
100.00%
32 / 32
54
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 getCreator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCreator
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLastModifiedBy
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLastModifiedBy
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCreated
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCreated
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getModified
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setModified
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTitle
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getDescription
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDescription
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getSubject
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSubject
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getKeywords
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setKeywords
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCategory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCategory
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCompany
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCompany
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getManager
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setManager
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCustomProperties
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isCustomPropertySet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCustomPropertyValue
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getCustomPropertyType
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setCustomProperty
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
8
 convertProperty
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
8
 convertPropertyType
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 setValue
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 getConversion
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2/**
3 * This file is part of PHPWord - A pure PHP library for reading and writing
4 * word processing documents.
5 *
6 * PHPWord is free software distributed under the terms of the GNU Lesser
7 * General Public License version 3 as published by the Free Software Foundation.
8 *
9 * For the full copyright and license information, please read the LICENSE
10 * file that was distributed with this source code. For the full list of
11 * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
12 *
13 * @see         https://github.com/PHPOffice/PHPWord
14 *
15 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16 */
17
18namespace PhpOffice\PhpWord\Metadata;
19
20use DateTime;
21
22/**
23 * Document information.
24 */
25class DocInfo
26{
27    /** @const string Property type constants */
28    const PROPERTY_TYPE_BOOLEAN = 'b';
29    const PROPERTY_TYPE_INTEGER = 'i';
30    const PROPERTY_TYPE_FLOAT = 'f';
31    const PROPERTY_TYPE_DATE = 'd';
32    const PROPERTY_TYPE_STRING = 's';
33    const PROPERTY_TYPE_UNKNOWN = 'u';
34
35    /**
36     * Creator.
37     *
38     * @var string
39     */
40    private $creator;
41
42    /**
43     * LastModifiedBy.
44     *
45     * @var string
46     */
47    private $lastModifiedBy;
48
49    /**
50     * Created.
51     *
52     * @var int
53     */
54    private $created;
55
56    /**
57     * Modified.
58     *
59     * @var int
60     */
61    private $modified;
62
63    /**
64     * Title.
65     *
66     * @var string
67     */
68    private $title;
69
70    /**
71     * Description.
72     *
73     * @var string
74     */
75    private $description;
76
77    /**
78     * Subject.
79     *
80     * @var string
81     */
82    private $subject;
83
84    /**
85     * Keywords.
86     *
87     * @var string
88     */
89    private $keywords;
90
91    /**
92     * Category.
93     *
94     * @var string
95     */
96    private $category;
97
98    /**
99     * Company.
100     *
101     * @var string
102     */
103    private $company;
104
105    /**
106     * Manager.
107     *
108     * @var string
109     */
110    private $manager;
111
112    /**
113     * Custom Properties.
114     *
115     * @var array
116     */
117    private $customProperties = [];
118
119    /**
120     * Create new instance.
121     */
122    public function __construct()
123    {
124        $this->creator = '';
125        $this->lastModifiedBy = $this->creator;
126        $this->created = time();
127        $this->modified = time();
128        $this->title = '';
129        $this->subject = '';
130        $this->description = '';
131        $this->keywords = '';
132        $this->category = '';
133        $this->company = '';
134        $this->manager = '';
135    }
136
137    /**
138     * Get Creator.
139     *
140     * @return string
141     */
142    public function getCreator()
143    {
144        return $this->creator;
145    }
146
147    /**
148     * Set Creator.
149     *
150     * @param  string $value
151     *
152     * @return self
153     */
154    public function setCreator($value = '')
155    {
156        $this->creator = $this->setValue($value, '');
157
158        return $this;
159    }
160
161    /**
162     * Get Last Modified By.
163     *
164     * @return string
165     */
166    public function getLastModifiedBy()
167    {
168        return $this->lastModifiedBy;
169    }
170
171    /**
172     * Set Last Modified By.
173     *
174     * @param  string $value
175     *
176     * @return self
177     */
178    public function setLastModifiedBy($value = '')
179    {
180        $this->lastModifiedBy = $this->setValue($value, $this->creator);
181
182        return $this;
183    }
184
185    /**
186     * Get Created.
187     *
188     * @return int
189     */
190    public function getCreated()
191    {
192        return $this->created;
193    }
194
195    /**
196     * Set Created.
197     *
198     * @param  int $value
199     *
200     * @return self
201     */
202    public function setCreated($value = null)
203    {
204        $this->created = $this->setValue($value, time());
205
206        return $this;
207    }
208
209    /**
210     * Get Modified.
211     *
212     * @return int
213     */
214    public function getModified()
215    {
216        return $this->modified;
217    }
218
219    /**
220     * Set Modified.
221     *
222     * @param  int $value
223     *
224     * @return self
225     */
226    public function setModified($value = null)
227    {
228        $this->modified = $this->setValue($value, time());
229
230        return $this;
231    }
232
233    /**
234     * Get Title.
235     *
236     * @return string
237     */
238    public function getTitle()
239    {
240        return $this->title;
241    }
242
243    /**
244     * Set Title.
245     *
246     * @param  string $value
247     *
248     * @return self
249     */
250    public function setTitle($value = '')
251    {
252        $this->title = $this->setValue($value, '');
253
254        return $this;
255    }
256
257    /**
258     * Get Description.
259     *
260     * @return string
261     */
262    public function getDescription()
263    {
264        return $this->description;
265    }
266
267    /**
268     * Set Description.
269     *
270     * @param  string $value
271     *
272     * @return self
273     */
274    public function setDescription($value = '')
275    {
276        $this->description = $this->setValue($value, '');
277
278        return $this;
279    }
280
281    /**
282     * Get Subject.
283     *
284     * @return string
285     */
286    public function getSubject()
287    {
288        return $this->subject;
289    }
290
291    /**
292     * Set Subject.
293     *
294     * @param  string $value
295     *
296     * @return self
297     */
298    public function setSubject($value = '')
299    {
300        $this->subject = $this->setValue($value, '');
301
302        return $this;
303    }
304
305    /**
306     * Get Keywords.
307     *
308     * @return string
309     */
310    public function getKeywords()
311    {
312        return $this->keywords;
313    }
314
315    /**
316     * Set Keywords.
317     *
318     * @param string $value
319     *
320     * @return self
321     */
322    public function setKeywords($value = '')
323    {
324        $this->keywords = $this->setValue($value, '');
325
326        return $this;
327    }
328
329    /**
330     * Get Category.
331     *
332     * @return string
333     */
334    public function getCategory()
335    {
336        return $this->category;
337    }
338
339    /**
340     * Set Category.
341     *
342     * @param string $value
343     *
344     * @return self
345     */
346    public function setCategory($value = '')
347    {
348        $this->category = $this->setValue($value, '');
349
350        return $this;
351    }
352
353    /**
354     * Get Company.
355     *
356     * @return string
357     */
358    public function getCompany()
359    {
360        return $this->company;
361    }
362
363    /**
364     * Set Company.
365     *
366     * @param string $value
367     *
368     * @return self
369     */
370    public function setCompany($value = '')
371    {
372        $this->company = $this->setValue($value, '');
373
374        return $this;
375    }
376
377    /**
378     * Get Manager.
379     *
380     * @return string
381     */
382    public function getManager()
383    {
384        return $this->manager;
385    }
386
387    /**
388     * Set Manager.
389     *
390     * @param string $value
391     *
392     * @return self
393     */
394    public function setManager($value = '')
395    {
396        $this->manager = $this->setValue($value, '');
397
398        return $this;
399    }
400
401    /**
402     * Get a List of Custom Property Names.
403     *
404     * @return array of string
405     */
406    public function getCustomProperties()
407    {
408        return array_keys($this->customProperties);
409    }
410
411    /**
412     * Check if a Custom Property is defined.
413     *
414     * @param string $propertyName
415     *
416     * @return bool
417     */
418    public function isCustomPropertySet($propertyName)
419    {
420        return isset($this->customProperties[$propertyName]);
421    }
422
423    /**
424     * Get a Custom Property Value.
425     *
426     * @param string $propertyName
427     *
428     * @return mixed
429     */
430    public function getCustomPropertyValue($propertyName)
431    {
432        if ($this->isCustomPropertySet($propertyName)) {
433            return $this->customProperties[$propertyName]['value'];
434        }
435
436        return null;
437    }
438
439    /**
440     * Get a Custom Property Type.
441     *
442     * @param string $propertyName
443     *
444     * @return ?string
445     */
446    public function getCustomPropertyType($propertyName)
447    {
448        if ($this->isCustomPropertySet($propertyName)) {
449            return $this->customProperties[$propertyName]['type'];
450        }
451
452        return null;
453    }
454
455    /**
456     * Set a Custom Property.
457     *
458     * @param string $propertyName
459     * @param mixed $propertyValue
460     * @param string $propertyType
461     *   'i': Integer
462     *   'f': Floating Point
463     *   's': String
464     *   'd': Date/Time
465     *   'b': Boolean
466     *
467     * @return self
468     */
469    public function setCustomProperty($propertyName, $propertyValue = '', $propertyType = null)
470    {
471        $propertyTypes = [
472            self::PROPERTY_TYPE_INTEGER,
473            self::PROPERTY_TYPE_FLOAT,
474            self::PROPERTY_TYPE_STRING,
475            self::PROPERTY_TYPE_DATE,
476            self::PROPERTY_TYPE_BOOLEAN,
477        ];
478        if (($propertyType === null) || (!in_array($propertyType, $propertyTypes))) {
479            if ($propertyValue === null) {
480                $propertyType = self::PROPERTY_TYPE_STRING;
481            } elseif (is_float($propertyValue)) {
482                $propertyType = self::PROPERTY_TYPE_FLOAT;
483            } elseif (is_int($propertyValue)) {
484                $propertyType = self::PROPERTY_TYPE_INTEGER;
485            } elseif (is_bool($propertyValue)) {
486                $propertyType = self::PROPERTY_TYPE_BOOLEAN;
487            } elseif ($propertyValue instanceof DateTime) {
488                $propertyType = self::PROPERTY_TYPE_DATE;
489            } else {
490                $propertyType = self::PROPERTY_TYPE_STRING;
491            }
492        }
493
494        $this->customProperties[$propertyName] = [
495            'value' => $propertyValue,
496            'type' => $propertyType,
497        ];
498
499        return $this;
500    }
501
502    /**
503     * Convert document property based on type.
504     *
505     * @param string $propertyValue
506     * @param string $propertyType
507     *
508     * @return mixed
509     */
510    public static function convertProperty($propertyValue, $propertyType)
511    {
512        $conversion = self::getConversion($propertyType);
513
514        switch ($conversion) {
515            case 'empty': // Empty
516                return '';
517            case 'null': // Null
518                return null;
519            case 'int': // Signed integer
520                return (int) $propertyValue;
521            case 'uint': // Unsigned integer
522                return abs((int) $propertyValue);
523            case 'float': // Float
524                return (float) $propertyValue;
525            case 'date': // Date
526                return strtotime($propertyValue);
527            case 'bool': // Boolean
528                return $propertyValue == 'true';
529        }
530
531        return $propertyValue;
532    }
533
534    /**
535     * Convert document property type.
536     *
537     * @param string $propertyType
538     *
539     * @return string
540     */
541    public static function convertPropertyType($propertyType)
542    {
543        $typeGroups = [
544            self::PROPERTY_TYPE_INTEGER => ['i1', 'i2', 'i4', 'i8', 'int', 'ui1', 'ui2', 'ui4', 'ui8', 'uint'],
545            self::PROPERTY_TYPE_FLOAT => ['r4', 'r8', 'decimal'],
546            self::PROPERTY_TYPE_STRING => ['empty', 'null', 'lpstr', 'lpwstr', 'bstr'],
547            self::PROPERTY_TYPE_DATE => ['date', 'filetime'],
548            self::PROPERTY_TYPE_BOOLEAN => ['bool'],
549        ];
550        foreach ($typeGroups as $groupId => $groupMembers) {
551            if (in_array($propertyType, $groupMembers)) {
552                return $groupId;
553            }
554        }
555
556        return self::PROPERTY_TYPE_UNKNOWN;
557    }
558
559    /**
560     * Set default for null and empty value.
561     *
562     * @param mixed $value
563     * @param mixed $default
564     *
565     * @return mixed
566     */
567    private function setValue($value, $default)
568    {
569        if ($value === null || $value == '') {
570            $value = $default;
571        }
572
573        return $value;
574    }
575
576    /**
577     * Get conversion model depending on property type.
578     *
579     * @param string $propertyType
580     *
581     * @return string
582     */
583    private static function getConversion($propertyType)
584    {
585        $conversions = [
586            'empty' => ['empty'],
587            'null' => ['null'],
588            'int' => ['i1', 'i2', 'i4', 'i8', 'int'],
589            'uint' => ['ui1', 'ui2', 'ui4', 'ui8', 'uint'],
590            'float' => ['r4', 'r8', 'decimal'],
591            'bool' => ['bool'],
592            'date' => ['date', 'filetime'],
593        ];
594        foreach ($conversions as $conversion => $types) {
595            if (in_array($propertyType, $types)) {
596                return $conversion;
597            }
598        }
599
600        return 'string';
601    }
602}