grav = $grav; } /** * @return PageInterface|null */ public function getPage(): ?PageInterface { return $this->page; } /** * Get currently active form. * * @return AdminForm|null */ public function getActiveForm(): ?AdminForm { if (null === $this->form) { $post = $this->getPost(); $active = $post['__form-name__'] ?? null; $this->form = $active ? $this->getForm($active) : null; } return $this->form; } /** * Get a form. * * @param string $name * @param array $options * @return AdminForm|null */ public function getForm(string $name, array $options = []): ?AdminForm { $post = $this->getPost(); $page = $this->getPage(); $forms = $page ? $page->forms() : []; $blueprint = $forms[$name] ?? null; if (null === $blueprint) { return null; } $active = $post['__form-name__'] ?? null; $unique_id = $active && $active === $name ? ($post['__unique_form_id__'] ?? null) : null; $options += [ 'unique_id' => $unique_id, 'blueprint' => new Blueprint(null, ['form' => $blueprint]), 'submit_method' => $this->getFormSubmitMethod($name), 'nonce_name' => $this->nonce_name, 'nonce_action' => $this->nonce_action, ]; return new AdminForm($name, $options); } abstract protected function getFormSubmitMethod(string $name): callable; /** * @param string $route * @param string|null $lang * @return string */ public function getAdminUrl(string $route, string $lang = null): string { /** @var Pages $pages */ $pages = $this->grav['pages']; $admin = $this->getAdmin(); return $pages->baseUrl($lang) . $admin->base . $route; } /** * @param string $route * @param string|null $lang * @return string */ public function getAbsoluteAdminUrl(string $route, string $lang = null): string { /** @var Pages $pages */ $pages = $this->grav['pages']; $admin = $this->getAdmin(); return $pages->baseUrl($lang, true) . $admin->base . $route; } /** * Get session. * * @return SessionInterface */ public function getSession(): SessionInterface { return $this->grav['session']; } /** * @return Admin */ protected function getAdmin(): Admin { return $this->grav['admin']; } /** * @return UserInterface */ protected function getUser(): UserInterface { return $this->getAdmin()->user; } /** * @return ServerRequestInterface */ public function getRequest(): ServerRequestInterface { return $this->getAdmin()->request; } /** * @return array */ public function getPost(): array { return (array)($this->getRequest()->getParsedBody() ?? []); } /** * Translate a string. * * @param string $string * @param mixed ...$args * @return string */ public function translate(string $string, ...$args): string { /** @var Language $language */ $language = $this->grav['language']; array_unshift($args, $string); return $language->translate($args); } /** * Set message to be shown in the admin. * * @param string $message * @param string $type * @return $this */ public function setMessage(string $message, string $type = 'info'): AdminController { /** @var Message $messages */ $messages = $this->grav['messages']; $messages->add($message, $type); return $this; } /** * @return Config */ protected function getConfig(): Config { return $this->grav['config']; } /** * Check if request nonce is valid. * * @return void * @throws PageExpiredException If nonce is not valid. */ protected function checkNonce(): void { $nonce = null; $nonce_name = $this->form ? $this->form->getNonceName() : $this->nonce_name; $nonce_action = $this->form ? $this->form->getNonceAction() : $this->nonce_action; if (\in_array(strtoupper($this->getRequest()->getMethod()), ['POST', 'PUT', 'PATCH', 'DELETE'])) { $post = $this->getPost(); $nonce = $post[$nonce_name] ?? null; } /** @var Uri $uri */ $uri = $this->grav['uri']; if (!$nonce) { $nonce = $uri->param($nonce_name); } if (!$nonce) { $nonce = $uri->query($nonce_name); } if (!$nonce || !Utils::verifyNonce($nonce, $nonce_action)) { throw new PageExpiredException($this->getRequest()); } } /** * Return the best matching mime type for the request. * * @param string[] $compare * @return string|null */ protected function getAccept(array $compare): ?string { $accepted = []; foreach ($this->getRequest()->getHeader('Accept') as $accept) { foreach (explode(',', $accept) as $item) { if (!$item) { continue; } $split = explode(';q=', $item); $mime = array_shift($split); $priority = array_shift($split) ?? 1.0; $accepted[$mime] = $priority; } } arsort($accepted); // TODO: add support for image/* etc $list = array_intersect($compare, array_keys($accepted)); if (!$list && (isset($accepted['*/*']) || isset($accepted['*']))) { return reset($compare) ?: null; } return reset($list) ?: null; } /** * @param string $template * @return PageInterface */ protected function createPage(string $template): PageInterface { $page = new Page(); // Plugins may not have the correct Cache-Control header set, force no-store for the proxies. $page->expires(0); $filename = "plugin://admin/pages/admin/{$template}.md"; if (!file_exists($filename)) { throw new \RuntimeException(sprintf('Creating admin page %s failed: not found', $template)); } Admin::DEBUG && Admin::addDebugMessage("Admin page: {$template}"); $page->init(new \SplFileInfo($filename)); $page->slug($template); return $page; } /** * @param string|null $url * @param int|null $code * @return ResponseInterface */ protected function createRedirectResponse(string $url = null, int $code = null): ResponseInterface { $request = $this->getRequest(); if (null === $url || '' === $url) { $url = (string)$request->getUri(); } elseif (mb_strpos($url, '/') === 0) { $url = $this->getAbsoluteAdminUrl($url); } if (null === $code) { if (in_array($request->getMethod(), ['GET', 'HEAD'])) { $code = 302; } else { $code = 303; } } return $this->traitCreateRedirectResponse($url, $code); } /** * @param \Throwable $e * @return array */ protected function getErrorJson(\Throwable $e): array { $json = $this->traitGetErrorJson($e); $code = $e->getCode(); if ($code === 401) { $json['redirect'] = $this->getAbsoluteAdminUrl('/'); } return $json; } }