nur-sery/nur_src/v/page.php

209 lines
6.7 KiB
PHP

<?php
namespace nur\v;
use nur\A;
use nur\config;
use nur\v\html5\Html5NavigablePageContainer;
use nur\v\model\IPage;
use nur\v\model\IPageContainer;
class page {
const CONTAINER_CLASS = Html5NavigablePageContainer::class;
/** @var string */
protected static $container_class;
/**
* spécifier la classe à utiliser pour instancier le container.
*
* cette méthode *doit* être appelée avant d'appeler la méthode container()
*/
static final function set_container_class(string $container_class) {
self::$container_class = $container_class;
}
/** @var IPageContainer */
protected static $container;
/** obtenir l'instance globale de container */
static final function container(): IPageContainer {
if (self::$container === null) {
$container_class = self::$container_class;
if ($container_class === null) $container_class = static::CONTAINER_CLASS;
self::$container = new $container_class();
}
return self::$container;
}
static final function render(?IPage $page=null): void {
config::set_fact(config::FACT_WEB_APP);
config::configure(config::CONFIGURE_INITIAL_ONLY);
$pc = self::container();
if ($page === null) {
config::configure(config::CONFIGURE_ROUTES_ONLY);
$page = route::get_page();
}
$pc->setPage($page);
$pc->print();
}
/** @var IPage */
protected static $page;
/** spécifier la page courante. cette opération est automatique */
static final function set_current_page(IPage $page) {
self::$page = $page;
}
private static function _qsbu(string $url, array $params): string {
if (count($params) > 0 && $params[0] === true) {
$query_string = $_SERVER["QUERY_STRING"];
if ($query_string) $url .= "?$query_string";
$params = array_slice($params, 1);
}
return html::bu($url, ...$params);
}
/**
* retourner le chemin de la page courante depuis la racine.
*
* cette méthode existe parce que l'url "" renvoie vers la page courante mais
* avec tous ses paramètres. on veut parfois rediriger vers la page courante
* sans aucun paramètre.
*
* si le premier argument de cette méthode est true, retourner le chemin de la
* page courante suivie de la valeur de $_SERVER["QUERY_STRING"]
*
* dans tous les cas, les arguments de params sont rajoutés
*
* @see prefix::get_default_self() pour une information sur l'exactitude de la
* valeur retournée
*/
static final function self(...$params): string {
$self = $_SERVER["SCRIPT_NAME"];
return self::_qsbu($self, $params);
}
/** comme {@link self()} mais avec un chemin absolu */
static final function origself(...$params): string {
$self = prefix::get_default_self();
return self::_qsbu($self, $params);
}
/**
* construire un url avec les paramètres spécifiés. le cas échéant, corriger
* l'url en fonction de self
*
* cette méthode sera utilisée notamment pour des liens vers des resources
* statiques
*/
static final function resu(string $url, ...$params): string {
$prefix = self::$page->getSelfRelativePrefix();
return html::bu(prefix::add($url, $prefix), ...$params);
}
/**
* construire un url vers le composant destination avec les paramètres
* spécifiés. le cas échéant, corriger l'url en fonction de self
*
* @param string|IPage $dest composant destination
*/
static final function dynu($dest, ...$params): string {
$prefix = self::$page->getSelfRelativePrefix();
$url = route::get_path($dest);
return html::bu(prefix::add($url, $prefix), ...$params);
}
const BU_STATIC_PARTS = ["scheme", "host", "port", "query", "fragment"];
/**
* méthode générique pour construire une url. utiliser des heuristiques pour
* déterminer si la destination est une url statique ou si c'est un composant
*/
static final function bu($dest, ...$params): string {
$dyn = true;
if (is_object($dest)) $dest = get_class($dest);
if (is_string($dest)) {
# heuristiques pour déterminer si c'est une url statique
$parts = parse_url($dest);
foreach (self::BU_STATIC_PARTS as $part) {
if (A::has($parts, $part)) {
# y a-t-il au moins une partie d'une url statique?
$dyn = false;
break;
}
}
if ($dyn) {
# s'il n'y a qu'un chemin, tester si ça ressemble à une url
$path = A::get($parts, "path", "");
if ($path === "" || $path === ".") $dyn = false;
elseif (strpos($path, "/") !== false) $dyn = false;
elseif (preg_match('/\.(php|html)\b/', $path)) $dyn = false;
}
}
if ($dyn) {
# tenir compte du préfixe, puisque les chemins des composants sont
# toujours exprimés depuis la racine
$prefix = self::$page->getSelfRelativePrefix();
if ($dest !== null) {
$url = route::get_path($dest);
$url = prefix::add($url, $prefix);
} else {
$url = $prefix;
}
return html::bu($url, ...$params);
} else {
# ne pas corriger une url statique: on fait confiance à l'utilisateur pour
# utiliser des chemins relatifs
return html::bu($dest, ...$params);
}
}
static final function no_cache(): void {
http::no_cache();
}
static final function content_type(string $content_type=null, string $charset=null): void {
http::content_type($content_type, $charset);
}
static final function download_as($filename, string $disposition=null): void {
http::download_as($filename, $disposition);
}
private static function _get_url($dest): string {
if ($dest === null) $url = self::self();
elseif ($dest === true || is_array($dest)) $url = self::self($dest);
else $url = self::bu($dest);
return $url;
}
static final function redirect($dest=null, bool $exit_now=true): void {
http::redirect(self::_get_url($dest), $exit_now);
}
static final function refresh($dest=null, int $delay=1, bool $exit_now=true): void {
http::refresh(self::_get_url($dest), $delay, $exit_now);
}
static final function send_no_content(bool $exit_now=true): void {
http::send_no_content($exit_now);
}
static final function send_file(string $file, bool $delete=false, bool $close_session=true, bool $add_content_length=true, bool $exit_now=true): bool {
return http::send_file($file, $delete, $close_session, $add_content_length, $exit_now);
}
static function more_time(?int $time=600) {
if ($time !== null) set_time_limit($time);
}
static function more_memory(?string $memory="256M") {
if ($memory !== null) ini_set("memory_limit", $memory);
}
static function more_resources(?int $time=600, ?string $memory="256M") {
self::more_time($time);
self::more_memory($memory);
}
}