MediaBlockExtractor   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
eloc 22
c 1
b 0
f 0
dl 0
loc 55
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
B extract() 0 44 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ReliqArts\StyleImporter\CSS\Extractor;
6
7
use ReliqArts\StyleImporter\CSS\Extractor;
8
use ReliqArts\StyleImporter\CSS\MediaBlock;
9
use ReliqArts\StyleImporter\Exception\InvalidArgument;
10
11
final class MediaBlockExtractor implements Extractor
12
{
13
    /**
14
     * @param string $styles
15
     *
16
     * @throws InvalidArgument
17
     *
18
     * @return MediaBlock[]
19
     *
20
     * @see https://stackoverflow.com/a/14145856 Adapted from this answer on the legendary StackOverflow
21
     */
22
    public function extract(string $styles): array
23
    {
24
        $mediaBlocks = [];
25
26
        $start = 0;
27
        while (($start = strpos($styles, MediaBlock::TOKEN_MEDIA, $start)) !== false) {
28
            // stack to manage brackets
29
            $brackets = [];
30
31
            // get the first opening bracket
32
            $openingBracketPosition = strpos($styles, MediaBlock::TOKEN_OPENING_BRACKET, $start);
33
34
            // if $i is false, then there is probably a css syntax error
35
            if ($openingBracketPosition !== false) {
36
                // push bracket onto stack
37
                array_push($brackets, $styles[$openingBracketPosition]);
38
39
                // move past first bracket
40
                ++$openingBracketPosition;
41
42
                while (!empty($brackets)) {
43
                    // if the character is an opening bracket, push it onto the stack, otherwise pop the stack
44
                    if ($styles[$openingBracketPosition] === MediaBlock::TOKEN_OPENING_BRACKET) {
45
                        array_push($brackets, MediaBlock::TOKEN_OPENING_BRACKET);
46
                    } elseif ($styles[$openingBracketPosition] === MediaBlock::TOKEN_CLOSING_BRACKET) {
47
                        array_pop($brackets);
48
                    }
49
50
                    ++$openingBracketPosition;
51
                }
52
53
                // cut the media block out of the css and store
54
                $mediaBlocks[] = MediaBlock::createFromString(substr(
55
                    $styles,
56
                    $start,
57
                    ($openingBracketPosition + 1) - $start
58
                ) ?: '');
59
60
                // set the new $start to the end of the block
61
                $start = $openingBracketPosition;
62
            }
63
        }
64
65
        return $mediaBlocks;
66
    }
67
}
68