Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ProjectLibre
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
2 / 2
7
100.00% covered (success)
100.00%
1 / 1
 canRead
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 load
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3/**
4 * This file is part of PHPProject - A pure PHP library for reading and writing
5 * project management files.
6 *
7 * PHPProject 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/PHPProject/contributors.
13 *
14 * @link        https://github.com/PHPOffice/PHPProject
15 * @copyright   2009-2014 PHPProject contributors
16 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
17 */
18
19declare(strict_types=1);
20
21namespace PhpOffice\PhpProject\Reader;
22
23use PhpOffice\PhpProject\PhpProject;
24
25/**
26 * ProjectLibre reader
27 *
28 * A ProjectLibre `.pod` file (version 1.5.5+) is made of serialized Java data,
29 * a separator, then an MSPDI file. This reader locates the separator and reads
30 * the embedded MSPDI part with the MSPDI reader.
31 */
32class ProjectLibre implements ReaderInterface
33{
34    /**
35     * Separator placed before the embedded MSPDI file inside a `.pod` file
36     */
37    const MSPDI_SEPARATOR = '@@@@@@@@@@ProjectLibreSeparator_MSXML@@@@@@@@@@';
38
39    /**
40     * @param string $pFilename
41     * @return bool
42     */
43    public function canRead(string $pFilename): bool
44    {
45        if (!file_exists($pFilename) || !is_readable($pFilename)) {
46            return false;
47        }
48        $content = (string) file_get_contents($pFilename);
49
50        return strpos($content, self::MSPDI_SEPARATOR) !== false;
51    }
52
53    /**
54     * @param string $pFilename
55     * @throws \Exception
56     * @return PhpProject
57     */
58    public function load(string $pFilename): PhpProject
59    {
60        if (!file_exists($pFilename) || !is_readable($pFilename)) {
61            throw new \Exception('The file is not accessible.');
62        }
63
64        // Keep only the MSPDI part, located after the separator.
65        $content = (string) file_get_contents($pFilename);
66        $position = strpos($content, self::MSPDI_SEPARATOR);
67        if ($position === false) {
68            throw new \Exception('The file is not a valid ProjectLibre file.');
69        }
70        $mspdi = substr($content, $position + strlen(self::MSPDI_SEPARATOR));
71
72        // The MSPDI reader expects a file, so we write the MSPDI part to a
73        // temporary file before delegating to it.
74        $tempFile = (string) tempnam(sys_get_temp_dir(), 'PHPPROJECT');
75        file_put_contents($tempFile, $mspdi);
76
77        $phpProject = (new MSPDI())->load($tempFile);
78
79        unlink($tempFile);
80
81        return $phpProject;
82    }
83}