context -> record content -> form). These live together * instead because the contract above is what must not drift between them, and * it had no single home: each dead end carried its own copy of the reasoning * and a third was about to carry a third copy. */ class ABJ_404_Solution_RedirectEditDeadEndRenderer { /** @var ABJ_404_Solution_RedirectEditFormPresenter */ private $presenter; /** @var ABJ_404_Solution_Logging */ private $logger; /** * @param ABJ_404_Solution_RedirectEditFormPresenter $presenter Builds the notice markup. * @param ABJ_404_Solution_Logging $logger Receives the below-error-level line. */ public function __construct($presenter, $logger) { $this->presenter = $presenter; $this->logger = $logger; } /** * The requested ids no longer have a row -- or the request named no usable * id at all, which is a different message: naming an empty id list would * print "Redirects were not found." * * Takes the page context rather than resolving the destination again, so * the notice's way back can never disagree with the way back the edit form * itself would have offered. * * @param array{backUrl: string, backLabel: string} $context From editRedirectPageContext(). * @param array $ids The redirect ids the request asked for. Empty * when the request carried no usable id at all. * @return null Always null, so a caller can `return $renderer->missingRedirects(...)`. */ public function missingRedirects(array $context, array $ids) { $backUrl = $context['backUrl']; $backLabel = $context['backLabel']; if (empty($ids)) { echo $this->presenter->buildNoRedirectIdsNoticeHtml($backUrl, $backLabel); $this->logger->debugMessage('Edit redirect page: request carried no usable redirect id.'); return null; } echo $this->presenter->buildMissingRedirectsNoticeHtml($ids, $backUrl, $backLabel); $this->logger->debugMessage('Edit redirect page: no redirect row exists for requested id(s): ' . esc_html(implode(', ', array_map('strval', $ids)))); return null; } /** * The selection is larger than one edit screen may carry, so it is refused. * * RedirectEditRequest's cap bounds the work one request can cause, but a * bound the admin cannot see is a silent partial edit: they selected N, the * screen would render MAX_SELECTED_IDS of them with nothing marking the * boundary, and the save that follows applies to exactly that subset. * * @param array{backUrl: string, backLabel: string} $context From editRedirectPageContext(). * @param int $requestedCount How many redirects the request actually named. * @return null Always null, so a caller can `return $renderer->tooManySelected(...)`. */ public function tooManySelected(array $context, int $requestedCount) { $maximum = ABJ_404_Solution_RedirectEditRequest::MAX_SELECTED_IDS; echo $this->presenter->buildTooManySelectedNoticeHtml( $requestedCount, $maximum, $context['backUrl'], $context['backLabel']); $this->logger->debugMessage('Edit redirect page: refused a selection of ' . $requestedCount . ' redirects; the maximum is ' . $maximum . '.'); return null; } }