HyperlinkExternal::getData()   B
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 36
rs 8.8571
cc 3
eloc 22
nc 4
nop 2
1
<?php
2
namespace Xls\Record;
3
4
use Xls\StringUtils;
5
use Xls\Range;
6
7
class HyperlinkExternal extends Hyperlink
8
{
9
    const MONIKER_GUID = "0303000000000000C000000000000046";
10
11
    /**
12
     * @param Range $range
13
     * @param $url
14
     *
15
     * @return string
16
     */
17
    public function getData(Range $range, $url)
18
    {
19
        $cellRef = null;
20
        if (preg_match("/\#/", $url)) {
21
            $parts = explode('#', $url);
22
            $url = $parts[0];
23
            $cellRef = $parts[1];
24
        }
25
26
        // Calculate the up-level dir count e.g.. (..\..\..\ == 3)
27
        $upCount = preg_match_all("/\.\.\\\/", $url, $useless);
28
29
        // Store the short dos dir name (null terminated)
30
        $urlWithoutDots = preg_replace("/\.\.\\\/", '', $url) . "\0";
31
32
        // Unknown 24 bytes
33
        $unknown = pack("H*", 'FFFFADDE' . str_repeat('00', 20));
34
35
        $streamLen = pack("V", 0);
36
37
        $options = $this->getOptions($url);
38
        $data = $this->getCommonData($range, $options);
39
        $data .= pack("H*", static::MONIKER_GUID) .
40
            pack("v", $upCount) .
41
            pack("V", strlen($urlWithoutDots)) .
42
            $urlWithoutDots .
43
            $unknown .
44
            $streamLen;
45
46
        if ($cellRef) {
47
            $cellRef = StringUtils::toNullTerminatedWchar($cellRef);
48
            $data .= $this->getTextMarkData($cellRef);
49
        }
50
51
        return $this->getFullRecord($data);
52
    }
53
54
    protected function getOptions($url)
55
    {
56
        // Determine if the link is relative or absolute:
57
        //   relative if link contains no dir separator, "somefile.xls"
58
        //   relative if link starts with up-dir, "..\..\somefile.xls"
59
        //   otherwise, absolute
60
61
        $absolute = 1; // Bit mask
62
        if (!preg_match("/\\\/", $url)
63
            || preg_match("/^\.\.\\\/", $url)
64
        ) {
65
            $absolute = 0;
66
        }
67
68
        $options = 0x00;
69
        $options |= 1 << 0; //File link or URL
70
        $options |= $absolute << 1; //File link or URL
71
72
        if (preg_match("/\#/", $url)) {
73
            $options |= 1 << 3; //Has text mark
74
        }
75
76
        return $options;
77
    }
78
}
79