From 464ff738bafbd7882c3e9b399531702e95f08023 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Wed, 10 Jul 2019 12:09:48 -0400 Subject: [PATCH] Refactor bin/createNewsEntry --- bin/createNewsEntry | 344 ++++++++++++++++++++++++++------------------ 1 file changed, 202 insertions(+), 142 deletions(-) diff --git a/bin/createNewsEntry b/bin/createNewsEntry index 0ee149127..de960b00c 100755 --- a/bin/createNewsEntry +++ b/bin/createNewsEntry @@ -1,9 +1,110 @@ #!/usr/bin/env php '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("
{$entry['content']}
")) { + $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 .\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('
'.$news.'
')) { - $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 .\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); +}