{$addnotesnippet}
User Contributed Notes {$num_notes}
END_USERNOTE_HEADER;
// If we have no notes, then inform the user
if (sizeof($notes) == 0) {
echo "\n There are no user contributed notes for this page.
";
}
// If we have notes, print them out
else {
echo '';
foreach($notes as $note) {
manual_note_display(
$note['xwhen'], $note['user'], $note['note'], $note['id'], $note['votes']
);
}
echo "
\n";
echo "\n \n";
}
// #usernotes gets closed by the footer
}
// Get user notes from the appropriate text dump
function manual_notes_load($id)
{
// Initialize values
$notes = 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] = array(
"id" => $id,
"sect" => $sect,
"rate" => $rate,
"xwhen" => $ts,
"user" => $user,
"note" => base64_decode($note),
"votes" => array("up"=> (int)$up, "down"=> (int)$down)
);
}
fclose($fp);
}
return $notes;
}
// Print out one user note entry
function manual_note_display($date, $name, $text, $id, $votes = array('up'=>0,'down'=>0), $voteOption = true)
{
if ($name) {
$name = "\n " . htmlspecialchars($name) . "";
} else {
$name = "Anonymous";
}
$name = ($id ? "\n $name ¶" : "\n $name");
// New date style will be relative time
$datestr = relTime(new DateTime("@{$date}"));
$fdatestr = date("Y-m-d h:i", $date);
$text = clean_note($text);
// Calculate note rating by up/down votes
$vote = $votes['up'] - $votes['down'];
$p = floor(($votes['up'] / (($votes['up'] + $votes['down']) ? $votes['up'] + $votes['down'] : 1)) * 100);
$rate = !$p && !($votes['up'] + $votes['down']) ? "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']) && $id) {
$admin = "\n \n " .
make_popup_link(
'https://master.php.net/manage/user-notes.php?action=edit+' . $id,
'
',
'admin',
'scrollbars=yes,width=650,height=400'
) . "\n " .
make_popup_link(
'https://master.php.net/manage/user-notes.php?action=reject+' . $id,
'
',
'admin',
'scrollbars=no,width=300,height=200'
) . "\n " .
make_popup_link(
'https://master.php.net/manage/user-notes.php?action=delete+' . $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 = array();
foreach(array_reverse($setup["parents"]) as $parent) {
$menu[] = array(
"title" => $parent[1],
"link" => $parent[0],
);
}
// The index manual page has no parent..
if ($setup["up"][0]) {
$last_item = array(
"title" => $setup["up"][1],
"link" => $setup["up"][0],
);
$menu[] = $last_item;
}
return $menu;
}
function manual_navigation_related(array $setup) {
$siblings = array();
foreach($setup['toc'] as $entry) {
$siblings[] = array(
"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 = array(
"title" => $setup["up"][1],
"link" => $setup["up"][0],
);
$siblings = array(array_merge($last_item, array("children" => $siblings)));
}
return $siblings;
}
function manual_navigation_deprecated(array $setup) {
$methods = array();
foreach((array)$setup['toc_deprecated'] as $entry) {
$methods[] = array(
"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(array('-','_'), array('-','_'), $methodname);
}
// Set up variables important for this page
// including HTTP header information
function manual_setup($setup) {
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"] = array();
}
$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'];
// Load user note for this page
list($filename, $title) = $PGI['this'];
// Drop file extension from the name
if (substr($filename, -4) == '.php') {
$filename = substr($filename, 0, -4);
}
$USERNOTES = manual_notes_load($filename);
$note = current($USERNOTES);
$lastusernote = $note["xwhen"];
$timestamps = array(
filemtime($_SERVER["DOCUMENT_ROOT"] . "/" . $_SERVER["BASE_PAGE"]),
filemtime($_SERVER["DOCUMENT_ROOT"] . "/include/prepend.inc"),
filemtime($_SERVER["DOCUMENT_ROOT"] . "/styles/theme-base.css"),
$lastusernote,
);
$lastmod = max($timestamps);
$breadcrumbs = manual_navigation_breadcrumbs($setup);
$__RELATED['toc'] = manual_navigation_related($setup);
$__RELATED['toc_deprecated'] = manual_navigation_deprecated($setup);
$config = array(
"current" => "docs",
"breadcrumbs" => $breadcrumbs,
"languages" => array_keys($ACTIVE_ONLINE_LANGUAGES),
"meta-navigation" => array(
"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);
$id = substr($setup['this'][0], 0, -4);
$language_chooser = 'manual_language_chooser';
echo <<
{$language_chooser($config['lang'], $config['thispage'])}
PAGE_TOOLS;
}
function manual_language_chooser($currentlang, $currentpage) {
global $ACTIVE_ONLINE_LANGUAGES;
$links = array();
foreach ($ACTIVE_ONLINE_LANGUAGES as $lang => $name) {
$links[] = array("$lang/$currentpage", $name, $lang);
}
// Print out the form with all the options
$othersel = ' selected="selected"';
$format_options = function (array $links) use ($currentlang, &$othersel) {
$out = '';
$tab = str_repeat(' ', 6);
foreach ($links as $link) {
list($value, $text, $lang) = $link;
$selected = '';
if ($lang == $currentlang) {
$selected = ' selected="selected"';
$othersel = '';
}
$out .= "$tab\n";
}
return trim($out);
};
$r = <<
CHANGE_LANG;
return trim($r);
}
function manual_header(){}
function manual_footer() {
global $USERNOTES, $__RELATED;
manual_notes($USERNOTES);
echo "";
$config = array(
'related_menu' => $__RELATED['toc'],
'related_menu_deprecated' => $__RELATED['toc_deprecated']
);
site_footer($config);
}
// 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 = array("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;
}
/* vim: set et ts=4 sw=4: */