support du retour direct depuis setup()

This commit is contained in:
Jephté Clain 2025-06-10 17:55:28 +04:00
parent aaa99825f0
commit e221300ba4
10 changed files with 137 additions and 95 deletions

View File

@ -8,6 +8,7 @@ use nur\b\ExitError;
use nur\co;
use nur\config;
use nur\func;
use nur\json;
use nur\v\html5\Html5BasicErrorPage;
use nur\v\model\IChildComponent;
use nur\v\model\IComponent;
@ -19,6 +20,7 @@ use nur\v\page;
use nur\v\prefix;
use nur\v\vo;
use Throwable;
use Traversable;
abstract class AbstractPageContainer implements IPageContainer {
protected static function ensure_preparec(IComponent $c, bool $afterPrepare=false): bool {
@ -41,10 +43,10 @@ abstract class AbstractPageContainer implements IPageContainer {
return false;
}
protected static function ensure_setupc(IComponent $c, bool $afterSetup=false): bool {
protected static function ensure_setupc(IComponent $c, bool $afterSetup=false, &$output=null): bool {
if (!$c->didSetup()) {
$c->beforeSetup();
$c->setup();
$output = $c->setup();
if ($afterSetup) $c->afterSetup();
return true;
}
@ -248,6 +250,7 @@ abstract class AbstractPageContainer implements IPageContainer {
function print(): void {
$page = $this->page;
page::set_current_page($page);
$output = null;
try {
$this->phase = self::PREPARE_PHASE;
@ -265,14 +268,43 @@ abstract class AbstractPageContainer implements IPageContainer {
config::configure($this->config["configure_options"]);
$this->phase = self::SETUP_PHASE;
if (self::ensure_setupc($page)) {
if (self::ensure_setupc($page, false, $output)) {
$this->overrideSetup($page);
$page->afterSetup();
}
$this->phase = self::PRINT_PHASE;
$this->overridePrint($page);
if ($output instanceof IComponent) {
self::ensure_phasec($output);
if ($this->beforePrint($output)) {
$this->haveOutput = true;
co::_print([$output]);
}
} elseif (is_callable($output)) {
if ($this->beforePrint(null)) {
$this->haveOutput = true;
$output();
}
} elseif ($output !== null) {
if ($this->beforePrint(null)) {
$this->haveOutput = true;
if (is_iterable($output)) {
header("Content-Type: application/json");
echo "[";
$sep = "";
foreach ($output as $data) {
$line = json::encode($data);
echo "$sep$line\n";
$sep = ",";
}
echo "]";
} else {
co::_print([strval($output)]);
}
}
} else {
$this->overridePrint($page);
}
} catch (Throwable $e) {
if ($e instanceof ExitError && !$e->isError()) {
# NOP
@ -293,6 +325,9 @@ abstract class AbstractPageContainer implements IPageContainer {
}
if ($page->didSetup()) {
$this->phase = self::TEARDOWN_PHASE;
if ($output instanceof IComponent) {
self::ensure_teardownc($output);
}
if (self::ensure_teardownc($page)) {
$this->overrideTeardown($page);
$page->afterTeardown();
@ -310,11 +345,14 @@ abstract class AbstractPageContainer implements IPageContainer {
protected function overrideSetup(IPage $page): void {
}
protected function beforePrint(?IComponent $component): bool {
return $component === null || $component->haveContent();
}
protected function overridePrint(IPage $page): void {
if ($page->haveContent()) {
$this->haveOutput = true;
co::_print([$page]);
}
if (!$this->beforePrint($page)) return;
$this->haveOutput = true;
co::_print([$page]);
}
protected function overrideTeardown(IPage $page): void {

View File

@ -55,7 +55,7 @@ trait TComponent {
protected $setupDone = false;
function beforeSetup(): void {}
function setup(): void {}
function setup() {}
function afterSetup(): void { $this->setupDone = true; }
function didSetup(): bool { return $this->setupDone; }

View File

@ -6,6 +6,7 @@ use nur\co;
use nur\session;
use nur\v\ly;
use nur\v\model\IBasicPage;
use nur\v\model\IComponent;
use nur\v\model\IPage;
class Html5BasicPageContainer extends Html5VanillaPageContainer {
@ -23,30 +24,31 @@ class Html5BasicPageContainer extends Html5VanillaPageContainer {
function isAutocloseSession(): bool { return $this->config["autoclose_session"]; }
protected function overridePrint(IPage $page): void {
protected function beforePrint(?IComponent $component): bool {
if ($this->isAutocloseSession()) session::close();
return parent::beforePrint($component);
}
protected function overridePrint(IPage $page): void {
if (!$this->beforePrint($page)) return;
if ($page instanceof IBasicPage) {
if ($page->haveContent()) {
$this->doResolveConfig();
$this->haveOutput = true;
$this->printStartHtml();
$this->printStartHead();
$this->printCss();
$this->printJs();
$this->printScript();
$this->printHeadTitle();
$this->printEndHead();
$this->printStartBody();
$this->printContent();
$this->printEndBody();
$this->printEndHtml();
}
$this->doResolveConfig();
$this->haveOutput = true;
$this->printStartHtml();
$this->printStartHead();
$this->printCss();
$this->printJs();
$this->printScript();
$this->printHeadTitle();
$this->printEndHead();
$this->printStartBody();
$this->printContent();
$this->printEndBody();
$this->printEndHtml();
} else {
# si ce n'est pas une instance de IBasicPage, l'imprimer tel quel
if ($page->haveContent()) {
$this->haveOutput = true;
co::_write([$this->page]);
}
$this->haveOutput = true;
co::_write([$page]);
}
}

View File

@ -12,69 +12,65 @@ use nur\v\v;
class Html5NavigablePageContainer extends Html5BasicPageContainer {
protected function overridePrint(IPage $page): void {
if ($this->isAutocloseSession()) session::close();
if (!$this->beforePrint($page)) return;
if ($page instanceof IBasicPage) {
if ($page->haveContent()) {
$this->doResolveConfig();
$this->haveOutput = true;
$this->printStartHtml();
$this->printStartHead();
$this->printCss();
$this->printJs();
$this->printScript();
$this->printHeadTitle();
$this->printEndHead();
$this->printStartBody();
if ($page instanceof INavigablePage) {
$showNavigation = $page->navigationShowNavigation();
$implementsOwnLayout = $page->navigationImplementsOwnLayout();
$containerOptions = $page->CONTAINER_OPTIONS();
} else {
$showNavigation = false;
$containerOptions = null;
}
if ($showNavigation) {
$page->beforePrintStartNavigation();
if ($implementsOwnLayout) $page->printStartNavigation();
else $this->printStartNavigation($page->NAVBAR_OPTIONS());
$page->afterPrintStartNavigation();
$page->beforePrintNavigation();
$page->printNavigation();
$page->afterPrintNavigation();
$page->beforePrintEndNavigation();
if ($implementsOwnLayout) $page->printEndNavigation();
else $this->printEndNavigation();
$page->afterPrintEndNavigation();
$page->beforePrintStartContainer();
if ($implementsOwnLayout) $page->printStartContainer();
else $this->printStartContainer($containerOptions);
$page->afterPrintStartContainer();
} else {
$this->printStartContainer($containerOptions);
}
$this->printContent();
# s'assurer que le layout est correctement fermé
ly::end();
if ($showNavigation) {
$page->beforePrintEndContainer();
if ($implementsOwnLayout) $page->printEndContainer();
else $this->printEndContainer();
$page->afterPrintEndContainer();
} else {
$this->printEndContainer();
}
$this->printEndBody();
$this->printEndHtml();
$this->doResolveConfig();
$this->haveOutput = true;
$this->printStartHtml();
$this->printStartHead();
$this->printCss();
$this->printJs();
$this->printScript();
$this->printHeadTitle();
$this->printEndHead();
$this->printStartBody();
if ($page instanceof INavigablePage) {
$showNavigation = $page->navigationShowNavigation();
$implementsOwnLayout = $page->navigationImplementsOwnLayout();
$containerOptions = $page->CONTAINER_OPTIONS();
} else {
$showNavigation = false;
$containerOptions = null;
}
if ($showNavigation) {
$page->beforePrintStartNavigation();
if ($implementsOwnLayout) $page->printStartNavigation();
else $this->printStartNavigation($page->NAVBAR_OPTIONS());
$page->afterPrintStartNavigation();
$page->beforePrintNavigation();
$page->printNavigation();
$page->afterPrintNavigation();
$page->beforePrintEndNavigation();
if ($implementsOwnLayout) $page->printEndNavigation();
else $this->printEndNavigation();
$page->afterPrintEndNavigation();
$page->beforePrintStartContainer();
if ($implementsOwnLayout) $page->printStartContainer();
else $this->printStartContainer($containerOptions);
$page->afterPrintStartContainer();
} else {
$this->printStartContainer($containerOptions);
}
$this->printContent();
# s'assurer que le layout est correctement fermé
ly::end();
if ($showNavigation) {
$page->beforePrintEndContainer();
if ($implementsOwnLayout) $page->printEndContainer();
else $this->printEndContainer();
$page->afterPrintEndContainer();
} else {
$this->printEndContainer();
}
$this->printEndBody();
$this->printEndHtml();
} else {
# si ce n'est pas une instance de IBasicPage, l'imprimer tel quel
if ($page->haveContent()) {
$this->haveOutput = true;
co::_write([$this->page]);
}
$this->haveOutput = true;
co::_write([$this->page]);
}
}

View File

@ -12,6 +12,7 @@ use nur\v\base\AbstractPageContainer;
use nur\v\base\MenuManager;
use nur\v\fo;
use nur\v\ly;
use nur\v\model\IBasicPage;
use nur\v\model\IComponent;
use nur\v\model\IPage;
use nur\v\model\IPlugin;
@ -46,7 +47,8 @@ class Html5VanillaPageContainer extends AbstractPageContainer {
}
protected function overridePrint(IPage $page): void {
if ($page->haveContent()) {
if (!$this->beforePrint($page)) return;
if ($page instanceof IPage) {
$this->doResolveConfig();
$this->haveOutput = true;
$this->printStartHtml();
@ -62,6 +64,10 @@ class Html5VanillaPageContainer extends AbstractPageContainer {
$this->printContent();
$this->printEndBody();
$this->printEndHtml();
} else {
# si ce n'est pas une instance de IPage, l'imprimer tel quel
$this->haveOutput = true;
co::_write([$page]);
}
}

View File

@ -43,7 +43,7 @@ interface IComponent extends IPlugin {
function beforeSetup(): void;
/** initialiser le composant */
function setup(): void;
function setup();
/** marquer le composant comme initialisé */
function afterSetup(): void;

View File

@ -23,7 +23,7 @@ class AppCasauthPage extends AbstractPage {
/** @var string nom de l'utilisateur connecté */
private $user;
function setup(): void {
function setup() {
$destUrl = $retUrl = null;
$user = false;
if ($user === false) $user = A::get($_SERVER, "REMOTE_USER", false);

View File

@ -9,7 +9,7 @@ class AppDevauthPage extends AInitPage {
/** @var string nom de l'utilisateur connecté */
private $user;
function setup(): void {
function setup() {
if (!$this->isDevauthAllowed()) {
page::redirect($this->getLoginUrl());
}

View File

@ -23,7 +23,7 @@ class AppExtauthPage extends AbstractPage {
/** @var string nom de l'utilisateur connecté */
private $user;
function setup(): void {
function setup() {
$destUrl = null;
$user = false;
if ($user === false) $user = A::get($_SERVER, "REMOTE_USER", false);

View File

@ -16,7 +16,7 @@ class AppLogoutPage extends AInitPage {
return static::DEBUG || F::get("d");
}
function setup(): void {
function setup() {
cookie::set("MOD_AUTH_CAS", false);
cookie::set("MOD_AUTH_CAS_S", false);
authz::manager()->resetSession(authz::DISCONNECTED);