| [ Index ] |
PHP Cross Reference of Moodle 310 |
[Summary view] [Print] [Text view]
1 // This file is part of Moodle - http://moodle.org/ 2 // 3 // Moodle is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // Moodle is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 15 16 /** 17 * Helper functions for working with Moodle component names, directories, and sources. 18 * 19 * @copyright 2019 Andrew Nicols <andrew@nicols.co.uk> 20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 21 */ 22 23 "use strict"; 24 /* eslint-env node */ 25 26 /** @var {Object} A list of subsystems in Moodle */ 27 const componentData = {}; 28 29 /** 30 * Load details of all moodle modules. 31 * 32 * @returns {object} 33 */ 34 const fetchComponentData = () => { 35 const fs = require('fs'); 36 const path = require('path'); 37 const glob = require('glob'); 38 const gruntFilePath = process.cwd(); 39 40 if (!Object.entries(componentData).length) { 41 componentData.subsystems = {}; 42 componentData.pathList = []; 43 44 // Fetch the component definiitions from the distributed JSON file. 45 const components = JSON.parse(fs.readFileSync(`$gruntFilePath}/lib/components.json`)); 46 47 // Build the list of moodle subsystems. 48 componentData.subsystems.lib = 'core'; 49 componentData.pathList.push(process.cwd() + path.sep + 'lib'); 50 for (const [component, thisPath] of Object.entries(components.subsystems)) { 51 if (thisPath) { 52 // Prefix "core_" to the front of the subsystems. 53 componentData.subsystems[thisPath] = `core_$component}`; 54 componentData.pathList.push(process.cwd() + path.sep + thisPath); 55 } 56 } 57 58 // The list of components incldues the list of subsystems. 59 componentData.components = componentData.subsystems; 60 61 // Go through each of the plugintypes. 62 Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => { 63 // We don't allow any code in this place..? 64 glob.sync(`$pluginTypePath}/*/version.php`).forEach(versionPath => { 65 const componentPath = fs.realpathSync(path.dirname(versionPath)); 66 const componentName = path.basename(componentPath); 67 const frankenstyleName = `${pluginType}_${componentName}`; 68 componentData.components[`${pluginTypePath}/${componentName}`] = frankenstyleName; 69 componentData.pathList.push(componentPath); 70 71 // Look for any subplugins. 72 const subPluginConfigurationFile = `${componentPath}/db/subplugins.json`; 73 if (fs.existsSync(subPluginConfigurationFile)) { 74 const subpluginList = JSON.parse(fs.readFileSync(fs.realpathSync(subPluginConfigurationFile))); 75 76 Object.entries(subpluginList.plugintypes).forEach(([subpluginType, subpluginTypePath]) => { 77 glob.sync(`${subpluginTypePath}/*/version.php`).forEach(versionPath => { 78 const componentPath = fs.realpathSync(path.dirname(versionPath)); 79 const componentName = path.basename(componentPath); 80 const frankenstyleName = `$subpluginType}_$componentName}`; 81 82 componentData.components[`$subpluginTypePath}/$componentName}`] = frankenstyleName; 83 componentData.pathList.push(componentPath); 84 }); 85 }); 86 } 87 }); 88 }); 89 90 } 91 92 return componentData; 93 }; 94 95 /** 96 * Get the list of paths to build AMD sources. 97 * 98 * @returns {Array} 99 */ 100 const getAmdSrcGlobList = () => { 101 const globList = []; 102 fetchComponentData().pathList.forEach(componentPath => { 103 globList.push(`$componentPath}/amd/src/*.js`); 104 globList.push(`${componentPath}/amd/src/**/*.js`); 105 }); 106 107 return globList; 108 }; 109 110 /** 111 * Get the list of paths to build YUI sources. 112 * 113 * @param {String} relativeTo 114 * @returns {Array} 115 */ 116 const getYuiSrcGlobList = relativeTo => { 117 const globList = []; 118 fetchComponentData().pathList.forEach(componentPath => { 119 const relativeComponentPath = componentPath.replace(relativeTo, ''); 120 globList.push(`$relativeComponentPath}/yui/src/**/*.js`); 121 }); 122 123 return globList; 124 }; 125 126 /** 127 * Get the list of paths to thirdpartylibs.xml. 128 * 129 * @param {String} relativeTo 130 * @returns {Array} 131 */ 132 const getThirdPartyLibsList = relativeTo => { 133 const fs = require('fs'); 134 const path = require('path'); 135 136 return fetchComponentData().pathList 137 .map(componentPath => path.relative(relativeTo, componentPath) + '/thirdpartylibs.xml') 138 .map(componentPath => componentPath.replace(/\\/g, '/')) 139 .filter(path => fs.existsSync(path)) 140 .sort(); 141 }; 142 143 /** 144 * Get the list of thirdparty library paths. 145 * 146 * @returns {array} 147 */ 148 const getThirdPartyPaths = () => { 149 const DOMParser = require('xmldom').DOMParser; 150 const fs = require('fs'); 151 const path = require('path'); 152 const xpath = require('xpath'); 153 154 const thirdpartyfiles = getThirdPartyLibsList(fs.realpathSync('./')); 155 const libs = ['node_modules/', 'vendor/']; 156 157 const addLibToList = lib => { 158 if (!lib.match('\\*') && fs.statSync(lib).isDirectory()) { 159 // Ensure trailing slash on dirs. 160 lib = lib.replace(/\/?$/, '/'); 161 } 162 163 // Look for duplicate paths before adding to array. 164 if (libs.indexOf(lib) === -1) { 165 libs.push(lib); 166 } 167 }; 168 169 thirdpartyfiles.forEach(function(file) { 170 const dirname = path.dirname(file); 171 172 const xmlContent = fs.readFileSync(file, 'utf8'); 173 const doc = new DOMParser().parseFromString(xmlContent); 174 const nodes = xpath.select("/libraries/library/location/text()", doc); 175 176 nodes.forEach(function(node) { 177 let lib = path.posix.join(dirname, node.toString()); 178 addLibToList(lib); 179 }); 180 }); 181 182 return libs; 183 184 }; 185 186 187 /** 188 * Find the name of the component matching the specified path. 189 * 190 * @param {String} path 191 * @returns {String|null} Name of matching component. 192 */ 193 const getComponentFromPath = path => { 194 const componentList = fetchComponentData().components; 195 196 if (componentList.hasOwnProperty(path)) { 197 return componentList[path]; 198 } 199 200 return null; 201 }; 202 203 /** 204 * Check whether the supplied path, relative to the Gruntfile.js, is in a known component. 205 * 206 * @param {String} checkPath The path to check. This can be with either Windows, or Linux directory separators. 207 * @returns {String|null} 208 */ 209 const getOwningComponentDirectory = checkPath => { 210 const path = require('path'); 211 212 // Fetch all components into a reverse sorted array. 213 // This ensures that components which are within the directory of another component match first. 214 const pathList = Object.keys(fetchComponentData().components).sort().reverse(); 215 for (const componentPath of pathList) { 216 // If the componentPath is the directory being checked, it will be empty. 217 // If the componentPath is a parent of the directory being checked, the relative directory will not start with .. 218 if (!path.relative(componentPath, checkPath).startsWith('..')) { 219 return componentPath; 220 } 221 } 222 223 return null; 224 }; 225 226 module.exports = { 227 getAmdSrcGlobList, 228 getComponentFromPath, 229 getOwningComponentDirectory, 230 getYuiSrcGlobList, 231 getThirdPartyLibsList, 232 getThirdPartyPaths, 233 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 22 11:59:49 2025 | Cross-referenced by PHPXref 0.7.1 |