From a45cd5aabfdf823b48e0ea5bcbd1b42eee82cb38 Mon Sep 17 00:00:00 2001 From: Rich Lott / Artful Robot Date: Sat, 18 Apr 2020 08:55:51 +0100 Subject: [PATCH] dev-core/1719: replace xml encoding function in CaseType --- CRM/Case/BAO/CaseType.php | 149 +- tests/phpunit/CRM/Case/BAO/CaseTypeTest.php | 13 + tests/phpunit/CRM/Case/BAO/xml/empty-defn.xml | 2 +- .../phpunit/CRM/Case/BAO/xml/empty-lists.xml | 2 +- .../CRM/Case/BAO/xml/empty-node-text.xml | 2 +- tests/phpunit/CRM/Case/BAO/xml/forkable-0.xml | 2 +- tests/phpunit/CRM/Case/BAO/xml/forkable-1.xml | 2 +- .../CRM/Case/BAO/xml/one-item-in-each.xml | 2 +- tests/phpunit/CRM/Case/BAO/xml/statuses.xml | 14 + .../CRM/Case/BAO/xml/two-items-in-each.xml | 2 +- .../Incremental/php/FiveTwentyTest.php | 1204 ++++++++--------- 11 files changed, 729 insertions(+), 665 deletions(-) create mode 100644 tests/phpunit/CRM/Case/BAO/xml/statuses.xml diff --git a/CRM/Case/BAO/CaseType.php b/CRM/Case/BAO/CaseType.php index 9937c56272..e10c70da07 100644 --- a/CRM/Case/BAO/CaseType.php +++ b/CRM/Case/BAO/CaseType.php @@ -96,50 +96,87 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType { * XML */ public static function convertDefinitionToXML($name, $definition) { - $xmlFile = '' . "\n\n\n"; - $xmlFile .= "" . self::encodeXmlString($name) . "\n"; + + $xw = new XMLWriter(); + $xw->openMemory(); + $xw->setIndent(TRUE); + $xw->setIndentString(' '); + $xw->startDocument("1.0", 'UTF-8'); + + $xw->startElement('CaseType'); + + $xw->startElement('name'); + $xw->text($name); + $xw->fullEndElement(); if (array_key_exists('forkable', $definition)) { - $xmlFile .= "" . ((int) $definition['forkable']) . "\n"; + $xw->startElement('forkable'); + $xw->text((int) $definition['forkable']); + $xw->fullEndElement(); } if (isset($definition['activityTypes'])) { - $xmlFile .= "\n"; + $xw->startElement('ActivityTypes'); + foreach ($definition['activityTypes'] as $values) { - $xmlFile .= "\n"; + $xw->startElement('ActivityType'); foreach ($values as $key => $value) { - $xmlFile .= "<{$key}>" . self::encodeXmlString($value) . "\n"; + $xw->startElement($key); + $xw->text($value); + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // ActivityType + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // ActivityTypes + $xw->fullEndElement(); } if (!empty($definition['statuses'])) { - $xmlFile .= "\n"; + $xw->startElement('Statuses'); + foreach ($definition['statuses'] as $value) { - $xmlFile .= "$value\n"; + $xw->startElement('Status'); + $xw->text($value); + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // Statuses + $xw->fullEndElement(); } if (isset($definition['activitySets'])) { - $xmlFile .= "\n"; + + $xw->startElement('ActivitySets'); foreach ($definition['activitySets'] as $k => $val) { - $xmlFile .= "\n"; + + $xw->startElement('ActivitySet'); foreach ($val as $index => $setVal) { switch ($index) { case 'activityTypes': if (!empty($setVal)) { - $xmlFile .= "\n"; + $xw->startElement('ActivityTypes'); foreach ($setVal as $values) { - $xmlFile .= "\n"; + $xw->startElement('ActivityType'); foreach ($values as $key => $value) { - $xmlFile .= "<{$key}>" . self::encodeXmlString($value) . "\n"; + // Some parameters here may be arrays of values. + // Also, the tests expect an empty array to be represented as an empty value. + $value = (array) $value; + if (count($value) === 0) { + // Create an empty value. + $value[] = ''; + } + + foreach ($value as $val) { + $xw->startElement($key); + $xw->text($val); + $xw->fullEndElement(); + } } - $xmlFile .= "\n"; + // ActivityType + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // ActivityTypes + $xw->fullEndElement(); } break; @@ -147,68 +184,68 @@ class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType { case 'sequence': case 'timeline': if ($setVal) { - $xmlFile .= "<{$index}>true\n"; + $xw->startElement($index); + $xw->text('true'); + $xw->fullEndElement(); } break; default: - $xmlFile .= "<{$index}>" . self::encodeXmlString($setVal) . "\n"; + $xw->startElement($index); + $xw->text($setVal); + $xw->fullEndElement(); } } - - $xmlFile .= "\n"; + // ActivitySet + $xw->fullEndElement(); } - - $xmlFile .= "\n"; + // ActivitySets + $xw->fullEndElement(); } if (isset($definition['caseRoles'])) { - $xmlFile .= "\n"; + $xw->startElement('CaseRoles'); foreach ($definition['caseRoles'] as $values) { - $xmlFile .= "\n"; + $xw->startElement('RelationshipType'); foreach ($values as $key => $value) { - $xmlFile .= "<{$key}>" . ($key == 'groups' ? implode(',', array_map(['\CRM_Case_BAO_CaseType', 'encodeXmlString'], (array) $value)) : self::encodeXmlString($value)) . "\n"; + $xw->startElement($key); + if ($key == 'groups') { + $xw->text(implode(',', (array) $value)); + } + else { + $xw->text($value); + } + // $key + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // RelationshipType + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // CaseRoles + $xw->fullEndElement(); } if (array_key_exists('restrictActivityAsgmtToCmsUser', $definition)) { - $xmlFile .= "" . $definition['restrictActivityAsgmtToCmsUser'] . "\n"; + $xw->startElement('RestrictActivityAsgmtToCmsUser'); + $xw->text($definition['restrictActivityAsgmtToCmsUser']); + $xw->fullEndElement(); } - if (!empty($definition['activityAsgmtGrps'])) { - $xmlFile .= "\n"; + $xw->startElement('ActivityAsgmtGrps'); foreach ((array) $definition['activityAsgmtGrps'] as $value) { - $xmlFile .= "$value\n"; + $xw->startElement('Group'); + $xw->text($value); + $xw->fullEndElement(); } - $xmlFile .= "\n"; + // ActivityAsgmtGrps + $xw->fullEndElement(); } - $xmlFile .= ''; - - return $xmlFile; - } + // CaseType + $xw->fullEndElement(); + $xw->endDocument(); - /** - * Ugh. This shouldn't exist. Use a real XML-encoder. - * - * Escape a string for use in XML. - * - * @param string $str - * A string which should outputted to XML. - * @return string - * @deprecated - */ - protected static function encodeXmlString($str) { - // PHP 5.4: return htmlspecialchars($str, ENT_XML1, 'UTF-8') - if (is_scalar($str)) { - return htmlspecialchars($str); - } - else { - return NULL; - } + return $xw->outputMemory(); } /** diff --git a/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php b/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php index 54514f9bbe..b93ce0629c 100644 --- a/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php +++ b/tests/phpunit/CRM/Case/BAO/CaseTypeTest.php @@ -28,6 +28,18 @@ class CRM_Case_BAO_CaseTypeTest extends CiviUnitTestCase { 'xml' => file_get_contents(__DIR__ . '/xml/empty-lists.xml'), ]; + $fixtures['statuses'] = [ + 'json' => json_encode([ + 'activitySets' => [], + 'activityTypes' => [], + 'caseRoles' => [], + 'statuses' => ['Ongoing', 'Completed', 'This & That'], + //'statuses' => ['Ongoing', 'Completed'], + 'timelineActivityTypes' => [], + ]), + 'xml' => file_get_contents(__DIR__ . '/xml/statuses.xml'), + ]; + $fixtures['one-item-in-each'] = [ 'json' => json_encode([ 'activityTypes' => [ @@ -177,6 +189,7 @@ class CRM_Case_BAO_CaseTypeTest extends CiviUnitTestCase { 'two-items-in-each', 'forkable-0', 'forkable-1', + 'statuses', ] as $key) { $cases[] = [$key, $fixtures[$key]['json'], $fixtures[$key]['xml']]; } diff --git a/tests/phpunit/CRM/Case/BAO/xml/empty-defn.xml b/tests/phpunit/CRM/Case/BAO/xml/empty-defn.xml index 575aaa4226..e94ac35423 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/empty-defn.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/empty-defn.xml @@ -1,4 +1,4 @@ - + Housing Support diff --git a/tests/phpunit/CRM/Case/BAO/xml/empty-lists.xml b/tests/phpunit/CRM/Case/BAO/xml/empty-lists.xml index 768b6cdb2c..9c671a37ba 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/empty-lists.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/empty-lists.xml @@ -1,4 +1,4 @@ - + Housing Support diff --git a/tests/phpunit/CRM/Case/BAO/xml/empty-node-text.xml b/tests/phpunit/CRM/Case/BAO/xml/empty-node-text.xml index 48c116b523..b36d991bd4 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/empty-node-text.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/empty-node-text.xml @@ -1,4 +1,4 @@ - + Housing Support diff --git a/tests/phpunit/CRM/Case/BAO/xml/forkable-0.xml b/tests/phpunit/CRM/Case/BAO/xml/forkable-0.xml index a6e6ed1b36..49fb512673 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/forkable-0.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/forkable-0.xml @@ -1,4 +1,4 @@ - + Housing Support 0 diff --git a/tests/phpunit/CRM/Case/BAO/xml/forkable-1.xml b/tests/phpunit/CRM/Case/BAO/xml/forkable-1.xml index e1427534a7..a483592ebf 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/forkable-1.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/forkable-1.xml @@ -1,4 +1,4 @@ - + Housing Support 1 diff --git a/tests/phpunit/CRM/Case/BAO/xml/one-item-in-each.xml b/tests/phpunit/CRM/Case/BAO/xml/one-item-in-each.xml index 2445273761..1822f84645 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/one-item-in-each.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/one-item-in-each.xml @@ -1,4 +1,4 @@ - + Housing Support diff --git a/tests/phpunit/CRM/Case/BAO/xml/statuses.xml b/tests/phpunit/CRM/Case/BAO/xml/statuses.xml new file mode 100644 index 0000000000..d32b57db7b --- /dev/null +++ b/tests/phpunit/CRM/Case/BAO/xml/statuses.xml @@ -0,0 +1,14 @@ + + + + Housing Support + + + Ongoing + Completed + This & That + + + + + diff --git a/tests/phpunit/CRM/Case/BAO/xml/two-items-in-each.xml b/tests/phpunit/CRM/Case/BAO/xml/two-items-in-each.xml index 313c6652bf..82f6786367 100644 --- a/tests/phpunit/CRM/Case/BAO/xml/two-items-in-each.xml +++ b/tests/phpunit/CRM/Case/BAO/xml/two-items-in-each.xml @@ -1,4 +1,4 @@ - + Housing Support diff --git a/tests/phpunit/CRM/Upgrade/Incremental/php/FiveTwentyTest.php b/tests/phpunit/CRM/Upgrade/Incremental/php/FiveTwentyTest.php index fe01cc3ca5..14aa68c27f 100644 --- a/tests/phpunit/CRM/Upgrade/Incremental/php/FiveTwentyTest.php +++ b/tests/phpunit/CRM/Upgrade/Incremental/php/FiveTwentyTest.php @@ -54,111 +54,111 @@ class CRM_Upgrade_Incremental_php_FiveTwentyTest extends CiviCaseTestCase { * don't get borked. */ $newCaseTypeXml = << - + -test_type - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - -давид - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - -Follow up - -Scheduled -Open Case -14 -newest -2 -{$relationshipTypeNames['Benefits Specialist']}_a_b - - - -Follow up - -Scheduled -Open Case -21 -newest -2 -{$relationshipTypeNames['Spouse of']}_a_b - - - -Follow up - -Scheduled -Open Case -28 -newest -2 -{$relationshipTypeNames['Spouse of']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -0 - + test_type + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + давид + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + Follow up + + Scheduled + Open Case + 14 + newest + 2 + {$relationshipTypeNames['Benefits Specialist']}_a_b + + + + Follow up + + Scheduled + Open Case + 21 + newest + 2 + {$relationshipTypeNames['Spouse of']}_a_b + + + + Follow up + + Scheduled + Open Case + 28 + newest + 2 + {$relationshipTypeNames['Spouse of']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + 0 + + ENDXML; $dao = new CRM_Case_DAO_CaseType(); @@ -344,173 +344,173 @@ ENDXML; switch ($stage) { case 1: $newCaseTypeXml = << - + -simple - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -is Wallet Inspector of - - -has as Wallet Inspector - - -абвгде - - -αβγδ changed - - -0 + simple + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + is Wallet Inspector of + + + has as Wallet Inspector + + + абвгде + + + αβγδ changed + + + 0 + ENDXMLSIMPLE; $expectedCaseTypeXml = << - + -simple - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -Wallet Inspector - - -Wallet Inspector is - - -абвгде - - -αβγδ - - -0 + simple + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + Wallet Inspector + + + Wallet Inspector is + + + абвгде + + + αβγδ + + + 0 + ENDXMLSIMPLEEXPECTED; $caseTypeId = $this->addCaseType('simple', $newCaseTypeXml); @@ -525,185 +525,185 @@ ENDXMLSIMPLEEXPECTED; // unchanged if they choose to continue with the upgrade. $newCaseTypeXml = << - + -mixedup - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -is Wallet Inspector of - - -has as Wallet Inspector - - -абвгде - - -αβγδ changed - - -Benefits Specialist - - -Mythical Unicorn - - -0 + mixedup + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + is Wallet Inspector of + + + has as Wallet Inspector + + + абвгде + + + αβγδ changed + + + Benefits Specialist + + + Mythical Unicorn + + + 0 + ENDXMLMIXEDUP; $expectedCaseTypeXml = << - + -mixedup - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -Wallet Inspector - - -Wallet Inspector is - - -абвгде - - -αβγδ - - -Benefits Specialist - - -Mythical Unicorn - - -0 + mixedup + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + Wallet Inspector + + + Wallet Inspector is + + + абвгде + + + αβγδ + + + Benefits Specialist + + + Mythical Unicorn + + + 0 + ENDXMLMIXEDUPEXPECTED; $caseTypeId = $this->addCaseType('mixedup', $newCaseTypeXml); @@ -713,179 +713,179 @@ ENDXMLMIXEDUPEXPECTED; ]; $newCaseTypeXml = << - + -diffname - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -is Wallet Inspector of - - -has as Wallet Inspector - - -абвгде - - -αβγδ changed - - -Archenemy of - - -0 + diffname + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + is Wallet Inspector of + + + has as Wallet Inspector + + + абвгде + + + αβγδ changed + + + Archenemy of + + + 0 + ENDXMLDIFFNAME; $expectedCaseTypeXml = << - + -diffname - - -Open Case -1 - - -Email - - -Follow up - - -Meeting - - -Phone Call - - - - -standard_timeline - -true - - -Open Case -Completed - -1 - - - - -timeline_1 - -true - - -Follow up - -Scheduled -Open Case -7 -newest -2 -{$relationshipTypeNames['Senior Services Coordinator']}_b_a - - - - - - - -Senior Services Coordinator -1 -1 - - -Spouse of - - -Benefits Specialist is - - -Wallet Inspector - - -Wallet Inspector is - - -абвгде - - -αβγδ - - -Archenemy of - - -0 + diffname + + + Open Case + 1 + + + Email + + + Follow up + + + Meeting + + + Phone Call + + + + + standard_timeline + + true + + + Open Case + Completed + + 1 + + + + + timeline_1 + + true + + + Follow up + + Scheduled + Open Case + 7 + newest + 2 + {$relationshipTypeNames['Senior Services Coordinator']}_b_a + + + + + + + + Senior Services Coordinator + 1 + 1 + + + Spouse of + + + Benefits Specialist is + + + Wallet Inspector + + + Wallet Inspector is + + + абвгде + + + αβγδ + + + Archenemy of + + + 0 + ENDXMLDIFFNAMEEXPECTED; $caseTypeId = $this->addCaseType('diffname', $newCaseTypeXml); -- 2.25.1