From 7e2d16d545c612887bf18b33ce6e312ecf562baf Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Wed, 21 Jan 2026 15:02:14 +0000 Subject: [PATCH] Revert "Create UserNoteService class" This reverts commit b31ec1c7f1ad8901a2a27df56e766a1bf236cea5. --- include/layout.inc | 29 ++++ include/shared-manual.inc | 210 +++++++++++++++++++++++++- manual/add-note.php | 4 +- manual/vote-note.php | 14 +- src/UserNotes/UserNoteService.php | 237 ------------------------------ 5 files changed, 239 insertions(+), 255 deletions(-) delete mode 100644 src/UserNotes/UserNoteService.php diff --git a/include/layout.inc b/include/layout.inc index 98d8c845c..02b6f733c 100644 --- a/include/layout.inc +++ b/include/layout.inc @@ -164,6 +164,21 @@ function make_link(string $url, string $linktext = ''): string return sprintf("%s", $url, $linktext ?: $url); } +// make_popup_link() +// return a hyperlink to something, within the site, that pops up a new window +// +function make_popup_link($url, $linktext = false, $target = false, $windowprops = "", $extras = false) { + return sprintf("%s", + htmlspecialchars($url, ENT_QUOTES | ENT_IGNORE), + ($target ?: "_new"), + htmlspecialchars($url, ENT_QUOTES | ENT_IGNORE), + ($target ?: "_new"), + $windowprops, + ($extras ? ' ' . $extras : ''), + ($linktext ?: $url), + ); +} + // Print a link for a downloadable file (including filesize) function download_link($file, $title): void { @@ -205,6 +220,20 @@ function clean($var) { return htmlspecialchars($var, ENT_QUOTES); } +// Clean out the content of one user note for printing to HTML +function clean_note($text) +{ + // Highlight PHP source + $text = highlight_php(trim($text), true); + + // Turn urls into links + return preg_replace( + '!((mailto:|(https?|ftp|nntp|news)://).*?)(\s|<|\)|"|\\\\|\'|$)!', + '\1\4', + $text, + ); +} + function display_errors($errors): void { echo '
'; diff --git a/include/shared-manual.inc b/include/shared-manual.inc index 0a7c6e8ac..821b2704b 100644 --- a/include/shared-manual.inc +++ b/include/shared-manual.inc @@ -23,7 +23,185 @@ $PGI = []; $SIDEBAR_DATA = ''; // ============================================================================= use phpweb\I18n\Languages; -use phpweb\UserNotes\UserNoteService; +use phpweb\UserNotes\Sorter; +use phpweb\UserNotes\UserNote; + +/** + * Print out all user notes for this manual page + * + * @param array $notes + */ +function manual_notes($notes):void { + global $LANG; + + // Get needed values + list($filename) = $GLOBALS['PGI']['this']; + + // Drop file extension from the name + if (substr($filename, -4) == '.php') { + $filename = substr($filename, 0, -4); + } + + $sorter = new Sorter(); + $sorter->sort($notes); + + $repo = strtolower($LANG); + $addNote = autogen('add_a_note', $LANG); + // Link target to add a note to the current manual page, + // and it's extended form with a [+] image + $addnotelink = '/manual/add-note.php?sect=' . $filename . + '&repo=' . $repo . + '&redirect=' . $_SERVER['BASE_HREF']; + $addnotesnippet = make_link( + $addnotelink, + "+$addNote", + ); + + $num_notes = count($notes); + $noteCountHtml = ''; + if ($num_notes) { + $noteCountHtml = "$num_notes note" . ($num_notes == 1 ? '' : 's') . ""; + } + + $userContributedNotes = autogen('user_contributed_notes', $LANG); + echo << +
+ {$addnotesnippet} +

$userContributedNotes {$noteCountHtml}

+
+END_USERNOTE_HEADER; + + // If we have no notes, then inform the user + if ($num_notes === 0) { + $noUserContributedNotes = autogen('no_user_notes', $LANG); + echo "\n
$noUserContributedNotes
"; + } else { + // If we have notes, print them out + echo '
'; + foreach ($notes as $note) { + manual_note_display($note); + } + echo "
\n"; + echo "
$addnotesnippet
\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 = << +
+ up +
+
+ down +
+
+ {$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, + 'edit note', + 'admin', + 'scrollbars=yes,width=650,height=400', + ) . "\n " . + + make_popup_link( + 'https://main.php.net/manage/user-notes.php?action=reject+' . $note->id, + 'reject note', + 'admin', + 'scrollbars=no,width=300,height=200', + ) . "\n " . + + make_popup_link( + 'https://main.php.net/manage/user-notes.php?action=delete+' . $note->id, + 'delete note', + '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 = []; @@ -120,9 +298,7 @@ function manual_setup($setup): void { if (substr($filename, -4) == '.php') { $filename = substr($filename, 0, -4); } - - $userNoteService = new UserNoteService(); - $USERNOTES = $userNoteService->load($filename); + $USERNOTES = manual_notes_load($filename); if ($USERNOTES) { $note = current($USERNOTES); $timestamps[] = $note->ts; @@ -246,14 +422,35 @@ function manual_footer($setup): void { CONTRIBUTE; - $userNoteService = new UserNoteService(); - $userNoteService->display($USERNOTES); + manual_notes($USERNOTES); 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"]) @@ -280,6 +477,7 @@ function autogen(string $text, string $lang) { static $translations = []; $lang = ($lang === "") ? "en" : $lang; + $lang = strtolower($lang); if (isset($translations[$lang])) { if (isset($translations[$lang][$text]) && $translations[$lang][$text] !== "") { return $translations[$lang][$text]; diff --git a/manual/add-note.php b/manual/add-note.php index 522c4b509..4cb665136 100644 --- a/manual/add-note.php +++ b/manual/add-note.php @@ -8,7 +8,6 @@ include_once __DIR__ . '/../include/shared-manual.inc'; include __DIR__ . '/spam_challenge.php'; use phpweb\UserNotes\UserNote; -use phpweb\UserNotes\UserNoteService; site_header("Add Manual Note", ['css' => 'add-note.css']); @@ -147,10 +146,9 @@ if ($process) { if ($error) { echo "

$error

\n"; } // Print out preview of note - $userNoteService = new UserNoteService(); echo '

This is what your entry will look like, roughly:

'; echo '
'; - $userNoteService->displaySingle(new UserNote('', '', '', time(), $user, $note)); + manual_note_display(new UserNote('', '', '', time(), $user, $note)); echo '


'; } diff --git a/manual/vote-note.php b/manual/vote-note.php index 94b4f69e8..d07689e8e 100644 --- a/manual/vote-note.php +++ b/manual/vote-note.php @@ -1,7 +1,4 @@ load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) { + if (isset($_SERVER['HTTP_X_JSON']) && $_SERVER['HTTP_X_JSON'] == 'On' && !empty($_REQUEST['id']) && !empty($_REQUEST['page']) && ($N = manual_notes_load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) { $response = []; $hash = substr(md5($_REQUEST['page']), 0, 16); $notes_file = $_SERVER['DOCUMENT_ROOT'] . "/backend/notes/" . substr($hash, 0, 2) . "/$hash"; @@ -55,7 +51,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') { echo json_encode($response); exit; } - if (!empty($_REQUEST['id']) && !empty($_REQUEST['page']) && ($N = $notes->load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) { + if (!empty($_REQUEST['id']) && !empty($_REQUEST['page']) && ($N = manual_notes_load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) { if (!empty($_POST['challenge']) && !empty($_POST['func']) || empty($_POST['arga']) || empty($_POST['argb'])) { if (!test_answer($_POST['func'], $_POST['arga'], $_POST['argb'], $_POST['challenge'])) { $error = "Incorrect answer! Please try again."; @@ -100,7 +96,7 @@ else { site_header("Vote On User Notes"); $headerset = true; - if (!empty($_REQUEST['id']) && !empty($_REQUEST['page']) && ($N = $notes->load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) { + if (!empty($_REQUEST['id']) && !empty($_REQUEST['page']) && ($N = manual_notes_load($_REQUEST['page'])) && array_key_exists($_REQUEST['id'], $N) && !empty($_REQUEST['vote']) && ($_REQUEST['vote'] === 'up' || $_REQUEST['vote'] === 'down')) { ?>

Voting

@@ -122,7 +118,7 @@ else { displaySingle($N[$_REQUEST['id']], false); + manual_note_display($N[$_REQUEST['id']], false); ?>

"><< Back to user notes page

@@ -175,7 +171,7 @@ if (!$headerset) { displaySingle($N[$_REQUEST['id']], false); + manual_note_display($N[$_REQUEST['id']], false); ?>

"><< Back to user notes page

diff --git a/src/UserNotes/UserNoteService.php b/src/UserNotes/UserNoteService.php deleted file mode 100644 index 5e49ad9b5..000000000 --- a/src/UserNotes/UserNoteService.php +++ /dev/null @@ -1,237 +0,0 @@ - - */ - public function 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 all user notes for this manual page - * - * @param array $notes - */ - public function display($notes):void { - global $LANG; - - // Get needed values - list($filename) = $GLOBALS['PGI']['this']; - - // Drop file extension from the name - if (substr($filename, -4) == '.php') { - $filename = substr($filename, 0, -4); - } - - $sorter = new Sorter(); - $sorter->sort($notes); - - $addNote = autogen('add_a_note', $LANG); - $repo = strtolower($LANG); - // Link target to add a note to the current manual page, - // and it's extended form with a [+] image - $addnotelink = '/manual/add-note.php?sect=' . $filename . - '&repo=' . $repo . - '&redirect=' . $_SERVER['BASE_HREF']; - $addnotesnippet = make_link( - $addnotelink, - "+$addNote", - ); - - $num_notes = count($notes); - $noteCountHtml = ''; - if ($num_notes) { - $noteCountHtml = "$num_notes note" . ($num_notes == 1 ? '' : 's') . ""; - } - - $userContributedNotes = autogen('user_contributed_notes', $LANG); - echo << -
- {$addnotesnippet} -

$userContributedNotes {$noteCountHtml}

-
-END_USERNOTE_HEADER; - - // If we have no notes, then inform the user - if ($num_notes === 0) { - $noUserContributedNotes = autogen('no_user_notes', $LANG); - echo "\n
$noUserContributedNotes
"; - } else { - // If we have notes, print them out - echo '
'; - foreach ($notes as $note) { - $this->displaySingle($note); - } - echo "
\n"; - echo "
$addnotesnippet
\n"; - } - echo ""; - } - - /** - * Print out one user note entry - */ - public function displaySingle(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 = $this->relTime($date); - $fdatestr = $date->format("Y-m-d h:i"); - $text = $this->cleanContent($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 = << -
- up -
-
- down -
-
- {$vote} -
- -VOTEDIV; - } else { - $votediv = null; - } - - // If the viewer is logged in, show admin options - if (isset($_COOKIE['IS_DEV']) && $note->id) { - - $admin = "\n \n " . - - $this->makePopupLink( - 'https://main.php.net/manage/user-notes.php?action=edit+' . $note->id, - 'edit note', - 'admin', - 'scrollbars=yes,width=650,height=400', - ) . "\n " . - - $this->makePopupLink( - 'https://main.php.net/manage/user-notes.php?action=reject+' . $note->id, - 'reject note', - 'admin', - 'scrollbars=no,width=300,height=200', - ) . "\n " . - - $this->makePopupLink( - 'https://main.php.net/manage/user-notes.php?action=delete+' . $note->id, - 'delete note', - 'admin', - 'scrollbars=no,width=300,height=200', - ) . "\n "; - - } else { - $admin = ''; - } - - echo <<{$votediv}{$name}{$admin}
{$datestr}
-
-{$text} -
- -USER_NOTE_TEXT; - } - - // Clean out the content of one user note for printing to HTML - private function cleanContent(string $text): string - { - // Highlight PHP source - $text = highlight_php(trim($text), true); - - // Turn urls into links - return preg_replace( - '!((mailto:|(https?|ftp|nntp|news)://).*?)(\s|<|\)|"|\\\\|\'|$)!', - '\1\4', - $text, - ); - } - - /** - * This function takes a DateTime object and returns a formated string of the time difference relative to now - */ - private function relTime(\DateTime $date): string - { - $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; - } - - /** - * Return a hyperlink to something, within the site, that pops up a new window - */ - private function makePopupLink(string $url, string $linktext = '', string $target = '', string $windowprops = ''): string - { - return sprintf("%s", - htmlspecialchars($url, ENT_QUOTES | ENT_IGNORE), - ($target ?: "_new"), - htmlspecialchars($url, ENT_QUOTES | ENT_IGNORE), - ($target ?: "_new"), - $windowprops, - ($linktext ?: $url), - ); - } -}