Completed
Push — develop ( 8b7740...30f26a )
by
unknown
08:10 queued 04:46
created

Meta::convertKeys()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.054

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 13
ccs 9
cts 11
cp 0.8182
rs 9.4285
cc 3
eloc 9
nc 3
nop 1
crap 3.054
1
<?php
2
/**
3
 * The Meta Parser Interface
4
 */
5
namespace Phile\Plugin\Phile\ParserMeta\Parser;
6
7
use Phile\ServiceLocator\MetaInterface;
8
use Symfony\Component\Yaml\Yaml;
9
10
/**
11
 * Class Meta
12
 *
13
 * @author  PhileCMS
14
 * @link    https://philecms.com
15
 * @license http://opensource.org/licenses/MIT
16
 * @package Phile\Plugin\Phile\ParserMeta\Parser
17
 */
18
class Meta implements MetaInterface
19
{
20
    /**
21
 * @var array $config the configuration for this parser
22
*/
23
    private $config;
24
25
    /**
26
     * the constructor
27
     *
28
     * @param array $config
29
     */
30 2
    public function __construct(array $config = null)
31
    {
32 2
        if (!is_null($config)) {
33 2
            $this->config = $config;
34 2
        }
35 2
    }
36
37
    /**
38
     * parse the content and extract meta information
39
     *
40
     * @param  string $rawData raw page data
41
     * @return array with key/value store
42
     */
43 19
    public function parse($rawData)
44
    {
45 19
        $rawData = trim($rawData);
46 19
        $fences = $this->config['fences'];
47
48 19
        $start = $stop = null;
49 19
        foreach ($fences as $fence) {
50 19
            $start = $fence['open'];
51 19
            $length = strlen($start);
52 19
            if (substr($rawData, 0, $length) === $start) {
53 19
                $stop = $fence['close'];
54 19
                break;
55
            }
56 19
        }
57
58 19
        if ($stop === null) {
59 1
            return [];
60
        }
61
62 19
        $meta = trim(substr($rawData, strlen($start), strpos($rawData, $stop) - (strlen($stop) + 1)));
63 19
        if (strtolower($this->config['format']) === 'yaml') {
64
            $meta = Yaml::parse($meta);
0 ignored issues
show
Security File Exposure introduced by
$meta can contain request data and is used in file inclusion context(s) leading to a potential security vulnerability.

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
65
        } else {
66 19
            $meta = $this->parsePhileFormat($meta);
0 ignored issues
show
Deprecated Code introduced by
The method Phile\Plugin\Phile\Parse...eta::parsePhileFormat() has been deprecated with message: since 1.6.0 Phile is going to switch to YAML

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
67
        }
68 19
        $meta = ($meta === null) ? [] : $this->convertKeys($meta);
0 ignored issues
show
Bug introduced by
It seems like $meta can also be of type string; however, Phile\Plugin\Phile\Parse...ser\Meta::convertKeys() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
69 19
        return $meta;
70
    }
71
72
    /**
73
     * convert meta data keys
74
     *
75
     * Creates "compatible" keys allowing easy access e.g. as template var.
76
     *
77
     * Conversions applied:
78
     *
79
     * - lowercase all chars
80
     * - replace special chars and whitespace with underscore
81
     *
82
     * @param  array $meta meta-data
83
     * @return array
84
     */
85 18
    protected function convertKeys(array $meta)
86
    {
87 18
        $return = [];
88 18
        foreach ($meta as $key => $value) {
89 18
            if (is_array($value)) {
90
                $value = $this->convertKeys($value);
91
            }
92 18
            $newKey = strtolower($key);
93 18
            $newKey = preg_replace('/[^\w+]/', '_', $newKey);
94 18
            $return[$newKey] = $value;
95 18
        }
96 18
        return $return;
97
    }
98
99
    /**
100
     * Phile meta format parser.
101
     *
102
     * @param  string $string unparsed meta-data
103
     * @return array|null array with meta-tags; null: on meta-data found
104
     *
105
     * @deprecated since 1.6.0 Phile is going to switch to YAML
106
     */
107
    protected function parsePhileFormat($string)
108
    {
109
        if (empty($string)) {
110
            return null;
111
        }
112
        $meta = [];
113
        $lines = explode("\n", $string);
114
        foreach ($lines as $line) {
115
            $parts = explode(':', $line, 2);
116
            if (count($parts) !== 2) {
117
                continue;
118
            }
119
            $parts = array_map('trim', $parts);
120
            $meta[$parts[0]] = $parts[1];
121
        }
122
        return $meta;
123
    }
124
}
125