1<?php 2 3declare(strict_types=1); 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 18namespace TYPO3\CMS\Redirects\Repository; 19 20use TYPO3\CMS\Core\Database\ConnectionPool; 21use TYPO3\CMS\Core\Database\Query\QueryBuilder; 22use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; 23use TYPO3\CMS\Core\Utility\GeneralUtility; 24 25/** 26 * Class for accessing redirect records from the database 27 * @internal 28 */ 29class RedirectRepository 30{ 31 /** 32 * @var Demand 33 */ 34 protected $demand; 35 36 /** 37 * With a possible demand object 38 * 39 * @param Demand|null $demand 40 */ 41 public function __construct(Demand $demand = null) 42 { 43 $this->demand = $demand ?? new Demand(); 44 } 45 46 /** 47 * Used within the backend module, which also includes the hidden records, but never deleted records. 48 * 49 * @return array 50 */ 51 public function findRedirectsByDemand(): array 52 { 53 return $this->getQueryBuilderForDemand() 54 ->setMaxResults($this->demand->getLimit()) 55 ->setFirstResult($this->demand->getOffset()) 56 ->execute() 57 ->fetchAll(); 58 } 59 60 /** 61 * @return int 62 */ 63 public function countRedirectsByByDemand(): int 64 { 65 return $this->getQueryBuilderForDemand()->execute()->rowCount(); 66 } 67 68 /** 69 * Prepares the QueryBuilder with Constraints from the Demand 70 * 71 * @return QueryBuilder 72 */ 73 protected function getQueryBuilderForDemand(): QueryBuilder 74 { 75 $queryBuilder = $this->getQueryBuilder(); 76 $queryBuilder 77 ->select('*') 78 ->from('sys_redirect') 79 ->orderBy('source_host') 80 ->addOrderBy('source_path'); 81 82 $constraints = []; 83 if ($this->demand->hasSourceHost()) { 84 $constraints[] =$queryBuilder->expr()->eq( 85 'source_host', 86 $queryBuilder->createNamedParameter($this->demand->getSourceHost(), \PDO::PARAM_STR) 87 ); 88 } 89 90 if ($this->demand->hasSourcePath()) { 91 $escapedLikeString = '%' . $queryBuilder->escapeLikeWildcards($this->demand->getSourcePath()) . '%'; 92 $constraints[] = $queryBuilder->expr()->like( 93 'source_path', 94 $queryBuilder->createNamedParameter($escapedLikeString, \PDO::PARAM_STR) 95 ); 96 } 97 98 if ($this->demand->hasTarget()) { 99 $escapedLikeString = '%' . $queryBuilder->escapeLikeWildcards($this->demand->getTarget()) . '%'; 100 $constraints[] = $queryBuilder->expr()->like( 101 'target', 102 $queryBuilder->createNamedParameter($escapedLikeString, \PDO::PARAM_STR) 103 ); 104 } 105 106 if ($this->demand->hasStatusCode()) { 107 $constraints[] =$queryBuilder->expr()->eq( 108 'target_statuscode', 109 $queryBuilder->createNamedParameter($this->demand->getStatusCode(), \PDO::PARAM_INT) 110 ); 111 } 112 113 if (!empty($constraints)) { 114 $queryBuilder->where(...$constraints); 115 } 116 return $queryBuilder; 117 } 118 119 /** 120 * Used for the filtering in the backend 121 * 122 * @return array 123 */ 124 public function findHostsOfRedirects(): array 125 { 126 return $this->getQueryBuilder() 127 ->select('source_host as name') 128 ->from('sys_redirect') 129 ->orderBy('source_host') 130 ->groupBy('source_host') 131 ->execute() 132 ->fetchAll(); 133 } 134 135 /** 136 * Used for the filtering in the backend 137 * 138 * @return array 139 */ 140 public function findStatusCodesOfRedirects(): array 141 { 142 return $this->getQueryBuilder() 143 ->select('target_statuscode as code') 144 ->from('sys_redirect') 145 ->orderBy('target_statuscode') 146 ->groupBy('target_statuscode') 147 ->execute() 148 ->fetchAll(); 149 } 150 151 /** 152 * @return QueryBuilder 153 */ 154 protected function getQueryBuilder(): QueryBuilder 155 { 156 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_redirect'); 157 $queryBuilder->getRestrictions() 158 ->removeAll() 159 ->add(GeneralUtility::makeInstance(DeletedRestriction::class)); 160 return $queryBuilder; 161 } 162} 163