Passed
Push — 1.11.x ( bce6cd...c146d9 )
by Angel Fernando Quiroz
12:25
created

export/src/lib/ccdependencyparser.php (1 issue)

1
<?php
2
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/backup/cc/cc_lib/gral_lib/ccdependencyparser.php under GNU/GPL license */
3
4
/**
5
 * Converts \ Directory separator to the / more suitable for URL.
6
 *
7
 * @param string $path
8
 */
9
function toUrlPath(&$path)
10
{
11
    for ($count = 0; $count < strlen($path); $count++) {
12
        $chr = $path[$count];
13
        if (($chr == '\\')) {
14
            $path[$count] = '/';
15
        }
16
    }
17
}
18
19
/**
20
 * Returns relative path from two directories with full path.
21
 *
22
 * @param string $path1
23
 * @param string $path2
24
 *
25
 * @return string
26
 */
27
function pathDiff($path1, $path2)
28
{
29
    toUrlPath($path1);
30
    toUrlPath($path2);
31
    $result = "";
32
    $bl2 = strlen($path2);
33
    $a = strpos($path1, $path2);
34
    if ($a !== false) {
35
        $result = trim(substr($path1, $bl2 + $a), '/');
36
    }
37
38
    return $result;
39
}
40
41
/**
42
 * Converts direcotry separator in given path to / to validate in CC
43
 * Value is passed byref hence variable itself is changed.
44
 *
45
 * @param string $path
46
 */
47
function toNativePath(&$path)
48
{
49
    for ($count = 0; $count < strlen($path); $count++) {
50
        $chr = $path[$count];
51
        if (($chr == '\\') || ($chr == '/')) {
52
            $path[$count] = '/';
53
        }
54
    }
55
}
56
57
/**
58
 * Function strips url part from css link.
59
 *
60
 * @param string $path
61
 * @param string $rootDir
62
 *
63
 * @return string
64
 */
65
function stripUrl($path, $rootDir = '')
66
{
67
    $result = $path;
68
    if (is_string($path) && ($path != '')) {
69
        $start = strpos($path, '(') + 1;
70
        $length = strpos($path, ')') - $start;
71
        $rut = $rootDir.substr($path, $start, $length);
72
        $result = fullPath($rut, '/');
73
    }
74
75
    return $result;
76
}
77
78
/**
79
 * Get full path
80
 *
81
 * @param string $path
82
 * @param string $dirsep
83
 * @return false|string
84
 */
85
function fullPath($path, $dirsep = DIRECTORY_SEPARATOR)
86
{
87
    $token = '$IMS-CC-FILEBASE$';
88
    $path = str_replace($token, '', $path);
89
    if (is_string($path) && ($path != '')) {
90
        $sep = $dirsep;
91
        $dotDir = '.';
92
        $upDir = '..';
93
        $length = strlen($path);
94
        $rtemp = trim($path);
95
        $start = strrpos($path, $sep);
96
        $canContinue = ($start !== false);
97
        $result = $canContinue ? '' : $path;
98
        $rcount = 0;
99
        while ($canContinue) {
100
            $dirPart = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp;
101
            $canContinue = ($dirPart !== false);
102
            if ($canContinue) {
103
                if ($dirPart != $dotDir) {
104
                    if ($dirPart == $upDir) {
105
                        $rcount++;
106
                    } else {
107
                        if ($rcount > 0) {
108
                            $rcount--;
109
                        } else {
110
                            $result = ($result == '') ? $dirPart : $dirPart.$sep.$result;
111
                        }
112
                    }
113
                }
114
                $rtemp = substr($path, 0, $start);
115
                $start = strrpos($rtemp, $sep);
116
                $canContinue = (($start !== false) || (strlen($rtemp) > 0));
117
            }
118
        }
119
    }
120
121
    return $result;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.
Loading history...
122
}
123
124
/**
125
 * validates URL.
126
 *
127
 * @param string $url
128
 *
129
 * @return bool
130
 */
131
function isUrl($url)
132
{
133
    $result = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) !== false;
134
135
    return $result;
136
}
137
138
/**
139
 * Gets the dependency files of the $fname file
140
 *
141
 * @param string $manifestroot
142
 * @param string $fname
143
 * @param string $folder
144
 * @param array $filenames
145
 */
146
function getDepFiles($manifestroot, $fname, $folder, &$filenames)
147
{
148
    static $types = ['xhtml' => true, 'html' => true, 'htm' => true];
149
    $extension = strtolower(trim(pathinfo($fname, PATHINFO_EXTENSION)));
150
    $filenames = [];
151
    if (isset($types[$extension])) {
152
        $dcx = new XMLGenericDocument();
153
        $filename = $manifestroot.$folder.$fname;
154
        if (!file_exists($filename)) {
155
            $filename = $manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname;
156
        }
157
        if (file_exists($filename)) {
158
            $res = $dcx->loadHTMLFile($filename);
159
            if ($res) {
160
                getDepFilesHTML($manifestroot, $fname, $filenames, $dcx, $folder);
161
            }
162
        }
163
    }
164
}
165
166
/**
167
 * Gets the dependency of .html of the $fname file
168
 *
169
 * @param string $manifestroot
170
 * @param string $fname
171
 * @param string $filenames
172
 * @param string $dcx
173
 * @param string $folder
174
 */
175
function getDepFilesHTML($manifestroot, $fname, &$filenames, &$dcx, $folder)
176
{
177
    $dcx->resetXpath();
178
    $nlist = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href");
179
    $cssObjArray = [];
180
    foreach ($nlist as $nl) {
181
        $item = $folder.$nl->nodeValue;
182
        $path_parts = pathinfo($item);
183
        $fname = $path_parts['basename'];
184
        $ext = array_key_exists('extension', $path_parts) ? $path_parts['extension'] : '';
185
        if (!isUrl($folder.$nl->nodeValue) && !isUrl($nl->nodeValue)) {
186
            $path = $folder.$nl->nodeValue;
187
            $file = fullPath($path, "/");
188
            toNativePath($file);
189
            if (file_exists($manifestroot.DIRECTORY_SEPARATOR.$file)) {
190
                $filenames[$file] = $file;
191
            }
192
        }
193
        if ($ext == 'css') {
194
            $css = new CssParser();
195
            $css->parse($dcx->filePath().$nl->nodeValue);
196
            $cssObjArray[$item] = $css;
197
        }
198
    }
199
    $nlist = $dcx->nodeList("//*/@class");
200
    foreach ($nlist as $nl) {
201
        $item = $folder.$nl->nodeValue;
202
        foreach ($cssObjArray as $csskey => $cssobj) {
203
            $bimg = $cssobj->get($item, "background-image");
204
            $limg = $cssobj->get($item, "list-style-image");
205
            $npath = pathinfo($csskey);
206
            if ((!empty($bimg)) && ($bimg != 'none')) {
207
                $value = stripUrl($bimg, $npath['dirname'].'/');
208
                $filenames[$value] = $value;
209
            } elseif ((!empty($limg)) && ($limg != 'none')) {
210
                $value = stripUrl($limg, $npath['dirname'].'/');
211
                $filenames[$value] = $value;
212
            }
213
        }
214
    }
215
    $elemsToCheck = ["body", "p", "ul", "h4", "a", "th"];
216
    $doWeHaveIt = [];
217
    foreach ($elemsToCheck as $elem) {
218
        $doWeHaveIt[$elem] = ($dcx->nodeList("//".$elem)->length > 0);
219
    }
220
    foreach ($elemsToCheck as $elem) {
221
        if ($doWeHaveIt[$elem]) {
222
            foreach ($cssObjArray as $csskey => $cssobj) {
223
                $sb = $cssobj->get($elem, "background-image");
224
                $sbl = $cssobj->get($elem, "list-style-image");
225
                $npath = pathinfo($csskey);
226
                if ((!empty($sb)) && ($sb != 'none')) {
227
                    $value = stripUrl($sb, $npath['dirname'].'/');
228
                    $filenames[$value] = $value;
229
                } elseif ((!empty($sbl)) && ($sbl != 'none')) {
230
                    $value = stripUrl($sbl, $npath['dirname'].'/');
231
                    $filenames[$value] = $value;
232
                }
233
            }
234
        }
235
    }
236
}
237