setAspect(GeneralUtility::makeInstance(VisibilityAspect::class, true, true, false)) * ``` * * ... which in turn can be injected in the various places where TYPO3 uses contexts. * * * Classic aspect names to be used are: * - date (DateTimeAspect) * - workspace * - visibility * - frontend.user * - backend.user * - language * - frontend.preview [if EXT:frontend is loaded] */ class Context implements SingletonInterface { /** * @var AspectInterface[] */ protected array $aspects = []; /** * Checks if an aspect exists in the context */ public function hasAspect(string $name): bool { return match ($name) { 'date', 'visibility', 'backend.user', 'frontend.user', 'workspace', 'language' => true, default => isset($this->aspects[$name]), }; } /** * Returns an aspect, if it is set * * @throws AspectNotFoundException * @return ($name is 'date' ? DateTimeAspect * : ($name is 'visibility' ? VisibilityAspect * : ($name is 'backend.user' ? UserAspect * : ($name is 'frontend.user' ? UserAspect * : ($name is 'workspace' ? WorkspaceAspect * : ($name is 'language' ? LanguageAspect : AspectInterface)))))) */ public function getAspect(string $name): AspectInterface { if (!isset($this->aspects[$name])) { // Ensure the default aspects are available, this is mostly necessary for tests to not set up everything switch ($name) { case 'date': $this->setAspect('date', new DateTimeAspect(DateTimeFactory::createFromTimestamp($GLOBALS['EXEC_TIME']))); break; case 'visibility': $this->setAspect('visibility', new VisibilityAspect()); break; case 'backend.user': $this->setAspect('backend.user', new UserAspect()); break; case 'frontend.user': $this->setAspect('frontend.user', new UserAspect()); break; case 'workspace': $this->setAspect('workspace', new WorkspaceAspect()); break; case 'language': $this->setAspect('language', new LanguageAspect()); break; default: throw new AspectNotFoundException('No aspect named "' . $name . '" found.', 1527777641); } } return $this->aspects[$name]; } /** * Returns a property from the aspect, but only if the property is found. * * @throws AspectNotFoundException */ public function getPropertyFromAspect(string $name, string $property, mixed $default = null): mixed { if (!$this->hasAspect($name)) { throw new AspectNotFoundException('No aspect named "' . $name . '" found.', 1527777868); } try { return $this->getAspect($name)->get($property); } catch (AspectPropertyNotFoundException) { return $default; } } /** * Sets an aspect, or overrides an existing aspect if an aspect is already set */ public function setAspect(string $name, AspectInterface $aspect): void { $this->aspects[$name] = $aspect; } /** * @internal Using this method is a sign of a technical debt. It is used by RedirectService, * but may vanish any time when this is fixed, and thus internal. * In general, Context aspects should never have to be unset. * When a middleware has to use this method, it is either located * at the wrong position in the chain, or has some other dependency issue. */ public function unsetAspect(string $name): void { unset($this->aspects[$name]); } }