mirror of
https://github.com/php/web-php.git
synced 2026-03-23 23:02:13 +01:00
257 lines
6.9 KiB
PHP
Executable File
257 lines
6.9 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
<?php
|
|
PHP_SAPI == 'cli' or die("Please run this script using the cli sapi");
|
|
|
|
require_once __DIR__ . '/../src/News/Entry.php';
|
|
|
|
use phpweb\News\Entry;
|
|
|
|
$imageRestriction = [
|
|
'width' => 400,
|
|
'height' => 250
|
|
];
|
|
|
|
// Create an entry!
|
|
if (!file_exists(Entry::ARCHIVE_FILE_ABS)) {
|
|
fwrite(STDERR, "Can't find " . Entry::ARCHIVE_FILE_REL . ", are you sure you are in phpweb/?\n");
|
|
exit(1);
|
|
}
|
|
|
|
if ($_SERVER['argc'] > 1) {
|
|
// getopt based non-interactive mode
|
|
$entry = parseOptions();
|
|
} else {
|
|
// Classic interactive prompts
|
|
$entry = getEntry();
|
|
}
|
|
|
|
$entry->save()->updateArchiveXML();
|
|
|
|
fwrite(STDOUT, "File saved.\nPlease git diff " . Entry::ARCHIVE_FILE_REL . " and sanity-check the changes before committing\n");
|
|
fwrite(STDOUT, "NOTE: Remember to git add " . Entry::ARCHIVE_ENTRIES_REL . $entry->getId() . ".xml !!\n");
|
|
|
|
// Implementation functions
|
|
|
|
function getEntry(): Entry {
|
|
$entry = new Entry;
|
|
$entry->setTitle(getTitle());
|
|
$entry->setCategories(selectCategories());
|
|
if ($entry->isConference()) {
|
|
$entry->setConfTime(getConfTime());
|
|
}
|
|
|
|
$image = getImage();
|
|
$entry->setImage($image['path'] ?? '', $image['title'] ?? '', $image['link'] ?? '');
|
|
|
|
$entry->setContent(getContent());
|
|
|
|
return $entry;
|
|
}
|
|
|
|
function getTitle(): string {
|
|
do {
|
|
fwrite(STDOUT, "Please type in the title: ");
|
|
$title = rtrim(fgets(STDIN));
|
|
} while(strlen($title)<3);
|
|
|
|
return $title;
|
|
}
|
|
|
|
function selectCategories(): array { for(;;) {
|
|
$ids = array_keys(Entry::CATEGORIES);
|
|
|
|
fwrite(STDOUT, "Categories:\n");
|
|
foreach($ids as $n => $id) {
|
|
fprintf(STDOUT, "\t%d: %-11s\t [%s]\n", $n, Entry::CATEGORIES[$id], $id);
|
|
}
|
|
fwrite(STDOUT, "Please select appropriate categories, seperated with space: ");
|
|
|
|
// 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) {
|
|
return is_numeric($c) && ($c >= 0) && ($c < count(Entry::CATEGORIES));
|
|
})
|
|
);
|
|
|
|
// 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");
|
|
continue;
|
|
}
|
|
|
|
if (count($cat) == 0) {
|
|
fwrite(STDERR, "You have to pick at least one category\n");
|
|
continue;
|
|
}
|
|
|
|
return $cat;
|
|
}}
|
|
|
|
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");
|
|
continue;
|
|
}
|
|
|
|
return $t;
|
|
}}
|
|
|
|
function getImage(): ?array {
|
|
global $imageRestriction;
|
|
|
|
fwrite(STDOUT, "Will a picture be accompanying this entry? ");
|
|
$yn = fgets(STDIN);
|
|
|
|
|
|
if (strtoupper($yn[0]) !== "Y") {
|
|
return NULL;
|
|
}
|
|
|
|
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(Entry::PHPWEB . "/images/news/$path")) {
|
|
$isValidImage = true;
|
|
|
|
if (extension_loaded('gd')) {
|
|
break;
|
|
}
|
|
|
|
$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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fwrite(STDOUT, "Image title: ");
|
|
$title = rtrim(fgets(STDIN));
|
|
|
|
fwrite(STDOUT, "Link (when clicked on the image): ");
|
|
$via = rtrim(fgets(STDIN));
|
|
|
|
return [
|
|
'title' => $title,
|
|
'link' => $via,
|
|
'path' => $path,
|
|
];
|
|
}
|
|
|
|
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";
|
|
}
|
|
|
|
return $news;
|
|
}
|
|
|
|
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", "entries/{$id}.xml");
|
|
|
|
$second = $arch->getElementsByTagNameNs("http://www.w3.org/2001/XInclude", "include")->item(0);
|
|
$arch->documentElement->insertBefore($first, $second);
|
|
$arch->save($archiveFile);
|
|
}
|
|
|
|
function parseOptions(): Entry {
|
|
$opts = getopt('h', [
|
|
'help',
|
|
'title:',
|
|
'category:',
|
|
'conf-time:',
|
|
'image-path:',
|
|
'image-title:',
|
|
'image-link:',
|
|
'content:',
|
|
'content-file:',
|
|
]);
|
|
if (isset($opts['h']) || isset($opts['help'])) {
|
|
echo "Usage: {$_SERVER['argv'][0]} --title 'Name of event' --category cfp ( --content 'text' | --content-file '-') [...options]\n\n";
|
|
echo " --title 'value' The title of the entry (required)\n";
|
|
echo " --category 'value' 'frontpage', 'release', 'cfp', or 'conference' (required; may repeat)\n";
|
|
echo " --conf-time 'value' When the event will be occurign (cfp and conference categories only)\n";
|
|
echo " --content 'value' Text content for the entry, may include XHTML\n";
|
|
echo " --content-file 'value' Name of file to load content from, may not be specified with --content\n";
|
|
echo " --image-path 'value' Basename of image file in " . Entry::IMAGE_PATH_REL . "\n";
|
|
echo " --image-title 'value' Title for the image provided\n";
|
|
echo " --image-link 'value' URI to direct to when clicking the image\n";
|
|
exit(0);
|
|
}
|
|
|
|
$entry = new Entry;
|
|
if (!isset($opts['title'])) {
|
|
fwrite(STDERR, "--title required\n");
|
|
exit(1);
|
|
}
|
|
$entry->setTitle($opts['title']);
|
|
|
|
if (empty($opts['category'])) {
|
|
fwrite(STDERR, "--category required\n");
|
|
exit(1);
|
|
}
|
|
if (is_string($opts['category'])) {
|
|
$opts['category'] = [ $opts['category'] ];
|
|
}
|
|
foreach ($opts['category'] as $cat) {
|
|
$entry->addCategory($cat);
|
|
}
|
|
if ($entry->isConference()) {
|
|
if (empty($opts['conf-time'])) {
|
|
fwrite(STDERR, "--conf-time required for conferences\n");
|
|
exit(1);
|
|
}
|
|
$t = strtotime($opts['conf-time']);
|
|
if (!is_int($t)) {
|
|
fwrite(STDERR, "Error parsing --conf-time\n");
|
|
exit(1);
|
|
}
|
|
$entry->setConfTime($t);
|
|
} elseif (!empty($opts['conf-time'])) {
|
|
fwrite(STDERR, "--conf-time not allowed with non-conference events\n");
|
|
exit(1);
|
|
}
|
|
|
|
$entry->setImage($opts['image-path'] ?? '', $opts['image-title'] ?? '', $opts['image-link'] ?? '');
|
|
|
|
if (isset($opts['content'])) {
|
|
if (isset($opts['content-file'])) {
|
|
fwrite(STDERR, "--content and --content-file may not be specified together\n");
|
|
exit(1);
|
|
}
|
|
$entry->setContent($opts['content']);
|
|
} elseif (isset($opts['content-file'])) {
|
|
if ($opts['content-file'] === '-') {
|
|
$entry->setContent(stream_get_contents(STDIN));
|
|
} else {
|
|
$entry->setContent(file_get_contents($opts['content-file']));
|
|
}
|
|
} else {
|
|
fwrite(STDERR, "--content or --content-file required\n");
|
|
exit(1);
|
|
}
|
|
|
|
return $entry;
|
|
}
|