{$addnotesnippet}
User Contributed Notes {$noteCountHtml}
END_USERNOTE_HEADER;
// If we have no notes, then inform the user
if ($num_notes === 0) {
echo "\n There are no user contributed notes for this page.
";
} else {
// If we have notes, print them out
echo '';
foreach ($notes as $note) {
manual_note_display($note);
}
echo "
\n";
echo "\n";
}
echo "";
}
/**
* Get user notes from the appropriate text dump
*
* @return array
*/
function manual_notes_load(string $id): array
{
$hash = substr(md5($id), 0, 16);
$notes_file = $_SERVER['DOCUMENT_ROOT'] . "/backend/notes/" .
substr($hash, 0, 2) . "/$hash";
// Open the note file for reading and get the data (12KB)
// ..if it exists
if (!file_exists($notes_file)) {
return [];
}
$notes = [];
if ($fp = @fopen($notes_file, "r")) {
while (!feof($fp)) {
$line = chop(fgets($fp, 12288));
if ($line == "") { continue; }
@list($id, $sect, $rate, $ts, $user, $note, $up, $down) = explode("|", $line);
$notes[$id] = new UserNote($id, $sect, $rate, $ts, $user, base64_decode($note, true), (int) $up, (int) $down);
}
fclose($fp);
}
return $notes;
}
// Print out one user note entry
function manual_note_display(UserNote $note, $voteOption = true): void
{
if ($note->user) {
$name = "\n " . htmlspecialchars($note->user) . "";
} else {
$name = "Anonymous";
}
$name = ($note->id ? "\n id}\" class=\"name\">$nameid}\"> ¶" : "\n $name");
// New date style will be relative time
$date = new DateTime("@{$note->ts}");
$datestr = relTime($date);
$fdatestr = $date->format("Y-m-d h:i");
$text = clean_note($note->text);
// Calculate note rating by up/down votes
$vote = $note->upvotes - $note->downvotes;
$p = floor(($note->upvotes / (($note->upvotes + $note->downvotes) ?: 1)) * 100);
$rate = !$p && !($note->upvotes + $note->downvotes) ? "no votes..." : "$p% like this...";
// Vote User Notes Div
if ($voteOption) {
list($redir_filename) = $GLOBALS['PGI']['this'];
if (substr($redir_filename, -4) == '.php') {
$redir_filename = substr($redir_filename, 0, -4);
}
$rredir_filename = urlencode($redir_filename);
$votediv = <<
{$vote}
VOTEDIV;
} else {
$votediv = null;
}
// If the viewer is logged in, show admin options
if (isset($_COOKIE['IS_DEV']) && $note->id) {
$admin = "\n \n " .
make_popup_link(
'https://main.php.net/manage/user-notes.php?action=edit+' . $note->id,
'',
'admin',
'scrollbars=yes,width=650,height=400',
) . "\n " .
make_popup_link(
'https://main.php.net/manage/user-notes.php?action=reject+' . $note->id,
'',
'admin',
'scrollbars=no,width=300,height=200',
) . "\n " .
make_popup_link(
'https://main.php.net/manage/user-notes.php?action=delete+' . $note->id,
'',
'admin',
'scrollbars=no,width=300,height=200',
) . "\n ";
} else {
$admin = '';
}
echo <<{$votediv}{$name}{$admin}{$datestr}
{$text}
USER_NOTE_TEXT;
}
function manual_navigation_breadcrumbs(array $setup) {
$menu = [];
foreach (array_reverse($setup["parents"]) as $parent) {
$menu[] = [
"title" => $parent[1],
"link" => $parent[0],
];
}
// The index manual page has no parent..
if ($setup["up"][0]) {
$last_item = [
"title" => $setup["up"][1],
"link" => $setup["up"][0],
];
$menu[] = $last_item;
}
return $menu;
}
function manual_navigation_related(array $setup) {
$siblings = [];
foreach ($setup['toc'] as $entry) {
$siblings[] = [
"title" => manual_navigation_methodname($entry[1]),
"link" => $entry[0],
"current" => $setup["this"][0] == $entry[0],
];
}
// The index manual page has no parent..
if ($setup["up"][0]) {
$last_item = [
"title" => $setup["up"][1],
"link" => $setup["up"][0],
];
$siblings = [array_merge($last_item, ["children" => $siblings])];
}
return $siblings;
}
function manual_navigation_deprecated(array $setup) {
$methods = [];
foreach ((array)$setup['toc_deprecated'] as $entry) {
$methods[] = [
"title" => manual_navigation_methodname($entry[1]),
"link" => $entry[0],
"current" => $setup["this"][0] == $entry[0],
];
}
return $methods;
}
function manual_navigation_methodname($methodname) {
// We strip out any class prefix here, we only want method names
if (strpos($methodname, '::') !== false && strpos($methodname, ' ') === false) {
$tmp = explode('::', $methodname);
$methodname = $tmp[1];
}
// Add zero-width spaces to allow line-breaks at various characters
return str_replace(['-', '_'], ['-', '_'], $methodname);
}
// Set up variables important for this page
// including HTTP header information
function manual_setup($setup): void {
global $PGI, $MYSITE, $USERNOTES;
global $ACTIVE_ONLINE_LANGUAGES;
//TODO: get rid of this hack to get the related items into manual_footer
global $__RELATED;
if (!isset($setup["toc_deprecated"])) {
$setup["toc_deprecated"] = [];
}
$PGI = $setup;
// Set base href for this manual page
$base = 'manual/' . language_convert($setup['head'][1]) . "/";
$_SERVER['BASE_PAGE'] = $base . $setup['this'][0];
$_SERVER['BASE_HREF'] = $MYSITE . $_SERVER['BASE_PAGE'];
$timestamps = [
filemtime($_SERVER["DOCUMENT_ROOT"] . "/" . $_SERVER["BASE_PAGE"]),
filemtime($_SERVER["DOCUMENT_ROOT"] . "/include/prepend.inc"),
filemtime($_SERVER["DOCUMENT_ROOT"] . "/styles/theme-base.css"),
];
// Load user note for this page
$filename = $PGI['this'][0];
// Drop file extension from the name
if (substr($filename, -4) == '.php') {
$filename = substr($filename, 0, -4);
}
$USERNOTES = manual_notes_load($filename);
if ($USERNOTES) {
$note = current($USERNOTES);
$timestamps[] = $note->ts;
}
$lastmod = max($timestamps);
$breadcrumbs = manual_navigation_breadcrumbs($setup);
$__RELATED['toc'] = manual_navigation_related($setup);
$__RELATED['toc_deprecated'] = manual_navigation_deprecated($setup);
$config = [
"current" => "docs",
"breadcrumbs" => $breadcrumbs,
"languages" => array_keys($ACTIVE_ONLINE_LANGUAGES),
"meta-navigation" => [
"contents" => $base . $setup["home"][0],
"index" => $base . $setup["up"][0],
"prev" => $base . $setup["prev"][0],
"next" => $base . $setup["next"][0],
],
"lang" => $setup["head"][1],
"thispage" => $setup["this"][0],
"prev" => $setup["prev"],
"next" => $setup["next"],
"cache" => $lastmod,
];
site_header($setup["this"][1] . " - Manual ", $config);
$languageChooser = manual_language_chooser($config['lang'], $config['thispage']);
echo <<
{$languageChooser}
PAGE_TOOLS;
}
function manual_language_chooser($currentlang, $currentpage) {
global $ACTIVE_ONLINE_LANGUAGES;
// Prepare the form with all the options
$othersel = ' selected="selected"';
$out = [];
foreach ($ACTIVE_ONLINE_LANGUAGES as $lang => $text) {
$selected = '';
if ($lang == $currentlang) {
$selected = ' selected="selected"';
$othersel = '';
}
$out[] = "";
}
$out[] = "";
$format_options = implode("\n" . str_repeat(' ', 6), $out);
$r = <<
CHANGE_LANG;
return trim($r);
}
function manual_footer($setup): void {
global $USERNOTES, $__RELATED;
$id = substr($setup['this'][0], 0, -4);
$repo = strtolower($setup["head"][1]); // pt_BR etc.
$edit_url = "https://github.com/php/doc-{$repo}";
// If the documentation source information is available (generated using
// doc-base/configure.php and PhD) then try and make a source-specific URL.
if (isset($setup['source'])) {
$source_lang = $setup['source']['lang'];
if ($source_lang === $repo || $source_lang === 'base') {
$edit_url = "https://github.com/php/doc-{$source_lang}/blob/master/{$setup['source']['path']}";
}
}
$lastUpdate = '';
if (isset($setup["history"]['modified']) && $setup["history"]['modified'] !== "") {
$modifiedDateTime = date_create($setup["history"]['modified']);
if ($modifiedDateTime !== false) {
$lastUpdate .= "Last updated on " . date_format($modifiedDateTime,"M d, Y (H:i T)");
$lastUpdate .= (isset($setup["history"]['contributors'][0]) ? " by " . $setup["history"]['contributors'][0] : "") . ".";
}
}
$contributors = '';
if (isset($setup["history"]['contributors']) && count($setup["history"]['contributors']) > 0) {
$contributors = 'All contributors.';
}
echo <<
Improve This Page
$lastUpdate $contributors
CONTRIBUTE;
manual_notes($USERNOTES, $repo);
site_footer([
'related_menu' => $__RELATED['toc'],
'related_menu_deprecated' => $__RELATED['toc_deprecated'],
]);
}
// This function takes a DateTime object and returns a formated string of the time difference relative to now
function relTime(DateTime $date) {
$current = new DateTime();
$diff = $current->diff($date);
$units = ["year" => $diff->format("%y"),
"month" => $diff->format("%m"),
"day" => $diff->format("%d"),
"hour" => $diff->format("%h"),
"minute" => $diff->format("%i"),
"second" => $diff->format("%s"),
];
$out = "just now...";
foreach ($units as $unit => $amount) {
if (empty($amount)) {
continue;
}
$out = $amount . " " . ($amount == 1 ? $unit : $unit . "s") . " ago";
break;
}
return $out;
}
function contributors($setup) {
if (!isset($_GET["contributors"])
|| !isset($setup["history"]["contributors"])
|| count($setup["history"]["contributors"]) < 1) {
return;
}
$contributorList = "" . implode("", $setup["history"]["contributors"]) . "";
echo <<
Output Buffering Control
The following have authored commits that contributed to this page:
CONTRIBUTORS;
manual_footer($setup);
exit;
}