1
0
mirror of https://github.com/php/web-php.git synced 2026-03-23 23:02:13 +01:00

Refactor bin/createNewsEntry

This commit is contained in:
Sara Golemon
2019-07-10 12:09:48 -04:00
parent 0c795445aa
commit 464ff738ba

View File

@@ -1,9 +1,110 @@
#!/usr/bin/env php
<?php
PHP_SAPI == 'cli' or die("Please run this script using the cli sapi");
$BASE = "http://php.net";
function ce(DOMDocument $d, $name, $value, array $attrs = array(), DOMNode $to = null) {
// Script config
const BASE = "https://www.php.net";
const PHPWEB = __DIR__ . '/../';
const ARCHIVE_FILE_REL = 'archive/archive.xml';
const ARCHIVE_FILE_ABS = PHPWEB . ARCHIVE_FILE_REL;
const ARCHIVE_ENTRIES_REL = 'archive/entries/';
const ARCHIVE_ENTRIES_ABS = PHPWEB . ARCHIVE_ENTRIES_REL;
$categories = [
'frontpage' => 'PHP.net frontpage news',
'releases' => 'New PHP release',
'conferences' => 'Conference announcement',
'cfp' => 'Call for Papers',
];
$imageRestriction = [
'width' => 400,
'height' => 250
];
// Create an entry!
if (!file_exists(ARCHIVE_FILE_ABS)) {
fwrite(STDERR, "Can't find " . ARCHIVE_FILE_REL . ", are you sure you are in phpweb/?\n");
exit(1);
}
$id = getNextId();
createNewsEntry($id);
updateArchiveXML($id, ARCHIVE_FILE_ABS);
fwrite(STDOUT, "File saved.\nPlease git diff " . ARCHIVE_FILE_REL . " and sanity-check the changes before committing\n");
fwrite(STDOUT, "NOTE: Remeber to git add " . ARCHIVE_ENTRIES_REL . $id . ".xml !!\n");
// Implementation functions
function getNextId(): string {
$filename = date("Y-m-d", $_SERVER["REQUEST_TIME"]);
$count = 0;
do {
++$count;
$id = $filename . "-" . $count;
$basename = "{$id}.xml";
fprintf(STDOUT, "Trying $basename\n");
} while (file_exists(ARCHIVE_ENTRIES_ABS . $basename));
return $id;
}
function createNewsEntry(string $id): void {
global $categories;
$entry = getEntry($id);
// Create the XML document.
$dom = new DOMDocument("1.0", "utf-8");
$dom->formatOutput = true;
$dom->preserveWhiteSpace = false;
$item = $dom->createElementNs("http://www.w3.org/2005/Atom", "entry");
ce($dom, "title", $entry['title'], [], $item);
ce($dom, "id", $entry['archive'], array(), $item);
ce($dom, "published", date(DATE_ATOM), [], $item);
ce($dom, "updated", date(DATE_ATOM), [], $item);
ce($dom, "link", null, ['href' => "{$entry['href']}#id$id", "rel" => "alternate", "type" => "text/html"], $item);
ce($dom, "link", null, ['href' => $entry['via'], 'rel' => 'via', 'type' => 'text/html'], $item);
if (isset($entry['conf-time'])) {
$item->appendChild($dom->createElementNs("http://php.net/ns/news", "finalTeaserDate", date("Y-m-d", $entry['conf-time'])));
}
foreach ($entry['categories'] as $cat) {
ce($dom, "category", null, ['term' => $cat, "label" => $categories[$cat]], $item);
}
if ($entry['image'] ?? false) {
$image = $item->appendChild($dom->createElementNs("http://php.net/ns/news", "newsImage", $entry['image']['path']));
$image->setAttribute("link", $entry['image']['link']);
$image->setAttribute("title", $entry['image']['title']);
}
$content = ce($dom, "content", null, [], $item);
// Slurp content into our DOM.
$tdoc = new DOMDocument("1.0", "utf-8");
$tdoc->formatOutput = true;
if ($tdoc->loadXML("<div>{$entry['content']} </div>")) {
$content->setAttribute("type", "xhtml");
$div = $content->appendChild($dom->createElement("div"));
$div->setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
foreach($tdoc->firstChild->childNodes as $node) {
$div->appendChild($dom->importNode($node, true));
}
} else {
fwrite(STDERR, "There is something wrong with your xhtml, falling back to html");
$content->setAttribute("type", "html");
$content->nodeValue = $entry['content'];
}
$dom->appendChild($item);
$dom->save(ARCHIVE_ENTRIES_ABS . $id . ".xml");
}
function ce(DOMDocument $d, string $name, $value, array $attrs = [], ?DOMNode $to = null) {
if ($value) {
$n = $d->createElement($name, $value);
} else {
@@ -18,143 +119,117 @@ function ce(DOMDocument $d, $name, $value, array $attrs = array(), DOMNode $to =
return $n;
}
$archivefile = "archive/archive.xml";
file_exists($archivefile) or die("Can't find $archivefile, are you sure you are in phpweb/?\n");
function getEntry(string $id): array {
$entry = [];
$filename = date("Y-m-d", $_SERVER["REQUEST_TIME"]);
$count = 0;
do {
++$count;
$id = $filename. "-" . $count;
$basename = $id .".xml";
$file = "archive/entries/" . $basename;
$xincluded = "entries/" . $basename;
fprintf(STDOUT, "Trying $file\n");
} while (file_exists($file));
$entry['title'] = getTitle();
$dom = new DOMDocument("1.0", "utf-8");
$dom->formatOutput = true;
$dom->preserveWhiteSpace = false;
$entry['categories'] = selectCategories();
if (array_intersect($entry['categories'], ['cfp', 'conferences'])) {
$entry['href'] = BASE . '/conferences/index.php';
$entry['conf-time'] = getConfTime();
}
$item = $dom->createElementNs("http://www.w3.org/2005/Atom", "entry");
$entry['image'] = getImage();
$entry['content'] = getContent();
do {
fwrite(STDOUT, "Please type in the title: ");
$title = rtrim(fgets(STDIN));
} while(strlen($title)<3);
$entry['href'] = BASE . '/index.php';
$entry['archive'] = BASE . "/archive/" . date('Y', $_SERVER['REQUEST_TIME']) . ".php#$id";
$entry['via'] = $entry['image']['link'] ?? $entry['archive'];
ce($dom, "title", $title, array(), $item);
return $entry;
}
$categories = array(
array("frontpage" => "PHP.net frontpage news"),
array("releases" => "New PHP release"),
array("conferences" => "Conference announcement"),
array("cfp" => "Call for Papers"),
);
$confs = array(2, 3);
function getTitle(): string {
do {
fwrite(STDOUT, "Please type in the title: ");
$title = rtrim(fgets(STDIN));
} while(strlen($title)<3);
$imageRestriction = array(
'width' => 400,
'height' => 250
);
return $title;
}
function selectCategories(): array { for(;;) {
global $categories;
$ids = array_keys($categories);
do {
$catVerified = false;
fwrite(STDOUT, "Categories:\n");
foreach($categories as $n => $category) {
fprintf(STDOUT, "\t%d: %-11s\t [%s]\n", $n, key($category), current($category));
foreach($ids as $n => $id) {
fprintf(STDOUT, "\t%d: %-11s\t [%s]\n", $n, $categories[$id], $id);
}
fwrite(STDOUT, "Please select appropriate categories, seperated with space: ");
$cat = explode(" ", rtrim(fgets(STDIN)));
$cat = array_intersect(array_keys(array_values($categories)), $cat);
// Filter to 0..n-1, then map to short names.
$cat = array_map(
function ($c) use ($ids) {
return $ids[$c];
},
array_filter(
explode(" ", rtrim(fgets(STDIN))),
function ($c) use ($categories) {
return is_numeric($c) && ($c >= 0) && ($c < count($categories));
})
);
$intersect = array_intersect(array(2,3), $cat);
if ($cat && (count($intersect) < 2)) {
break;
}
if (count($intersect) == 2) {
// Special case, we don't allow items in both 'cfp' and 'conferences'.
if (count(array_intersect($cat, ['cfp', 'conferences'])) >= 2) {
fwrite(STDERR, "Pick either a CfP OR a conference\n");
} else {
continue;
}
if (count($cat) == 0) {
fwrite(STDERR, "You have to pick at least one category\n");
continue;
}
} while(1);
return $cat;
}}
$via = $archive = $BASE . "/archive/" .date("Y", $_SERVER["REQUEST_TIME"]).".php#id" .$id;
ce($dom, "id", $archive, array(), $item);
ce($dom, "published", date(DATE_ATOM), array(), $item);
ce($dom, "updated", date(DATE_ATOM), array(), $item);
$conf = false;
foreach($cat as $keys) {
if (in_array($keys, $confs)) {
$conf = true;
break;
}
}
if ($conf) {
/* /conferences news item */
$href = $BASE . "/conferences/index.php";
do {
fwrite(STDOUT, "When does the conference start/cfp end? (strtotime() compatible syntax): ");
$t = strtotime(fgets(STDIN));
if ($t) {
break;
}
function getConfTime(): int { for(;;) {
fwrite(STDOUT, "When does the conference start/cfp end? (strtotime() compatible syntax): ");
$t = strtotime(fgets(STDIN));
if (!$t) {
fwrite(STDERR, "I told you I would run it through strtotime()!\n");
} while(1);
$item->appendChild($dom->createElementNs("http://php.net/ns/news", "finalTeaserDate", date("Y-m-d", $t)));
} else {
$href = $BASE . "/index.php";
}
foreach($cat as $n) {
if (isset($categories[$n])) {
ce($dom, "category", null, array("term" => key($categories[$n]), "label" => current($categories[$n])), $item);
continue;
}
}
ce($dom, "link", null, array("href" => "$href#id$id", "rel" => "alternate", "type" => "text/html"), $item);
return $t;
}}
fwrite(STDOUT, "Will a picture be accompanying this entry? ");
$yn = fgets(STDIN);
function getImage(): ?array {
global $imageRestriction;
fwrite(STDOUT, "Will a picture be accompanying this entry? ");
$yn = fgets(STDIN);
if (strtoupper($yn[0]) == "Y") {
$isValidImage = false;
if (strtoupper($yn[0]) !== "Y") {
return NULL;
}
do {
for ($isValidImage = false; !$isValidImage;) {
fwrite(STDOUT, "Enter the image name (note: the image has to exist in './images/news'): ");
$path = basename(rtrim(fgets(STDIN)));
if (true === file_exists("./images/news/$path")) {
if (true === file_exists(PHPWEB . "/images/news/$path")) {
$isValidImage = true;
if (true === extension_loaded('gd')) {
$imageSizes = getimagesize("./images/news/$path");
if (extension_loaded('gd')) {
break;
}
if (
$imageSizes[0] > $imageRestriction['width'] ||
$imageSizes[1] > $imageRestriction['height']
) {
fwrite(STDOUT, "Provided image has a higher size than recommended (" . implode(' by ', $imageRestriction) . "). Continue? ");
$ynImg = fgets(STDIN);
if (strtoupper($ynImg[0]) == "Y") {
break;
} else {
$isValidImage = false;
}
$imageSizes = getimagesize("./images/news/$path");
if (($imageSizes[0] > $imageRestriction['width']) || ($imageSizes[1] > $imageRestriction['height'])) {
fwrite(STDOUT, "Provided image has a higher size than recommended (" . implode(' by ', $imageRestriction) . "). Continue? ");
$ynImg = fgets(STDIN);
if (strtoupper($ynImg[0]) !== "Y") {
$isValidImage = false;
}
}
}
} while($isValidImage !== true);
}
fwrite(STDOUT, "Image title: ");
$title = rtrim(fgets(STDIN));
@@ -162,48 +237,33 @@ if (strtoupper($yn[0]) == "Y") {
fwrite(STDOUT, "Link (when clicked on the image): ");
$via = rtrim(fgets(STDIN));
$image = $item->appendChild($dom->createElementNs("http://php.net/ns/news", "newsImage", $path));
$image->setAttribute("link", $via);
$image->setAttribute("title", $title);
}
ce($dom, "link", null, array("href" => $via, "rel" => "via", "type" => "text/html"), $item);
$content = ce($dom, "content", null, array(), $item);
fwrite(STDOUT, "And at last; paste/write your news item here.\nTo end it, hit <enter>.<enter>\n");
$news = "\n";
while(($line = rtrim(fgets(STDIN))) != ".") {
$news .= " $line\n";
return [
'title' => $title,
'link' => $via,
'path' => $path,
];
}
$tdoc = new DOMDocument("1.0", "utf-8");
$tdoc->formatOutput = true;
if ($tdoc->loadXML('<div>'.$news.' </div>')) {
$content->setAttribute("type", "xhtml");
$div = $content->appendChild($dom->createElement("div"));
$div->setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
foreach($tdoc->firstChild->childNodes as $node) {
$div->appendChild($dom->importNode($node, true));
function getContent(): string {
fwrite(STDOUT, "And at last; paste/write your news item here.\nTo end it, hit <enter>.<enter>\n");
$news = "\n";
while(($line = rtrim(fgets(STDIN))) != ".") {
$news .= " $line\n";
}
} else {
fwrite(STDERR, "There is something wrong with your xhtml, falling back to html");
$content->setAttribute("type", "html");
$content->nodeValue = $news;
return $news;
}
$dom->appendChild($item);
$dom->save($file);
$arch = new DOMDocument("1.0", "utf-8");
$arch->formatOutput = true;
$arch->preserveWhiteSpace = false;
$arch->load("archive/archive.xml");
function updateArchiveXML(string $id, string $archiveFile): void {
$arch = new DOMDocument("1.0", "utf-8");
$arch->formatOutput = true;
$arch->preserveWhiteSpace = false;
$arch->load($archiveFile);
$first = $arch->createElementNs("http://www.w3.org/2001/XInclude", "xi:include");
$first->setAttribute("href", $xincluded);
$first = $arch->createElementNs("http://www.w3.org/2001/XInclude", "xi:include");
$first->setAttribute("href", "entries/{$id}.xml");
$second = $arch->getElementsByTagNameNs("http://www.w3.org/2001/XInclude", "include")->item(0);
$arch->documentElement->insertBefore($first, $second);
$arch->save("archive/archive.xml");
fwrite(STDOUT, "File saved.\nPlease git diff $archivefile sanity-check the changes before committing\n");
fwrite(STDOUT, "NOTE: Remeber to git add $file && git commit $file && git push!!\n");
$second = $arch->getElementsByTagNameNs("http://www.w3.org/2001/XInclude", "include")->item(0);
$arch->documentElement->insertBefore($first, $second);
$arch->save($archiveFile);
}