FrontMarkHydrator::extractJsonFrontmatter()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 5
nop 1
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
ccs 14
cts 14
cp 1
crap 5
1
<?php
2
3
/**
4
 * apparat-resource
5
 *
6
 * @category    Apparat
7
 * @package     Apparat\Resource
8
 * @subpackage  Apparat\Resource\Infrastructure
9
 * @author      Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright   Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license     http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2016 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Apparat\Resource\Infrastructure\Model\Hydrator;
38
39
use Apparat\Resource\Application\Service\StringUtility;
40
use Apparat\Resource\Domain\Model\Hydrator\AbstractSequenceHydrator;
41
use Apparat\Resource\Domain\Model\Hydrator\HydratorInterface;
42
use Apparat\Resource\Domain\Model\Part\PartAggregateInterface;
43
44
/**
45
 * FrontMark part hydrator (combination of YAML / JSON front matter and CommonMark part)
46
 *
47
 * @package     Apparat\Resource
48
 * @subpackage  Apparat\Resource\Infrastructure
49
 */
50
class FrontMarkHydrator extends AbstractSequenceHydrator
51
{
52
    /**
53
     * Translate data to a YAML resource part
54
     *
55
     * @param string $data Part data
56
     * @return PartAggregateInterface Part aggregate
57
     */
58 20
    public function hydrate($data)
59
    {
60 20
        $aggregate = parent::hydrate(null);
61
62
        // Prepare and split the frontmatter data
63 20
        $data = StringUtility::stripBom($data);
64 20
        $frontMatter = '';
65 20
        $commonMarkBody = $data;
66
67
        // Check for a YAML document end marker
68 20
        $yamlParts = preg_split("%\R(\.\.\.)\R%", $data, 2);
69 20
        if (count($yamlParts) > 1) {
70 13
            $frontMatter = array_shift($yamlParts);
71 13
            $commonMarkBody = implode('...', $yamlParts);
72
73
            // Else: Check for JSON front matter
74 7
        } elseif (!strncmp('{', trim($data), 1)) {
75 6
            list($frontMatter, $commonMarkBody) = $this->extractJsonFrontmatter($data);
76
        }
77
78
        // Assign the front matter and body part
79 20
        $aggregate->assign(FrontMatterHydrator::FRONTMATTER, $frontMatter, 0);
80 20
        $aggregate->assign(HydratorInterface::STANDARD, $commonMarkBody, 0);
81
82 20
        return $aggregate;
83
    }
84
85
    /**
86
     * Extract the JSON front matter from a string
87
     *
88
     * @param string $data String
89
     * @return array    JSON front matter and string remainder
90
     */
91 6
    protected function extractJsonFrontmatter($data)
92
    {
93 6
        $jsonFrontMatter = '';
94 6
        $remainder = $data;
95
96
        // Try decoding the whole string first
97 6
        if (is_object(@json_decode(trim($data)))) {
98 1
            $jsonFrontMatter = trim($data);
99 1
            $remainder = '';
100
101
            // Else: If the data contains potential JSON closing brackets
102 5
        } elseif (preg_match_all("%\}[\s\R]*[^\,\}\]]%", $data, $closingBrackets, PREG_OFFSET_CAPTURE)) {
103 5
            foreach ($closingBrackets[0] as $closingBracket) {
104 5
                $jsonData = substr($data, 0, $closingBracket[1] + 1);
105 5
                if (is_object(@json_decode($jsonData))) {
106 5
                    $jsonFrontMatter = trim($jsonData);
107 5
                    $remainder = ltrim(substr($data, $closingBracket[1] + 1));
108 5
                    break;
109
                }
110
            }
111
        }
112
113 6
        return [$jsonFrontMatter, $remainder];
114
    }
115
}
116