RootlineUtility

A utility resolving and Caching the Rootline generation

Table of Contents

Constants

RUNTIME_CACHE_TAG  = 'rootline-utility'

Properties

$cache  : FrontendInterface
$cacheIdentifier  : string
$context  : Context
$languageUid  : int
$mountPointParameter  : string
$pageRepository  : PageRepository
$pageUid  : int
$parsedMountPointParameters  : array<string|int, int>
$runtimeCache  : FrontendInterface
$workspaceUid  : int

Methods

__construct()  : mixed
get()  : array<string|int, mixed>
Returns the actual rootline without the tree root (uid=0), including the page with $this->pageUid
cleanWorkspaceResolvedPageRecord()  : array<string|int, mixed>|null
columnHasRelationToResolve()  : bool
Checks whether the TCA Configuration array of a column describes a relation which is not stored as CSV in the record
createInitialQueryBuilder()  : QueryBuilder
Creates the QueryBuilder for the recursive CTE initial part within {@see self::getRootlineRecords()}.
createQueryBuilder()  : QueryBuilder
createTraversalQueryBuilder()  : QueryBuilder
Creates the QueryBuilder for the recursive CTE traversal part within {@see self::getRootlineRecords()}.
enrichPageRecordArray()  : array<string|int, mixed>
enrichWithRelationFields()  : array<string, string|int|float|null>
Resolve relations as defined in TCA and add them to the provided $pageRecord array.
generateRootlineCache()  : void
Actual function to generate the rootline and cache it
getCacheIdentifier()  : string
getPagesFields()  : array<string|int, mixed>
getRecordArray()  : array<string, string|int|float|null>
Queries the database for the page record and returns it.
getRootlineRecords()  : array<string|int, mixed>
Get enriched RootLine page records.
getWorkspaceResolvedPageRecord()  : array<string|int, mixed>|null
{@see self::getRecordArray()} used {@see PageRepository::versionOL()} to compose workspace overlayed records in the based, bypassing access checks (aka enableFields) resulting in multiple queries. This constellation of method and database query chains can be condensed down to a single database query, which this method uses to retrieve the equal workspace overlay database page record in one and thus reducing overall database query count.
isMountedPage()  : bool
Checks whether the current Page is a Mounted Page (according to the MP-URL-Parameter)
parseMountPointParameter()  : void
Parse the MountPoint Parameters Splits the MP-Param via "," for several nested mountpoints and afterwords registers the mountpoint configurations
processMountedPage()  : array<string, string|int|float|null>
Enhances with mount point information or replaces the node if needed
resolveMovePointerId()  : int|null
Fetched the UID of the versioned record if the live record has been moved in a workspace.
resolvePageId()  : int
Fetches the UID of the page.
resolvePageRecord()  : array<string|int, mixed>|null
sanitizeMountPointParameter()  : string
Sanitize the MountPoint Parameter Splits the MP-Param via "," and removes mountpoints that don't have the format \d+-\d+

Constants

RUNTIME_CACHE_TAG

public mixed RUNTIME_CACHE_TAG = 'rootline-utility'
Internal

Properties

$cacheIdentifier

protected string $cacheIdentifier

$languageUid

protected int $languageUid = 0

$mountPointParameter

protected string $mountPointParameter

$parsedMountPointParameters

protected array<string|int, int> $parsedMountPointParameters = []

$workspaceUid

protected int $workspaceUid = 0

Methods

cleanWorkspaceResolvedPageRecord()

protected cleanWorkspaceResolvedPageRecord([array<string|int, mixed>|null $row = null ]) : array<string|int, mixed>|null
Parameters
$row : array<string|int, mixed>|null = null
Return values
array<string|int, mixed>|null

columnHasRelationToResolve()

Checks whether the TCA Configuration array of a column describes a relation which is not stored as CSV in the record

protected columnHasRelationToResolve(array<string|int, mixed> $configuration) : bool
Parameters
$configuration : array<string|int, mixed>

TCA configuration to check

Return values
bool

TRUE, if it describes a non-CSV relation

createInitialQueryBuilder()

Creates the QueryBuilder for the recursive CTE initial part within {@see self::getRootlineRecords()}.

protected createInitialQueryBuilder(QueryBuilder $cte, int $pageId, int $workspaceId) : QueryBuilder

Not to be used standalone. self::getRootlineRecords() method docblock for overall CTE information.

Parameters
$cte : QueryBuilder
$pageId : int
$workspaceId : int
Return values
QueryBuilder

createTraversalQueryBuilder()

Creates the QueryBuilder for the recursive CTE traversal part within {@see self::getRootlineRecords()}.

protected createTraversalQueryBuilder(QueryBuilder $cte, int $workspaceId) : QueryBuilder

Not to be used standalone. self::getRootlineRecords() method docblock for overall CTE information.

Parameters
$cte : QueryBuilder
$workspaceId : int
Return values
QueryBuilder

enrichPageRecordArray()

protected enrichPageRecordArray(array<string|int, mixed> $row, int $pageId) : array<string|int, mixed>
Parameters
$row : array<string|int, mixed>
$pageId : int
Return values
array<string|int, mixed>

enrichWithRelationFields()

Resolve relations as defined in TCA and add them to the provided $pageRecord array.

protected enrichWithRelationFields(int $uid, array<string, string|int|float|null> $pageRecord) : array<string, string|int|float|null>
Parameters
$uid : int

page ID

$pageRecord : array<string, string|int|float|null>

Page record (possibly overlaid) to be extended with relations

Tags
throws
PagePropertyRelationNotFoundException
Return values
array<string, string|int|float|null>

$pageRecord with additional relations

getCacheIdentifier()

protected getCacheIdentifier([int|null $otherUid = null ]) : string
Parameters
$otherUid : int|null = null
Return values
string

getPagesFields()

protected getPagesFields() : array<string|int, mixed>
Return values
array<string|int, mixed>

getRecordArray()

Queries the database for the page record and returns it.

protected getRecordArray(int $uid) : array<string, string|int|float|null>
Parameters
$uid : int

Page id

Tags
throws
PageNotFoundException
Return values
array<string, string|int|float|null>

getRootlineRecords()

Get enriched RootLine page records.

protected getRootlineRecords(int $pageId, int $workspaceId) : array<string|int, mixed>

This method uses a recursive common-table-expression (CTE) doing the first workspace overlay handling withing the RootLine traversal. Language overlay and record enrichment (references data) are applied on retrieved records.

In case a received record is a mounted page, a new instance of RootlineUtility is created to retrieve the mounted page rootline and result spliced together.

In case only live-workspace rootline is required, for example in normal frontend visitors without backend login and selected workspaces, the created CTE is simplified avoiding irrelevant joins and further improve performance in that case.

Note that the created recursive CTE contains two guards against cycling rootline issues:

Guard 1 - ancestor path guard:

During the recursing a uid path is created (__CTE_PATH__) and in case that a page is already contained in the parent record __CTE_PATH__ the flag field __CTE_IS_CYCLE__ is set to 1, otherwise it is 0.

If the parent record __CTE_IS_CYLCE__ is 1 no records are retrieved which retrieves a duplicate page record except of this flag. During the record retrieval CircularRootLineException is thrown to abort and state this crucial data corruption.

This guard is designed to abort cycling recursion on the database side as early as possible while still transport the cycling issue information to this method.

Guard 2 - max recursion level guard:

During the recursive CTE handling recursion level info is created (__CTE_LEVEL__) and used as a hard recursion limit fence. That means, if the level reaches self::MAX_CTE_TRAVERSAL_LEVELS no more page records are received. In the case that neither GUARD 1, nor PID=0 abort criteria is reached and max level hit a meaningful BrokenRootLineException exception is thrown.

Note that further improvements are possible, for example adding language overlay handling directly to the CTE when strategy how to deal with the three dispatched PSR-14 events in PageRepository has been made up.

Parameters
$pageId : int
$workspaceId : int
Tags
todo

As already mentioned above, mountpoint pages are resolved by calling a new RootlineUtility instance which prevents the detection of circular mountpoint configuration like in the prior implementation. A way to add mountpoint page replacements within the CTE needs to be evaluated and implemented to make a circular mountpoint configuration finally detectable. At least first cycling rootline revealing database data corruption are now included.

throws
BrokenRootLineException
throws
CircularRootLineException
throws
Exception
Return values
array<string|int, mixed>

getWorkspaceResolvedPageRecord()

{@see self::getRecordArray()} used {@see PageRepository::versionOL()} to compose workspace overlayed records in the based, bypassing access checks (aka enableFields) resulting in multiple queries. This constellation of method and database query chains can be condensed down to a single database query, which this method uses to retrieve the equal workspace overlay database page record in one and thus reducing overall database query count.

protected getWorkspaceResolvedPageRecord(int $pageId, int $workspaceId) : array<string|int, mixed>|null
Parameters
$pageId : int
$workspaceId : int
Return values
array<string|int, mixed>|null

isMountedPage()

Checks whether the current Page is a Mounted Page (according to the MP-URL-Parameter)

protected isMountedPage(int $pageId) : bool
Parameters
$pageId : int
Return values
bool

parseMountPointParameter()

Parse the MountPoint Parameters Splits the MP-Param via "," for several nested mountpoints and afterwords registers the mountpoint configurations

protected parseMountPointParameter() : void

processMountedPage()

Enhances with mount point information or replaces the node if needed

protected processMountedPage(array<string, string|int|float|null> $mountedPageData, array<string, string|int|float|null> $mountPointPageData) : array<string, string|int|float|null>
Parameters
$mountedPageData : array<string, string|int|float|null>

page record array of mounted page

$mountPointPageData : array<string, string|int|float|null>

page record array of mount point page

Tags
throws
BrokenRootLineException
Return values
array<string, string|int|float|null>

resolveMovePointerId()

Fetched the UID of the versioned record if the live record has been moved in a workspace.

protected resolveMovePointerId(int $liveId) : int|null
Parameters
$liveId : int
Return values
int|null

resolvePageId()

Fetches the UID of the page.

protected resolvePageId(int $pageId) : int

If the page was moved in a workspace, actually returns the UID of the moved version in the workspace.

Parameters
$pageId : int
Return values
int

resolvePageRecord()

protected resolvePageRecord(int $pageId) : array<string|int, mixed>|null
Parameters
$pageId : int
Return values
array<string|int, mixed>|null

sanitizeMountPointParameter()

Sanitize the MountPoint Parameter Splits the MP-Param via "," and removes mountpoints that don't have the format \d+-\d+

protected sanitizeMountPointParameter(string $mountPointParameter) : string
Parameters
$mountPointParameter : string
Return values
string

        
On this page

Search results