Skip to content

Commit

Permalink
add docblocks
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnRDOrazio committed Oct 5, 2024
1 parent 5f08bf5 commit 73b65d4
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 11 deletions.
12 changes: 6 additions & 6 deletions src/LitCalFeedItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ class LitCalFeedItem implements \JsonSerializable
public string $mainText;
public string $redirectionUrl;
public string $updateDate;
public ?string $smml = null;
public ?string $ssml = null;

public function __construct(string $key, Festivity $festivity, \DateTime $publishDate, string $titleText, string $mainText, ?string $smml)
public function __construct(string $key, Festivity $festivity, \DateTime $publishDate, string $titleText, string $mainText, ?string $ssml = null)
{
$this->uid = "urn:uuid:" . md5("LITCAL-" . $key . '-' . $festivity->date->format('Y'));
$this->updateDate = $publishDate->format("Y-m-d\TH:i:s\Z");
$this->titleText = $titleText;
if (null !== $smml) {
$this->smml = $smml;
if (null !== $ssml) {
$this->ssml = $ssml;
}
$this->mainText = $mainText;
$this->redirectionUrl = "https://litcal.johnromanodorazio.com/";
}

public function jsonSerialize(): array
{
if (null === $this->smml) {
unset($this->smml);
if (null === $this->ssml) {
unset($this->ssml);
}
return get_object_vars($this);
}
Expand Down
113 changes: 108 additions & 5 deletions src/LiturgyOfTheDay.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@
use LiturgicalCalendar\AlexaNewsBrief\Festivity;
use LiturgicalCalendar\AlexaNewsBrief\LitCalFeedItem;

/**
* The LiturgyOfTheDay class is the main class of the Liturgical Calendar Alexa News Brief.
*
* It fetches metadata about all available calendars from the Liturgical Calendar API and
* initialize the LiturgyOfTheDay object with the locale from the
* GET parameter "locale". If the GET parameter "nationalcalendar" is
* set, use it to set the national calendar and the locale. If the GET
* parameter "diocesancalendar" is set, use it to set the diocesan
* calendar, national calendar, and the locale. If the GET parameter
* "timezone" is set, use it to set the timezone.
*
* It also sets up the locale and gettext translation environment.
*
* It fetches the liturgical data for the given locale and calendar from the Liturgical Calendar API
* and stores the "litcal" array in $this->LitCalData.
*
* It then filters out only the events for today and converts each of these events into a Festivity object,
* and calls prepareMainText to generate the main text and optional SSML for each event. Finally, it creates a new
* LitCalFeedItem for each event and adds it to the $this->LitCalFeed array.
*/
class LiturgyOfTheDay
{
private const METADATA_URL = 'https://litcal.johnromanodorazio.com/api/dev/calendars';
Expand All @@ -28,6 +48,19 @@ class LiturgyOfTheDay
'/Blessed( Virgin Mary)/' => '<phoneme alphabet="ipa" ph="ˈblɛsɪd">Blessed</phoneme>$1',
];

/**
* Construct the Liturgy of the Day object.
*
* Fetches metadata about all available calendars from the Liturgical Calendar API and
* initialize the LiturgyOfTheDay object with the locale from the
* GET parameter "locale". If the GET parameter "nationalcalendar" is
* set, use it to set the national calendar and the locale. If the GET
* parameter "diocesancalendar" is set, use it to set the diocesan
* calendar, national calendar, and the locale. If the GET parameter
* "timezone" is set, use it to set the timezone.
*
* @throws \Exception
*/
public function __construct()
{
$this->sendMetadataReq();
Expand Down Expand Up @@ -77,6 +110,17 @@ public function __construct()
}
}

/**
* Sets up the locale and gettext translation environment.
*
* We set the locale to either $this->Locale or the language part of $this->Locale (which is the locale
* from the national calendar if applicable, Latin otherwise), since the national calendar locale is the
* actual locale used for the translations. The country code shouldn't be too
* relevant for the translations.
*
* We also set up the gettext translation environment, which is used to
* translate the texts for the liturgical day.
*/
private function prepareL10N(): void
{
$this->baseLocale = \Locale::getPrimaryLanguage($this->Locale);
Expand All @@ -96,6 +140,16 @@ private function prepareL10N(): void
$this->monthDayFmt = \IntlDateFormatter::create($this->Locale, \IntlDateFormatter::FULL, \IntlDateFormatter::FULL, 'UTC', \IntlDateFormatter::GREGORIAN, 'd MMMM');
}

/**
* Sends a request to the Liturgical Calendar API's /calendars path to retrieve
* metadata about all available liturgical calendars.
*
* If the request fails, it will die with an error message.
*
* If the request succeeds, it will decode the JSON response
* and store the "litcal_metadata" array in $this->LitCalMetadata.
* @throws \Exception
*/
private function sendMetadataReq(): void
{
$ch = curl_init(self::METADATA_URL);
Expand Down Expand Up @@ -126,6 +180,20 @@ private function sendMetadataReq(): void
}


/**
* @throws \Exception
*/
/**
* Sends a request to the calendar API at $this->CalendarURL
* with the query parameters $this->queryParams, with the
* Accept-Language header set to $this->Locale and the
* Accept header set to application/json.
*
* If the request fails, it will die with an error message.
*
* If the request succeeds, it will decode the JSON response
* and store the "litcal" array in $this->LitCalData.
*/
private function sendReq()
{
$ch = curl_init();
Expand Down Expand Up @@ -161,6 +229,12 @@ private function sendReq()
curl_close($ch);
}

/**
* This function takes the LitCal data and filters out only the events for today.
* It then converts each of these events into a Festivity object, and calls prepareMainText
* to generate the main text and optional SSML for each event. Finally, it creates a new LitCalFeedItem
* for each event and adds it to the $this->LitCalFeed array.
*/
private function filterEventsToday()
{
$dateTimeToday = ( new \DateTime('now') )->format("Y-m-d") . " 00:00:00";
Expand All @@ -176,23 +250,33 @@ private function filterEventsToday()
// retransform each entry from an associative array to a Festivity class object
$festivity = new Festivity($value);
$festivity->tag = $key;
["mainText" => $mainText, "smml" => $smml] = $this->prepareMainText($festivity, $idx);
["mainText" => $mainText, "ssml" => $ssml] = $this->prepareMainText($festivity, $idx);
$titleText = _("Liturgy of the Day") . " ";
if ($this->baseLocale === LitLocale::ENGLISH) {
$titleText .= $festivity->date->format('F jS');
} else {
$titleText .= $this->monthDayFmt->format($festivity->date->format('U'));
}
$this->LitCalFeed[] = new LitCalFeedItem($key, $festivity, $publishDate, $titleText, $mainText, $smml);
$this->LitCalFeed[] = new LitCalFeedItem($key, $festivity, $publishDate, $titleText, $mainText, $ssml);
$idx++;
}
}
}

/**
* Prepares the main text for a given Festivity, given its index in the LitCalFeed array.
*
* This function takes into account the grade of the festivity and its relative position in the LitCalFeed array and returns
* a string that can be used as the main text for that festivity.
*
* @param Festivity $festivity The Festivity to generate the main text for.
* @param int $idx The index of the Festivity in the LitCalFeed array.
* @return array A two-element array containing the main text and the SSML string, if any.
*/
private function prepareMainText(Festivity $festivity, int $idx): array
{
$mainText = "";
$smml = null;
$ssml = null;
//Situations in which we don't need to actually state "Feast of the Lord":
$filterTagsDisplayGrade = [
"/OrdSunday[0-9]{1,2}(_vigil){0,1}/",
Expand Down Expand Up @@ -286,13 +370,19 @@ private function prepareMainText(Festivity $festivity, int $idx): array
//Fix some phonetic pronunciations
foreach (LiturgyOfTheDay::PHONETIC_PRONUNCATION_MAPPING as $key => $value) {
if (preg_match($key, $mainText) === 1) {
$smml = "<speak>" . preg_replace($key, $value, $mainText) . "</speak>";
$ssml = "<speak>" . preg_replace($key, $value, $mainText) . "</speak>";
}
}
}
return ["mainText" => $mainText, "smml" => $smml];
return ["mainText" => $mainText, "ssml" => $ssml];
}

/**
* Determines if the given timezone is valid.
*
* @param string $timezone
* @return boolean
*/
private function isValidTimezone($timezone)
{
if (in_array($timezone, \DateTimeZone::listIdentifiers())) {
Expand All @@ -301,6 +391,14 @@ private function isValidTimezone($timezone)
return false;
}

/**
* Sends the Alexa Flash Briefing response.
*
* This method will send either a single JSON object or an array of JSON objects, depending on the number of Festivity objects
* in the LitCalFeed array. If the LitCalFeed array contains only one Festivity, it will send the JSON representation of the
* single Festivity. If the LitCalFeed array contains more than one Festivity, it will send the JSON representation of the
* LitCalFeed array itself.
*/
private function sendResponse()
{
header('Content-Type: application/json');
Expand All @@ -311,6 +409,11 @@ private function sendResponse()
}
}

/**
* Initializes the LiturgicalCalendar\AlexaNewsBrief\LiturgyOfTheDay object.
*
* This method will call the other methods in the correct order to generate and send the Alexa Flash Briefing response.
*/
public function init()
{
$this->sendReq();
Expand Down

0 comments on commit 73b65d4

Please sign in to comment.