1<?php
2declare(strict_types = 1);
3namespace TYPO3\CMS\Core\Database\Query\Restriction;
4
5/*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18use TYPO3\CMS\Core\Context\Context;
19use TYPO3\CMS\Core\Context\VisibilityAspect;
20use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
21use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
22use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24/**
25 * A collection of restrictions to be used in frontend context.
26 * This is a replacement for PageRepository::enableFields()
27 */
28class FrontendRestrictionContainer extends AbstractRestrictionContainer
29{
30    /**
31     * @var QueryRestrictionInterface[]
32     */
33    protected $defaultRestrictionTypes = [
34        DeletedRestriction::class,
35        FrontendWorkspaceRestriction::class,
36        HiddenRestriction::class,
37        StartTimeRestriction::class,
38        EndTimeRestriction::class,
39        FrontendGroupRestriction::class,
40    ];
41
42    /**
43     * @var Context
44     */
45    protected $context;
46
47    /**
48     * FrontendRestrictionContainer constructor.
49     * Initializes the default restrictions for frontend requests
50     *
51     * @param Context $context
52     */
53    public function __construct(Context $context = null)
54    {
55        $this->context = $context ?? GeneralUtility::makeInstance(Context::class);
56        foreach ($this->defaultRestrictionTypes as $restrictionType) {
57            $this->add($this->createRestriction($restrictionType));
58        }
59    }
60
61    /**
62     * Main method to build expressions for given tables
63     * Iterates over all registered restrictions and removes the hidden restriction if preview is requested
64     *
65     * @param array $queriedTables Array of tables, where array key is table alias and value is a table name
66     * @param ExpressionBuilder $expressionBuilder Expression builder instance to add restrictions with
67     * @return CompositeExpression The result of query builder expression(s)
68     */
69    public function buildExpression(array $queriedTables, ExpressionBuilder $expressionBuilder): CompositeExpression
70    {
71        $constraints = [];
72        foreach ($this->restrictions as $restriction) {
73            foreach ($queriedTables as $tableAlias => $tableName) {
74                $disableRestriction = false;
75                if ($restriction instanceof HiddenRestriction) {
76                    /** @var VisibilityAspect $visibilityAspect */
77                    $visibilityAspect = $this->context->getAspect('visibility');
78                    // If display of hidden records is requested, we must disable the hidden restriction.
79                    if ($tableName === 'pages') {
80                        $disableRestriction = $visibilityAspect->includeHiddenPages();
81                    } else {
82                        $disableRestriction = $visibilityAspect->includeHiddenContent();
83                    }
84                }
85                if (!$disableRestriction) {
86                    $constraints[] = $restriction->buildExpression([$tableAlias => $tableName], $expressionBuilder);
87                }
88            }
89        }
90        return $expressionBuilder->andX(...$constraints);
91    }
92}
93