diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 34b10d53..32a06c5e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,13 +22,13 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Check-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Update source file translation strings id: update_pot run: | sudo apt-get install -y gettext - xgettext --from-code=UTF-8 --add-comments='translators:' --keyword="pgettext:1c,2" -o i18n/litcal.pot includes/AnniversaryCalculator.php includes/LitEvent.php includes/enums/AnnivType.php includes/enums/AreaInterest.php includes/enums/LitCalendar.php + xgettext --from-code=UTF-8 --add-comments='translators:' --keyword="pgettext:1c,2" -o i18n/litcal.pot src/AnniversaryCalculator.php src/AnniversaryCalculator/LitEvent.php src/AnniversaryCalculator/Enums/AnnivType.php src/AnniversaryCalculator/Enums/AreaInterest.php src/AnniversaryCalculator/Enums/LitCalendar.php echo "POT_LINES_CHANGED=$(git diff -U0 | grep '^[+|-][^+|-]' | grep -Ev '^[+-]"POT-Creation-Date' | wc -l)" >> $GITHUB_OUTPUT # push the output folder to your repo diff --git a/index.php b/index.php index f7834d30..bb4724f6 100644 --- a/index.php +++ b/index.php @@ -2,6 +2,9 @@ use LitCal\AnniversaryCalculator; +// error_reporting(E_ALL); +// ini_set('display_errors', 1); +ini_set('date.timezone', 'Europe/Vatican'); require_once 'vendor/autoload.php'; $calculator = new AnniversaryCalculator(); diff --git a/src/AnniversaryCalculator.php b/src/AnniversaryCalculator.php index 744ab870..2592c816 100644 --- a/src/AnniversaryCalculator.php +++ b/src/AnniversaryCalculator.php @@ -94,14 +94,17 @@ private function initParameterData() if (null === $rawJson || "" === $rawJson) { header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad Request", true, 400); $response = new \stdClass(); - $response->error = "No JSON data received in the request: <$rawJson>"; + $response->error = _("No JSON data received in the request"); die(json_encode($response)); } $data = json_decode($rawJson, true); if (json_last_error() !== JSON_ERROR_NONE) { header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad Request", true, 400); $response = new \stdClass(); - $response->error = "Malformed JSON data received in the request: <$rawJson>, " . json_last_error_msg(); + $response->error = sprintf( + _('Malformed JSON data received in the request: %s'), + json_last_error_msg() + ); die(json_encode($response)); } else { $this->parameterData = $data; @@ -111,7 +114,7 @@ private function initParameterData() if ("" === $rawYaml) { header($_SERVER[ "SERVER_PROTOCOL" ] . " 400 Bad Request", true, 400); $response = new \stdClass(); - $response->error = "No YAML data received in the request"; + $response->error = _("No YAML data received in the request"); die(json_encode($response)); } @@ -121,7 +124,7 @@ private function initParameterData() if (false === $data) { header($_SERVER[ "SERVER_PROTOCOL" ] . " 400 Bad Request", true, 400); $response = new \stdClass(); - $response->error = "Malformed YAML data received in the request"; + $response->error = _("Malformed YAML data received in the request"); die(json_encode($response)); } else { $this->parameterData = $data; @@ -129,51 +132,81 @@ private function initParameterData() } catch (\Exception $e) { header($_SERVER[ "SERVER_PROTOCOL" ] . " 400 Bad Request", true, 400); $response = new \stdClass(); - $response->status = "error"; - $response->message = "Malformed YAML data received in the request"; - $response->error = $e->getMessage(); - $response->line = $e->getLine(); - $response->code = $e->getCode(); + $response->error = sprintf( + _("Malformed YAML data received in the request: %s"), + $e->getMessage() + ); die(json_encode($response)); } } else { switch (strtoupper($_SERVER["REQUEST_METHOD"])) { case 'POST': + $_POST = array_change_key_case($_POST, CASE_UPPER); $this->parameterData = $_POST; break; case 'GET': + $_GET = array_change_key_case($_GET, CASE_UPPER); $this->parameterData = $_GET; break; default: header($_SERVER["SERVER_PROTOCOL"] . " 405 Method Not Allowed", true, 405); - $errorMessage = '{"error":"You seem to be forming a strange kind of request? Allowed Request Methods are '; - $errorMessage .= implode(' and ', self::ALLOWED_REQUEST_METHODS); - $errorMessage .= ', but your Request Method was ' . strtoupper($_SERVER['REQUEST_METHOD']) . '"}'; - die($errorMessage); + $response = new \stdClass(); + $response->status = "error"; + $response->message = sprintf( + _('Allowed request methods are: %1$s; but request method was \'%2$s\''), + implode(', ', self::ALLOWED_REQUEST_METHODS), + strtoupper($_SERVER['REQUEST_METHOD']) + ); + die(json_encode($response)); } } if (!isset($this->parameterData["YEAR"]) || $this->parameterData["YEAR"] === "") { $this->parameterData["YEAR"] = (int)date("Y"); } + $this->RESPONSE->Messages[] = sprintf( + _('Year set to %d'), + $this->parameterData["YEAR"] + ); - if (isset($this->parameterData["LOCALE"]) && in_array(strtolower($this->parameterData["LOCALE"]), self::ALLOWED_LOCALES)) { - $this->parameterData["LOCALE"] = strtolower($this->parameterData["LOCALE"]); + if (isset($this->parameterData["LOCALE"]) && $this->parameterData["LOCALE"] !== '') { + $this->parameterData["LOCALE"] = \Locale::canonicalize($this->parameterData["LOCALE"]); + $this->parameterData["BASE_LOCALE"] = \Locale::getPrimaryLanguage($this->parameterData["LOCALE"]); + if (false === in_array($this->parameterData["BASE_LOCALE"], self::ALLOWED_LOCALES)) { + $this->parameterData["LOCALE"] = "en_US"; + $this->parameterData["BASE_LOCALE"] = \Locale::getPrimaryLanguage($this->parameterData["LOCALE"]); + $this->RESPONSE->Messages[] = sprintf( + _('Allowed base locales are: \'%1$s\'; but base locale requested was \'%2$s\''), + implode(', ', self::ALLOWED_LOCALES), + $this->parameterData["BASE_LOCALE"] + ); + } } else { - $this->parameterData["LOCALE"] = "en"; + $this->parameterData["LOCALE"] = "en_US"; + $this->parameterData["BASE_LOCALE"] = \Locale::getPrimaryLanguage($this->parameterData["LOCALE"]); } + $this->RESPONSE->Messages[] = sprintf( + _('Locale set to \'%1$s\', base locale set to \'%2$s\''), + $this->parameterData["LOCALE"], + $this->parameterData["BASE_LOCALE"] + ); $this->responseContentType = ( - isset($this->parameterData["return"]) - && in_array(strtolower($this->parameterData["return"]), self::ALLOWED_RETURN_TYPES) + isset($this->parameterData["RETURN"]) + && in_array(strtolower($this->parameterData["RETURN"]), self::ALLOWED_RETURN_TYPES) ) - ? strtolower($this->parameterData["return"]) + ? strtolower($this->parameterData["RETURN"]) : ( $this->acceptHeader !== "" ? (string) self::ALLOWED_RETURN_TYPES[array_search($this->requestHeaders["Accept"], self::ALLOWED_ACCEPT_HEADERS)] : (string) self::ALLOWED_RETURN_TYPES[0] ); - $this->RESPONSE->Messages[] = "parameter data initialized"; + $this->RESPONSE->Messages[] = sprintf( + _('Return parameter set to \'%1$s\', response content type set to \'%2$s\''), + $this->parameterData["RETURN"], + $this->responseContentType + ); + $this->RESPONSE->Messages[] = _("parameter data initialized"); } private static function warningHandler($errno, $errstr) @@ -184,10 +217,12 @@ private static function warningHandler($errno, $errstr) private function prepareL10N(): void { $localeArray = [ - $this->parameterData["LOCALE"] . '_' . strtoupper($this->parameterData["LOCALE"]) . '.utf8', - $this->parameterData["LOCALE"] . '_' . strtoupper($this->parameterData["LOCALE"]) . '.UTF-8', - $this->parameterData["LOCALE"] . '_' . strtoupper($this->parameterData["LOCALE"]), - $this->parameterData["LOCALE"] + $this->parameterData["LOCALE"] . '.utf8', + $this->parameterData["LOCALE"] . '.UTF-8', + $this->parameterData["BASE_LOCALE"] . '_' . strtoupper($this->parameterData["BASE_LOCALE"]) . '.utf8', + $this->parameterData["BASE_LOCALE"] . '_' . strtoupper($this->parameterData["BASE_LOCALE"]) . '.UTF-8', + $this->parameterData["LOCALE"], + $this->parameterData["BASE_LOCALE"] . '_' . strtoupper($this->parameterData["BASE_LOCALE"]) ]; setlocale(LC_ALL, $localeArray); bindtextdomain("litcal", "i18n"); @@ -196,38 +231,53 @@ private function prepareL10N(): void private function setReponseContentTypeHeader() { + $header = ''; switch ($this->responseContentType) { case "xml": - header('Content-Type: application/xml; charset=utf-8'); + $header = 'Content-Type: application/xml; charset=utf-8'; break; case "json": - header('Content-Type: application/json; charset=utf-8'); + $header = 'Content-Type: application/json; charset=utf-8'; break; case "yaml": - header('Content-Type: application/yaml; charset=utf-8'); + $header = 'Content-Type: application/yaml; charset=utf-8'; break; case "html": - header('Content-Type: text/html; charset=utf-8'); + $header = 'Content-Type: text/html; charset=utf-8'; break; default: - header('Content-Type: application/json; charset=utf-8'); + $header = 'Content-Type: application/json; charset=utf-8'; } - $this->RESPONSE->Messages[] = "Response Content-Type header set"; + header($header); + $this->RESPONSE->Messages[] = sprintf( + _("Response Content-Type header set to '%s'"), + $header + ); } private function readData() { - if (file_exists("./data/LITURGY__anniversari.json")) { - if (file_exists("./data/i18n/{$this->parameterData["LOCALE"]}.json")) { - $lclData = json_decode(file_get_contents("./data/i18n/{$this->parameterData["LOCALE"]}.json")); - $results = json_decode(file_get_contents("./data/LITURGY__anniversari.json")); - $this->RESPONSE->Messages[] = "localized data events loaded: " . count(get_object_vars($lclData)); - $this->RESPONSE->Messages[] = "base data events loaded: " . count($results); + $dataFile = "data/LITURGY__anniversari.json"; + $translationFile = "data/i18n/{$this->parameterData["BASE_LOCALE"]}.json"; + if (file_exists($dataFile)) { + if (file_exists($translationFile)) { + $lclData = json_decode(file_get_contents($translationFile)); + $results = json_decode(file_get_contents($dataFile)); + $this->RESPONSE->Messages[] = sprintf( + _("%d localized data events loaded from translation file %s"), + count(get_object_vars($lclData)), + $translationFile + ); + $this->RESPONSE->Messages[] = sprintf( + _("%d events loaded from data file %s"), + count($results), + $dataFile + ); foreach ($lclData as $label => $lclRow) { list( $TAG, $IDX ) = explode("_", $label); foreach ($results as $idx => $obj) { if ($obj->TAG === $TAG && $obj->IDX === intval($IDX)) { - $litEvent = new LitEvent(array_merge((array) $results[$idx], (array) $lclRow), $this->parameterData["LOCALE"]); + $litEvent = new LitEvent(array_merge((array) $results[$idx], (array) $lclRow)); if ($litEvent->year !== null && $this->isAnniversary($litEvent)) { $this->RESPONSE->LitEvents[] = $litEvent; } @@ -249,12 +299,21 @@ private function readData() return 0; }); } - $this->RESPONSE->Messages[] = count($this->RESPONSE->LitEvents) . " data rows calculated"; + $this->RESPONSE->Messages[] = sprintf( + _("%d data rows calculated"), + count($this->RESPONSE->LitEvents) + ); } else { - $this->RESPONSE->Messages[] = "missing file ./data/i18n/{$this->parameterData["LOCALE"]}.json"; + $this->RESPONSE->Messages[] = sprintf( + _("missing translation file: %s"), + $translationFile + ); } } else { - $this->RESPONSE->Messages[] = "missing file ./data/LITURGY__anniversari.json"; + $this->RESPONSE->Messages[] = sprintf( + _("missing data file: %s"), + $dataFile + ); } } diff --git a/src/AnniversaryCalculator/Enums/AnnivType.php b/src/AnniversaryCalculator/Enums/AnnivType.php index d98b22a2..5167fcf5 100644 --- a/src/AnniversaryCalculator/Enums/AnnivType.php +++ b/src/AnniversaryCalculator/Enums/AnnivType.php @@ -12,16 +12,14 @@ class AnnivType public const TRANSLATION = "translation"; public const DOGMA = "dogma"; public const OTHER = "other"; - //private string $locale; private array $GTXT; public static array $values = [ "birth", "death", "canonization", "doctor", "dedication", "translation", "dogma", "other" ]; - public function __construct(string $locale) + public function __construct() { - //$this->locale = strtoupper( $locale ); $this->GTXT = [ self::BIRTH => strtoupper(_("birth")), self::DEATH => strtoupper(_("death")), @@ -29,7 +27,8 @@ public function __construct(string $locale) self::DOCTOR => strtoupper(_("doctor")), self::DEDICATION => strtoupper(_("dedication")), /**translators: term "translation" refers to the transferral of the relics of a saint */ - self::TRANSLATION => strtoupper(_("translation")), + self::TRANSLATION => strtoupper(_("translation")), + self::DOGMA => strtoupper(_("dogma")), self::OTHER => strtoupper(_("other")) ]; } diff --git a/src/AnniversaryCalculator/Enums/AreaInterest.php b/src/AnniversaryCalculator/Enums/AreaInterest.php index 1e918b37..9e8316a1 100644 --- a/src/AnniversaryCalculator/Enums/AreaInterest.php +++ b/src/AnniversaryCalculator/Enums/AreaInterest.php @@ -9,16 +9,14 @@ class AreaInterest public const WORLD = "world"; // IRC public const BIBLICAL = "biblical"; // BIBLICI public const MARIAN = "marian"; // MARIANI - //private string $locale; private array $GTXT; public static array $values = [ "rome", "italy", "world", "biblical", "marian" ]; - public function __construct(string $locale) + public function __construct() { - //$this->locale = strtoupper( $locale ); $this->GTXT = [ self::ROME => strtoupper(_("rome")), self::ITALY => strtoupper(_("italy")), diff --git a/src/AnniversaryCalculator/Enums/LitCalendar.php b/src/AnniversaryCalculator/Enums/LitCalendar.php index 9ad2c7df..0df76142 100644 --- a/src/AnniversaryCalculator/Enums/LitCalendar.php +++ b/src/AnniversaryCalculator/Enums/LitCalendar.php @@ -8,16 +8,14 @@ class LitCalendar public const NATIONAL = "national"; public const DIOCESAN = "diocesan"; public const WIDE_AREA = "wide_area"; - //private string $locale; private array $GTXT; public static array $values = [ "universal", "national", "diocesan", "wide_area" ]; - public function __construct(string $locale) + public function __construct() { - //$this->locale = strtoupper( $locale ); $this->GTXT = [ self::UNIVERSAL => strtoupper(_("universal")), self::NATIONAL => strtoupper(_("national")), diff --git a/src/AnniversaryCalculator/LitEvent.php b/src/AnniversaryCalculator/LitEvent.php index 243456ed..f405887d 100644 --- a/src/AnniversaryCalculator/LitEvent.php +++ b/src/AnniversaryCalculator/LitEvent.php @@ -52,15 +52,39 @@ class LitEvent public array $areaOfInterest; public ?string $notes; public ?string $anniversary; + public ?string $anniversaryLcl; public ?string $patronage; public int $yearDiff; + private array $GTXT; - public function __construct(array $rowData, string $locale) + public function __construct(array $rowData) { - $AnnivType = new AnnivType($locale); - $AreaInterest = new AreaInterest($locale); - $LitCalendar = new LitCalendar($locale); - + $AnnivType = new AnnivType(); + $AreaInterest = new AreaInterest(); + $LitCalendar = new LitCalendar(); + $this->GTXT = [ + "CENTENARY" => _("CENTENARY"), + "ONYX" => _("ONYX"), + "GRANITE" => _("GRANITE"), + "MARBLE" => _("MARBLE"), + "OAK" => _("OAK"), + "PLATINUM" => _("PLATINUM"), + "IRON" => _("IRON"), + "STONE" => _("STONE"), + "DIAMOND" => _("DIAMOND"), + "EMERALD" => _("EMERALD"), + "GOLD" => _("GOLD"), + "SAPPHIRE" => _("SAPPHIRE"), + "RUBY" => _("RUBY"), + "CORAL" => _("CORAL"), + "PEARL" => _("PEARL"), + "SILVER" => _("SILVER"), + "PORCELAIN" => _("PORCELAIN"), + "CRISTAL" => _("CRISTAL"), + "ALUMINUM" => _("ALUMINUM"), + "WOOD" => _("WOOD"), + "PAPER" => _("PAPER") + ]; $this->idx = $rowData["IDX"]; $this->tag = $rowData["TAG"]; @@ -85,6 +109,7 @@ public function __construct(array $rowData, string $locale) public function setAnniversary(int $anniv) { $this->anniversary = array_search($anniv, self::ANNIVERSARY); + $this->anniversaryLcl = $this->GTXT[ $this->anniversary ]; } public function setYearDiff(int $yearDiff)