leilukin-tumbleblog/includes/lib/JSONFeed.php

246 lines
6.8 KiB
PHP
Raw Permalink Normal View History

2024-06-20 14:10:42 +00:00
<?php
/**
* Class: JSONFeed
* Generates a JSON feed piece by piece.
*
* See Also:
* https://jsonfeed.org/version/1.1
*/
class JSONFeed implements FeedGenerator {
# Boolean: $open
# Has the feed been opened?
protected $open = false;
# Variable: $count
# The number of items generated.
protected $count = 0;
# Array: $json
# Holds the feed as a $key => $val array.
protected $json = array();
/**
* Function: type
* Returns the content type of the feed.
*/
public static function type(): string {
return "application/feed+json";
}
/**
* Function: open
* Adds the top-level feed objects.
*
* Parameters:
* $title - Title for this feed.
* $subtitle - Subtitle (optional).
* $id - Feed ID (optional).
* $updated - Time of update (optional).
*/
public function open(
$title,
$subtitle = "",
$id = "",
$updated = null
): bool {
if ($this->open)
return false;
$language = lang_base(Config::current()->locale);
$this->json = array(
"version" => "https://jsonfeed.org/version/1.1",
"language" => $language,
"title" => strip_tags($title),
"home_page_url" => url("/", MainController::current()),
"feed_url" => unfix(self_url())
);
if (!empty($subtitle))
$this->json["description"] = strip_tags($subtitle);
$this->json["items"] = array();
return $this->open = true;
}
/**
* Function: entry
* Adds an individual feed item.
*
* Parameters:
* $title - Title for this item.
* $id - The unique ID.
* $content - Content for this item.
* $link - The URL to the resource.
* $published - Time of creation.
* $updated - Time of update (optional).
* $name - Name of the author (optional).
* $uri - URI of the author (optional).
* $email - Email address of the author (optional).
*/
public function entry(
$title,
$id,
$content,
$link,
$published,
$updated = null,
$name = "",
$uri = "",
$email = ""
): bool {
if (!$this->open)
return false;
$this->count++;
$entry = array(
"id" => $id,
"url" => $link,
"title" => strip_tags($title),
"content_html" => $content,
"date_published" => when(DATE_RFC3339, $published),
"date_modified" => when(DATE_RFC3339, oneof($updated, $published)),
"authors" => array(array("name" => oneof($name, __("Guest"))))
);
if (!empty($uri) and is_url($uri))
$entry["author"]["url"] = $uri;
$item = $this->count - 1;
$this->json["items"][$item] = $entry;
return true;
}
/**
* Function: category
* Adds a tag object for an item.
*
* Parameters:
* $term - String that identifies the category.
* $scheme - URI for the categorization scheme (optional).
* $label - Human-readable label for the category (optional).
*/
public function category(
$term,
$scheme = "",
$label = ""
): bool {
if (!$this->open)
return false;
if (!$this->count)
return false;
$item = $this->count - 1;
fallback(
$this->json["items"][$item]["tags"],
array()
);
$this->json["items"][$item]["tags"][] = $term;
return true;
}
/**
* Function: rights
* Not implemented in JSON Feed version 1.
*/
public function rights($text): bool {
return false;
}
/**
* Function: enclosure
* Adds an attachment object for an item.
*
* Parameters:
* $link - The URL to the resource.
* $length - Size in bytes of the resource (optional).
* $type - The media type of the resource (optional).
* $title - Title for the resource (optional).
*/
public function enclosure(
$link,
$length = null,
$type = "",
$title = ""
): bool {
if (!$this->open)
return false;
if (!$this->count)
return false;
$item = $this->count - 1;
fallback(
$this->json["items"][$item]["attachments"],
array()
);
$attachment = array(
"url" => $link,
"mime_type" => oneof($type, "application/octet-stream")
);
if (!empty($length))
$attachment["size_in_bytes"] = $length;
if (!empty($title))
$attachment["title"] = $title;
$this->json["items"][$item]["attachments"][] = $attachment;
return true;
}
/**
* Function: related
* Adds an external_url attribute for an item.
*
* Parameters:
* $link - The external URL.
*/
public function related($link): bool {
if (!$this->open)
return false;
if (!$this->count)
return false;
if (empty($link) or !is_url($link))
return false;
$item = $this->count - 1;
$this->json["items"][$item]["external_url"] = $link;
return true;
}
/**
* Function: feed
* Returns the generated feed.
*/
public function feed(): string {
$encoded = json_set(
$this->json,
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
);
return ($encoded === false) ? "" : $encoded ;
}
/**
* Function: output
* Displays the generated feed.
*/
public function display(): bool {
if (headers_sent())
return false;
header("Content-Type: ".self::type()."; charset=UTF-8");
echo $this->feed();
return true;
}
}