Skip to content

Commit b0ec00f

Browse files
authored
Merge pull request #298 from Liturgical-Calendar/development
fix yaml output
2 parents 194a626 + 14c34e1 commit b0ec00f

File tree

6 files changed

+134
-42
lines changed

6 files changed

+134
-42
lines changed

jsondata/schemas/LitCalMetadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@
607607
},
608608
"api_path": {
609609
"type": "string",
610-
"pattern": "^https?:\\\/\\\/(?:litcal\\.johnromanodorazio\\.com\\\/api\\\/(?:dev|v[3-9])|localhost(?:\\:\\d+))\\\/data\\\/widerregion\\\/[ACEINOSW][flmnsueoc][rseatindo][a-zA-Z\\s]+\\?locale=\\{language\\}$"
610+
"pattern": "^https?:\\\/\\\/(?:litcal\\.johnromanodorazio\\.com\\\/api\\\/(?:dev|v[3-9])|localhost(?:\\:\\d{4}))\\\/data\\\/widerregion\\\/[ACEINOSW][flmnsueoc][rseatindo][a-zA-Z\\s]+\\?locale=\\{language\\}$"
611611
}
612612
},
613613
"required": ["name", "locales", "api_path"]

jsondata/schemas/LitCalMissalsPath.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"api_path": {
6767
"type": "string",
6868
"format": "uri",
69-
"pattern": "https?:\\\/\\\/litcal\\.johnromanodorazio\\.com\\\/api\\\/(dev|v[3-9])\\\/missals\\\/(EDITIO_TYPICA|IT|US|NL)_(19[7-9]|[2-9][0-9][0-9])[0-9]$"
69+
"pattern": "^https?:\\\/\\\/(?:litcal\\.johnromanodorazio\\.com\\\/api\\\/(?:dev|v[3-9])|localhost(?:\\:\\d{4}))\\\/missals\\\/(EDITIO_TYPICA|IT|US|NL)_(19[7-9]|[2-9][0-9][0-9])[0-9]$"
7070
}
7171
},
7272
"required": [

jsondata/schemas/LitCalSchemasPath.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"type": "array",
99
"items": {
1010
"type": "string",
11-
"pattern": "^https?:\\\/\\\/litcal\\.johnromanodorazio\\.com\\\/api\\\/(dev|v[3-9])\\\/jsondata\\\/schemas\\\/[a-zA-Z]+\\.json"
11+
"pattern": "^https?:\\\/\\\/(?:litcal\\.johnromanodorazio\\.com\\\/api\\\/(?:dev|v[3-9])|localhost(?:\\:\\d{4}))\\\/jsondata\\\/schemas\\\/[a-zA-Z]+\\.json"
1212
}
1313
}
1414
}

src/Health.php

Lines changed: 127 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ private static function retrieveSchemaForCategory(string $category, ?string $dat
304304
$schema = LitSchema::DATA;
305305
foreach ($matches as $idx => $match) {
306306
if ($idx > 0) {
307-
switch ($matches[$idx]) {
307+
switch ($match) {
308308
case 'nation':
309309
$schema = LitSchema::NATIONAL;
310310
break;
@@ -364,12 +364,22 @@ private static function retrieveSchemaForCategory(string $category, ?string $dat
364364
*/
365365
private function executeValidation(object $validation, ConnectionInterface $to)
366366
{
367+
// First thing is try to determine the schema that we will be validating against,
368+
// and the path to the source file or folder that we will be validating against the schema.
369+
// Our purpose here is to set the $pathForSchema and $dataPath variables.
370+
$pathForSchema = null;
371+
$dataPath = null;
372+
$responseType = 'JSON';
373+
374+
// Source data checks validate data directly in the filesystem, not through the API
367375
if ($validation->category === 'sourceDataCheck') {
368-
$pathForSchema = $validation->validate;
376+
$pathForSchema = $validation->validate;
377+
// Are we validating a single source file, or are we validating a folder of i18n files?
369378
if (property_exists($validation, 'sourceFolder')) {
379+
// If the 'sourceFolder' property is set, then we are validating a folder of i18n files
370380
$dataPath = rtrim($validation->sourceFolder, '/');
371381
$matches = null;
372-
if (preg_match("/^(wider\-region|national\-calendar|diocesan\-calendar)\-([A-Z][_a-z]+)\-i18n$/", $validation->validate, $matches)) {
382+
if (preg_match("/^(wider\-region|national\-calendar|diocesan\-calendar)\-([A-Za-z_]+)\-i18n$/", $validation->validate, $matches)) {
373383
switch ($matches[1]) {
374384
case 'wider-region':
375385
$dataPath = strtr(
@@ -388,8 +398,10 @@ private function executeValidation(object $validation, ConnectionInterface $to)
388398
$nation = $diocese->nation;
389399
$dataPath = strtr(
390400
JsonData::DIOCESAN_CALENDARS_I18N_FOLDER,
391-
['{diocese}' => $matches[2]],
392-
['{nation}' => $nation]
401+
[
402+
'{diocese}' => $matches[2],
403+
'{nation}' => $nation
404+
]
393405
);
394406
break;
395407
}
@@ -399,6 +411,8 @@ private function executeValidation(object $validation, ConnectionInterface $to)
399411
$dataPath = RomanMissal::$i18nPath["{$region}_{$year}"];
400412
}
401413
} else {
414+
// If we are not validating a folder of i18n files, then we are validating a single source file,
415+
// and the 'sourceFile' property is required in this case
402416
if (property_exists($validation, 'sourceFile')) {
403417
$dataPath = $validation->sourceFile;
404418
$matches = null;
@@ -422,9 +436,11 @@ private function executeValidation(object $validation, ConnectionInterface $to)
422436
$dioceseName = $diocese->diocese;
423437
$dataPath = strtr(
424438
JsonData::DIOCESAN_CALENDARS_FILE,
425-
['{diocese}' => $matches[2]],
426-
['{nation}' => $nation],
427-
['{diocese_name}' => $dioceseName]
439+
[
440+
'{diocese}' => $matches[2],
441+
'{nation}' => $nation,
442+
'{diocese_name}' => $dioceseName
443+
]
428444
);
429445
break;
430446
}
@@ -436,18 +452,23 @@ private function executeValidation(object $validation, ConnectionInterface $to)
436452
}
437453
}
438454
} else {
455+
// If it's not a sourceDataCheck, it's probably a resourceDataCheck
456+
// That is to say, an API path
439457
$pathForSchema = $validation->sourceFile;
440458
$dataPath = $validation->sourceFile;
441459
}
442460

443461
$schema = Health::retrieveSchemaForCategory($validation->category, $pathForSchema);
444462

463+
// Now that we have the correct schema to validate against,
464+
// we will perform the actual validation either for all files in a folder, or for a single file
445465
if (property_exists($validation, 'sourceFolder')) {
466+
// If the 'sourceFolder' property is set, then we are validating a folder of i18n files
446467
$files = glob($dataPath . '/*.json');
447468
if (false === $files || empty($files)) {
448469
$message = new \stdClass();
449470
$message->type = "error";
450-
$message->text = "Data folder $validation->sourceFolder does not exist or does not contain any json files";
471+
$message->text = "Data folder $validation->sourceFolder ($dataPath) does not exist or does not contain any json files";
451472
$message->classes = ".$validation->validate.file-exists";
452473
$this->sendMessage($to, $message);
453474
return;
@@ -525,6 +546,7 @@ private function executeValidation(object $validation, ConnectionInterface $to)
525546
$this->sendMessage($to, $message);
526547
}
527548
} else {
549+
// If the 'sourceFolder' property is not set, then we are validating a single source file or API path
528550
$matches = null;
529551
if (preg_match("/^diocesan-calendar-([a-z]{6}_[a-z]{2})$/", $pathForSchema, $matches)) {
530552
$dioceseId = $matches[1];
@@ -543,6 +565,8 @@ private function executeValidation(object $validation, ConnectionInterface $to)
543565
]);
544566
}
545567

568+
// If we are validating an API path, we check for a 200 OK HTTP response from the API
569+
// rather than checking for existence of the file in the filesystem
546570
if ($validation->category === 'resourceDataCheck') {
547571
$headers = get_headers($dataPath);
548572
if (!$headers || strpos($headers[0], '200') === false) {
@@ -563,12 +587,32 @@ private function executeValidation(object $validation, ConnectionInterface $to)
563587
$message->text = "Unable to verify schema for dataPath {$dataPath} and category {$validation->category} since Data file $dataPath does not exist or is not readable";
564588
$message->classes = ".$validation->validate.schema-valid";
565589
$this->sendMessage($to, $message);
566-
590+
// early exit
567591
return;
568592
}
569593
}
570594

571-
$data = file_get_contents($dataPath);
595+
$data = false;
596+
if (property_exists($validation, 'responsetype')) {
597+
$responseType = $validation->responsetype;
598+
//get the index of the responsetype from the ReturnType class
599+
$responseTypeIdx = array_search($responseType, ReturnType::$values);
600+
//get the corresponding accept mime type
601+
$acceptMimeType = AcceptHeader::$values[$responseTypeIdx];
602+
$opts = [
603+
"http" => [
604+
"method" => "GET",
605+
"header" => "Accept: $acceptMimeType\r\n"
606+
]
607+
];
608+
$context = stream_context_create($opts);
609+
// $dataPath is probably an API path in this case
610+
$data = file_get_contents($dataPath, false, $context);
611+
} else {
612+
// $dataPath is probably a source file in the filesystem in this case
613+
$data = file_get_contents($dataPath);
614+
}
615+
572616
if (false === $data) {
573617
$message = new \stdClass();
574618
$message->type = "error";
@@ -594,39 +638,83 @@ private function executeValidation(object $validation, ConnectionInterface $to)
594638
$message->classes = ".$validation->validate.file-exists";
595639
$this->sendMessage($to, $message);
596640

597-
$jsonData = json_decode($data);
598-
if (json_last_error() === JSON_ERROR_NONE) {
599-
$message = new \stdClass();
600-
$message->type = "success";
601-
$message->text = "The Data file $dataPath was successfully decoded as JSON";
602-
$message->classes = ".$validation->validate.json-valid";
603-
$this->sendMessage($to, $message);
641+
switch ($responseType) {
642+
case 'YML':
643+
try {
644+
$yamlData = json_decode(json_encode(yaml_parse($data)));
645+
if ($yamlData) {
646+
$message = new \stdClass();
647+
$message->type = "success";
648+
$message->text = "The Data file $dataPath was successfully decoded as YAML";
649+
$message->classes = ".$validation->validate.json-valid";
650+
$this->sendMessage($to, $message);
604651

605-
if (null !== $schema) {
606-
$validationResult = $this->validateDataAgainstSchema($jsonData, $schema);
607-
if (gettype($validationResult) === 'boolean' && $validationResult === true) {
652+
if (null !== $schema) {
653+
$validationResult = $this->validateDataAgainstSchema($yamlData, $schema);
654+
if (gettype($validationResult) === 'boolean' && $validationResult === true) {
655+
$message = new \stdClass();
656+
$message->type = "success";
657+
$message->text = "The Data file $dataPath was successfully validated against the Schema $schema";
658+
$message->classes = ".$validation->validate.schema-valid";
659+
$this->sendMessage($to, $message);
660+
} elseif (gettype($validationResult === 'object')) {
661+
$validationResult->classes = ".$validation->validate.schema-valid";
662+
$this->sendMessage($to, $validationResult);
663+
}
664+
} else {
665+
$message = new \stdClass();
666+
$message->type = "error";
667+
$message->text = "Unable to detect schema for dataPath {$dataPath} and category {$validation->category}";
668+
$message->classes = ".$validation->validate.schema-valid";
669+
$this->sendMessage($to, $message);
670+
}
671+
}
672+
} catch (\Exception $ex) {
673+
$message = new \stdClass();
674+
$message->type = "error";
675+
$message->text = "There was an error decoding the Data file $dataPath as YAML: " . $ex->getMessage() . " :: Raw data = <<<JSON\n$data\n>>>";
676+
$message->classes = ".$validation->validate.json-valid";
677+
$this->sendMessage($to, $message);
678+
}
679+
break;
680+
case 'JSON':
681+
// no break
682+
default:
683+
$jsonData = json_decode($data);
684+
if (json_last_error() === JSON_ERROR_NONE) {
608685
$message = new \stdClass();
609686
$message->type = "success";
610-
$message->text = "The Data file $dataPath was successfully validated against the Schema $schema";
611-
$message->classes = ".$validation->validate.schema-valid";
687+
$message->text = "The Data file $dataPath was successfully decoded as JSON";
688+
$message->classes = ".$validation->validate.json-valid";
689+
$this->sendMessage($to, $message);
690+
691+
if (null !== $schema) {
692+
$validationResult = $this->validateDataAgainstSchema($jsonData, $schema);
693+
if (gettype($validationResult) === 'boolean' && $validationResult === true) {
694+
$message = new \stdClass();
695+
$message->type = "success";
696+
$message->text = "The Data file $dataPath was successfully validated against the Schema $schema";
697+
$message->classes = ".$validation->validate.schema-valid";
698+
$this->sendMessage($to, $message);
699+
} elseif (gettype($validationResult === 'object')) {
700+
$validationResult->classes = ".$validation->validate.schema-valid";
701+
$this->sendMessage($to, $validationResult);
702+
}
703+
} else {
704+
$message = new \stdClass();
705+
$message->type = "error";
706+
$message->text = "Unable to detect schema for dataPath {$dataPath} and category {$validation->category}";
707+
$message->classes = ".$validation->validate.schema-valid";
708+
$this->sendMessage($to, $message);
709+
}
710+
} else {
711+
$message = new \stdClass();
712+
$message->type = "error";
713+
$message->text = "There was an error decoding the Data file $dataPath as JSON: " . json_last_error_msg() . " :: Raw data = <<<JSON\n$data\n>>>";
714+
$message->classes = ".$validation->validate.json-valid";
612715
$this->sendMessage($to, $message);
613-
} elseif (gettype($validationResult === 'object')) {
614-
$validationResult->classes = ".$validation->validate.schema-valid";
615-
$this->sendMessage($to, $validationResult);
616716
}
617-
} else {
618-
$message = new \stdClass();
619-
$message->type = "error";
620-
$message->text = "Unable to detect schema for dataPath {$dataPath} and category {$validation->category}";
621-
$message->classes = ".$validation->validate.schema-valid";
622-
$this->sendMessage($to, $message);
623-
}
624-
} else {
625-
$message = new \stdClass();
626-
$message->type = "error";
627-
$message->text = "There was an error decoding the Data file $dataPath as JSON: " . json_last_error_msg() . " :: Raw data = <<<JSON\n$data\n>>>";
628-
$message->classes = ".$validation->validate.json-valid";
629-
$this->sendMessage($to, $message);
717+
break;
630718
}
631719
}
632720
}

src/Paths/Events.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,9 @@ private function produceResponse(): void
708708
} else {
709709
switch (self::$Core->getResponseContentType()) {
710710
case AcceptHeader::YAML:
711+
// We must make sure that any nested stdClass objects are converted to associative arrays
712+
$responseStr = json_encode($responseObj);
713+
$responseObj = json_decode($responseStr, true);
711714
echo yaml_emit($responseObj, YAML_UTF8_ENCODING);
712715
break;
713716
case AcceptHeader::JSON:

src/Paths/Metadata.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ public static function response()
254254
} else {
255255
echo $response;
256256
}
257+
die();
257258
}
258259

259260
/**

0 commit comments

Comments
 (0)