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