Issues (2037)

export/src/lib/ccdependencyparser.php (2 issues)

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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result could also return false which is incompatible with the documented return type string. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
76
}
77
78
/**
79
 * Get full path.
80
 *
81
 * @param string $path
82
 * @param string $dirsep
83
 *
84
 * @return false|string
85
 */
86
function fullPath($path, $dirsep = DIRECTORY_SEPARATOR)
87
{
88
    $token = '$IMS-CC-FILEBASE$';
89
    $path = str_replace($token, '', $path);
90
    if (is_string($path) && ($path != '')) {
91
        $sep = $dirsep;
92
        $dotDir = '.';
93
        $upDir = '..';
94
        $length = strlen($path);
95
        $rtemp = trim($path);
96
        $start = strrpos($path, $sep);
97
        $canContinue = ($start !== false);
98
        $result = $canContinue ? '' : $path;
99
        $rcount = 0;
100
        while ($canContinue) {
101
            $dirPart = ($start !== false) ? substr($rtemp, $start + 1, $length - $start) : $rtemp;
102
            $canContinue = ($dirPart !== false);
103
            if ($canContinue) {
104
                if ($dirPart != $dotDir) {
105
                    if ($dirPart == $upDir) {
106
                        $rcount++;
107
                    } else {
108
                        if ($rcount > 0) {
109
                            $rcount--;
110
                        } else {
111
                            $result = ($result == '') ? $dirPart : $dirPart.$sep.$result;
112
                        }
113
                    }
114
                }
115
                $rtemp = substr($path, 0, $start);
116
                $start = strrpos($rtemp, $sep);
117
                $canContinue = (($start !== false) || (strlen($rtemp) > 0));
118
            }
119
        }
120
    }
121
122
    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...
123
}
124
125
/**
126
 * validates URL.
127
 *
128
 * @param string $url
129
 *
130
 * @return bool
131
 */
132
function isUrl($url)
133
{
134
    $result = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED) !== false;
135
136
    return $result;
137
}
138
139
/**
140
 * Gets the dependency files of the $fname file.
141
 *
142
 * @param string $manifestroot
143
 * @param string $fname
144
 * @param string $folder
145
 * @param array  $filenames
146
 */
147
function getDepFiles($manifestroot, $fname, $folder, &$filenames)
148
{
149
    static $types = ['xhtml' => true, 'html' => true, 'htm' => true];
150
    $extension = strtolower(trim(pathinfo($fname, PATHINFO_EXTENSION)));
151
    $filenames = [];
152
    if (isset($types[$extension])) {
153
        $dcx = new XMLGenericDocument();
154
        $filename = $manifestroot.$folder.$fname;
155
        if (!file_exists($filename)) {
156
            $filename = $manifestroot.DIRECTORY_SEPARATOR.$folder.DIRECTORY_SEPARATOR.$fname;
157
        }
158
        if (file_exists($filename)) {
159
            $res = $dcx->loadHTMLFile($filename);
160
            if ($res) {
161
                getDepFilesHTML($manifestroot, $fname, $filenames, $dcx, $folder);
162
            }
163
        }
164
    }
165
}
166
167
/**
168
 * Gets the dependency of .html of the $fname file.
169
 *
170
 * @param string $manifestroot
171
 * @param string $fname
172
 * @param string $filenames
173
 * @param string $dcx
174
 * @param string $folder
175
 */
176
function getDepFilesHTML($manifestroot, $fname, &$filenames, &$dcx, $folder)
177
{
178
    $dcx->resetXpath();
179
    $nlist = $dcx->nodeList("//img/@src | //link/@href | //script/@src | //a[not(starts-with(@href,'#'))]/@href");
180
    $cssObjArray = [];
181
    foreach ($nlist as $nl) {
182
        $item = $folder.$nl->nodeValue;
183
        $path_parts = pathinfo($item);
184
        $fname = $path_parts['basename'];
185
        $ext = array_key_exists('extension', $path_parts) ? $path_parts['extension'] : '';
186
        if (!isUrl($folder.$nl->nodeValue) && !isUrl($nl->nodeValue)) {
187
            $path = $folder.$nl->nodeValue;
188
            $file = fullPath($path, "/");
189
            toNativePath($file);
190
            if (file_exists($manifestroot.DIRECTORY_SEPARATOR.$file)) {
191
                $filenames[$file] = $file;
192
            }
193
        }
194
        if ($ext == 'css') {
195
            $css = new CssParser();
196
            $css->parse($dcx->filePath().$nl->nodeValue);
197
            $cssObjArray[$item] = $css;
198
        }
199
    }
200
    $nlist = $dcx->nodeList("//*/@class");
201
    foreach ($nlist as $nl) {
202
        $item = $folder.$nl->nodeValue;
203
        foreach ($cssObjArray as $csskey => $cssobj) {
204
            $bimg = $cssobj->get($item, "background-image");
205
            $limg = $cssobj->get($item, "list-style-image");
206
            $npath = pathinfo($csskey);
207
            if ((!empty($bimg)) && ($bimg != 'none')) {
208
                $value = stripUrl($bimg, $npath['dirname'].'/');
209
                $filenames[$value] = $value;
210
            } elseif ((!empty($limg)) && ($limg != 'none')) {
211
                $value = stripUrl($limg, $npath['dirname'].'/');
212
                $filenames[$value] = $value;
213
            }
214
        }
215
    }
216
    $elemsToCheck = ["body", "p", "ul", "h4", "a", "th"];
217
    $doWeHaveIt = [];
218
    foreach ($elemsToCheck as $elem) {
219
        $doWeHaveIt[$elem] = ($dcx->nodeList("//".$elem)->length > 0);
220
    }
221
    foreach ($elemsToCheck as $elem) {
222
        if ($doWeHaveIt[$elem]) {
223
            foreach ($cssObjArray as $csskey => $cssobj) {
224
                $sb = $cssobj->get($elem, "background-image");
225
                $sbl = $cssobj->get($elem, "list-style-image");
226
                $npath = pathinfo($csskey);
227
                if ((!empty($sb)) && ($sb != 'none')) {
228
                    $value = stripUrl($sb, $npath['dirname'].'/');
229
                    $filenames[$value] = $value;
230
                } elseif ((!empty($sbl)) && ($sbl != 'none')) {
231
                    $value = stripUrl($sbl, $npath['dirname'].'/');
232
                    $filenames[$value] = $value;
233
                }
234
            }
235
        }
236
    }
237
}
238