33
2
mirror of https://github.com/joomla-extensions/jedchecker.git synced 2024-11-27 15:26:36 +00:00

implement prefixed rules in DTD-json (to separate processing of files>file and sql>file nodes)

This commit is contained in:
Denis Ryabov 2021-03-09 23:33:42 +03:00
parent 4ed9b2c64d
commit f914e438c5
7 changed files with 62 additions and 19 deletions

View File

@ -219,17 +219,28 @@ class JedcheckerRulesXMLManifest extends JEDcheckerRule
} }
/** /**
* @param SimpleXMLElement $node XML node object * @param SimpleXMLElement $node XML node object
* @param string $name XML node name * @param string $ruleset rulest name in the DTD array
* *
* @return void * @return void
*/ */
protected function validateXml($node, $name) protected function validateXml($node, $ruleset)
{ {
// Check attributes // Get node name
$DTDattributes = isset($this->DTDAttrRules[$name]) ? $this->DTDAttrRules[$name] : array(); $name = $node->getName();
if (isset($DTDattributes[0]) && $DTDattributes[0] !== '*') // Check attributes
$DTDattributes = isset($this->DTDAttrRules[$ruleset]) ? $this->DTDAttrRules[$ruleset] : array();
if (count($DTDattributes) === 0)
{
// No known attributes for this node
foreach ($node->attributes() as $attr)
{
$this->infos[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_UNKNOWN_ATTRIBUTE', $name, (string) $attr->getName());
}
}
elseif ($DTDattributes[0] !== '*') // Skip node with arbitrary attributes (e.g. "field")
{ {
foreach ($node->attributes() as $attr) foreach ($node->attributes() as $attr)
{ {
@ -244,22 +255,35 @@ class JedcheckerRulesXMLManifest extends JEDcheckerRule
} }
// Check children nodes // Check children nodes
if (!isset($this->DTDNodeRules[$name])) $DTDchildRules = isset($this->DTDNodeRules[$ruleset]) ? $this->DTDNodeRules[$ruleset] : array();
// Child node name to ruleset name mapping
$DTDchildToRule = array();
if (count($DTDchildRules) === 0)
{ {
// No children // No known children for this node
if ($node->count() > 0) if ($node->count() > 0)
{ {
$this->infos[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_UNKNOWN_CHILDREN', $name); $this->infos[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_UNKNOWN_CHILDREN', $name);
} }
} }
elseif (!isset($this->DTDNodeRules[$name]['*'])) elseif (!isset($DTDchildRules['*'])) // Skip node with arbitrary children
{ {
$DTDchildren = $this->DTDNodeRules[$name];
// 1) check required single elements // 1) check required single elements
foreach ($DTDchildRules as $childRuleset => $mode)
foreach ($DTDchildren as $child => $mode)
{ {
$child = $childRuleset;
if (strpos($child, ':') !== false)
{
// Split ruleset name into a prefix and the child node name
list ($prefix, $child) = explode(':', $child, 2);
}
// Populate node-to-ruleset mapping
$DTDchildToRule[$child] = $childRuleset;
$count = $node->$child->count(); $count = $node->$child->count();
switch ($mode) switch ($mode)
@ -300,14 +324,16 @@ class JedcheckerRulesXMLManifest extends JEDcheckerRule
foreach ($childNames as $child) foreach ($childNames as $child)
{ {
if (!isset($DTDchildren[$child])) if (!isset($DTDchildToRule[$child]))
{ {
// The node contains unknown child element
$this->infos[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_UNKNOWN_CHILD', $name, $child); $this->infos[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_UNKNOWN_CHILD', $name, $child);
} }
else else
{ {
if ($DTDchildren[$child] === '?' && $node->$child->count() > 1) if ($DTDchildRules[$DTDchildToRule[$child]] === '?' && $node->$child->count() > 1)
{ {
// The node contains multiple child elements when single only is expected
$this->errors[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_MULTIPLE_FOUND', $name, $child); $this->errors[] = JText::sprintf('COM_JEDCHECKER_MANIFEST_MULTIPLE_FOUND', $name, $child);
} }
} }
@ -336,9 +362,9 @@ class JedcheckerRulesXMLManifest extends JEDcheckerRule
{ {
$childName = $child->getName(); $childName = $child->getName();
if (isset($this->DTDNodeRules[$childName])) if (isset($DTDchildToRule[$childName]))
{ {
$this->validateXml($child, $childName); $this->validateXml($child, $DTDchildToRule[$childName]);
} }
} }
} }

View File

@ -33,6 +33,7 @@
}, },
"files": { "files": {
"filename": "*", "filename": "*",
"files:file": "*",
"folder": "*" "folder": "*"
}, },
"languages": { "languages": {
@ -40,6 +41,7 @@
}, },
"media": { "media": {
"filename": "*", "filename": "*",
"media:file": "*",
"folder": "*" "folder": "*"
}, },
"submenu": { "submenu": {

View File

@ -20,14 +20,17 @@
}, },
"files": { "files": {
"filename": "*", "filename": "*",
"files:file": "*",
"folder": "*" "folder": "*"
}, },
"media": { "media": {
"filename": "*", "filename": "*",
"media:file": "*",
"folder": "*" "folder": "*"
}, },
"fonts": { "fonts": {
"filename": "*", "filename": "*",
"fonts:file": "*",
"folder": "*" "folder": "*"
}, },
"updateservers": { "updateservers": {

View File

@ -23,6 +23,7 @@
}, },
"files": { "files": {
"filename": "*", "filename": "*",
"files:file": "*",
"folder": "*" "folder": "*"
}, },
"languages": { "languages": {
@ -30,6 +31,7 @@
}, },
"media": { "media": {
"filename": "*", "filename": "*",
"media:file": "*",
"folder": "*" "folder": "*"
}, },
"install": { "install": {

View File

@ -25,6 +25,7 @@
}, },
"files": { "files": {
"filename": "*", "filename": "*",
"files:file": "*",
"folder": "*" "folder": "*"
}, },
"languages": { "languages": {
@ -32,6 +33,7 @@
}, },
"media": { "media": {
"filename": "*", "filename": "*",
"media:file": "*",
"folder": "*" "folder": "*"
}, },
"install": { "install": {
@ -77,6 +79,9 @@
"filename": [ "filename": [
"module" "module"
], ],
"files:file": [
"module"
],
"languages": [ "languages": [
"folder" "folder"
], ],

View File

@ -23,8 +23,8 @@
"blockChildUninstall": "?" "blockChildUninstall": "?"
}, },
"files": { "files": {
"file": "*",
"filename": "*", "filename": "*",
"files:file": "*",
"folder": "*" "folder": "*"
}, },
"languages": { "languages": {
@ -44,7 +44,7 @@
"files": [ "files": [
"folder" "folder"
], ],
"file": [ "files:file": [
"client", "client",
"group", "group",
"id", "id",

View File

@ -25,6 +25,7 @@
}, },
"files": { "files": {
"filename": "*", "filename": "*",
"files:file": "*",
"folder": "*" "folder": "*"
}, },
"languages": { "languages": {
@ -32,6 +33,7 @@
}, },
"media": { "media": {
"filename": "*", "filename": "*",
"media:file": "*",
"folder": "*" "folder": "*"
}, },
"install": { "install": {
@ -78,6 +80,9 @@
"filename": [ "filename": [
"plugin" "plugin"
], ],
"files:file": [
"plugin"
],
"languages": [ "languages": [
"folder" "folder"
], ],