[FEATURE] Add distribution management to extension manager
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Domain / Repository / ExtensionRepository.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Domain\Repository;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2012-2013 Susanne Moog, <typo3@susannemoog.de>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 /**
27 * A repository for extensions
28 *
29 * @author Susanne Moog <typo3@susannemoog.de>
30 */
31 class ExtensionRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
32
33 /**
34 * @var \TYPO3\CMS\Core\Database\DatabaseConnection
35 */
36 protected $databaseConnection;
37
38 /**
39 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
40 * @inject
41 */
42 protected $dataMapper;
43
44 /**
45 * Do not include pid in queries
46 *
47 * @return void
48 */
49 public function initializeObject() {
50 /** @var $defaultQuerySettings \TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface */
51 $defaultQuerySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\QuerySettingsInterface');
52 $defaultQuerySettings->setRespectStoragePage(FALSE);
53 $this->setDefaultQuerySettings($defaultQuerySettings);
54 $this->databaseConnection = $GLOBALS['TYPO3_DB'];
55 }
56
57 /**
58 * Count all extensions
59 *
60 * @return integer
61 */
62 public function countAll() {
63 $query = $this->createQuery();
64 $query = $this->addDefaultConstraints($query);
65 return $query->execute()->count();
66 }
67
68 /**
69 * Finds all extensions
70 *
71 * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
72 */
73 public function findAll() {
74 $query = $this->createQuery();
75 $query = $this->addDefaultConstraints($query);
76 return $query->execute();
77 }
78
79 /**
80 * Find an extension by extension key ordered by version
81 *
82 * @param string $extensionKey
83 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
84 */
85 public function findByExtensionKeyOrderedByVersion($extensionKey) {
86 $query = $this->createQuery();
87 $query->matching($query->logicalAnd($query->equals('extensionKey', $extensionKey), $query->greaterThanOrEqual('reviewState', 0)));
88 $query->setOrderings(array('version' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING));
89 return $query->execute();
90 }
91
92 /**
93 * Find the current version by extension key
94 *
95 * @param string $extensionKey
96 * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
97 */
98 public function findOneByCurrentVersionByExtensionKey($extensionKey) {
99 $query = $this->createQuery();
100 $query->matching(
101 $query->logicalAnd(
102 $query->equals('extensionKey', $extensionKey),
103 $query->greaterThanOrEqual('reviewState', 0),
104 $query->equals('currentVersion', 1)
105 )
106 );
107 $query->setLimit(1);
108 return $query->execute()->getFirst();
109 }
110
111 /**
112 * Find one extension by extension key and version
113 *
114 * @param string $extensionKey
115 * @param string $version (example: 4.3.10)
116 * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
117 */
118 public function findOneByExtensionKeyAndVersion($extensionKey, $version) {
119 $query = $this->createQuery();
120 // Hint: This method must not filter out insecure extensions, if needed,
121 // it should be done on a different level, or with a helper method.
122 $query->matching($query->logicalAnd(
123 $query->equals('extensionKey', $extensionKey),
124 $query->equals('version', $version)
125 ));
126 return $query->setLimit(1)->execute()->getFirst();
127 }
128
129 /**
130 * Find an extension by title, author name or extension key
131 * This is the function used by the TER search. It is using a
132 * scoring for the matches to sort the extension with an
133 * exact key match on top
134 *
135 * @param string $searchString The string to search for extensions
136 * @return mixed
137 */
138 public function findByTitleOrAuthorNameOrExtensionKey($searchString) {
139 $quotedSearchString = $this->databaseConnection->escapeStrForLike($this->databaseConnection->quoteStr($searchString, 'tx_extensionmanager_domain_model_extension'), 'tx_extensionmanager_domain_model_extension');
140 $quotedSearchStringForLike = '\'%' . $quotedSearchString . '%\'';
141 $quotedSearchString = '\'' . $quotedSearchString . '\'';
142 $select = 'tx_extensionmanager_domain_model_extension.*,
143 (
144 (extension_key like ' . $quotedSearchString . ') * 8 +
145 (extension_key like ' . $quotedSearchStringForLike . ') * 4 +
146 (title like ' . $quotedSearchStringForLike . ') * 2 +
147 (author_name like ' . $quotedSearchStringForLike . ')
148 ) as position';
149 $from = 'tx_extensionmanager_domain_model_extension';
150 $where = '(
151 extension_key = ' . $quotedSearchString . '
152 OR
153 extension_key LIKE ' . $quotedSearchStringForLike . '
154 OR
155 title LIKE ' . $quotedSearchStringForLike . '
156 OR
157 description LIKE ' . $quotedSearchStringForLike . '
158 OR
159 author_name LIKE ' . $quotedSearchStringForLike . '
160 )
161 AND current_version=1 AND review_state >= 0
162 HAVING position > 0';
163 $order = 'position desc';
164 $result = $this->databaseConnection->exec_SELECTgetRows($select, $from, $where, '', $order);
165 return $this->dataMapper->map('TYPO3\\CMS\\Extensionmanager\\Domain\\Model\\Extension', $result);
166 }
167
168 /**
169 * Find an extension between a certain version range ordered by version number
170 *
171 * @param string $extensionKey
172 * @param integer $lowestVersion
173 * @param integer $highestVersion
174 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
175 */
176 public function findByVersionRangeAndExtensionKeyOrderedByVersion($extensionKey, $lowestVersion = 0, $highestVersion = 0) {
177 $query = $this->createQuery();
178 $constraint = NULL;
179 if ($lowestVersion !== 0 && $highestVersion !== 0) {
180 $constraint = $query->logicalAnd($query->lessThan('integerVersion', $highestVersion), $query->greaterThan('integerVersion', $lowestVersion), $query->equals('extensionKey', $extensionKey));
181 } elseif ($lowestVersion === 0 && $highestVersion !== 0) {
182 $constraint = $query->logicalAnd($query->lessThan('integerVersion', $highestVersion), $query->equals('extensionKey', $extensionKey));
183 } elseif ($lowestVersion !== 0 && $highestVersion === 0) {
184 $constraint = $query->logicalAnd($query->greaterThan('integerVersion', $lowestVersion), $query->equals('extensionKey', $extensionKey));
185 } elseif ($lowestVersion === 0 && $highestVersion === 0) {
186 $constraint = $query->equals('extensionKey', $extensionKey);
187 }
188 if ($constraint) {
189 $query->matching($query->logicalAnd($constraint, $query->greaterThanOrEqual('reviewState', 0)));
190 }
191 $query->setOrderings(array(
192 'integerVersion' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
193 ));
194 return $query->execute();
195 }
196
197 /**
198 * Finds all extensions with category "distribution"
199 *
200 * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
201 */
202 public function findAllDistributions() {
203 $query = $this->createQuery();
204 $query->matching(
205 $query->logicalAnd(
206 $query->equals('category', \TYPO3\CMS\Extensionmanager\Domain\Model\Extension::DISTRIBUTION_CATEGORY),
207 $query->equals('currentVersion', 1)
208 )
209 );
210 return $query->execute();
211 }
212
213 /**
214 * Count extensions with a certain key between a given version range
215 *
216 * @param string $extensionKey
217 * @param integer $lowestVersion
218 * @param integer $highestVersion
219 * @return integer
220 */
221 public function countByVersionRangeAndExtensionKey($extensionKey, $lowestVersion = 0, $highestVersion = 0) {
222 return $this->findByVersionRangeAndExtensionKeyOrderedByVersion($extensionKey, $lowestVersion, $highestVersion)->count();
223 }
224
225 /**
226 * Find highest version available of an extension
227 *
228 * @param string $extensionKey
229 * @return object
230 */
231 public function findHighestAvailableVersion($extensionKey) {
232 $query = $this->createQuery();
233 $query->matching($query->logicalAnd($query->equals('extensionKey', $extensionKey), $query->greaterThanOrEqual('reviewState', 0)));
234 $query->setOrderings(array(
235 'integerVersion' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
236 ));
237 return $query->setLimit(1)->execute()->getFirst();
238 }
239
240 /**
241 * Update the current_version field after update
242 * For performance reason "native" TYPO3_DB is
243 * used here directly.
244 *
245 * @param integer $repositoryUid
246 * @return integer
247 */
248 public function insertLastVersion($repositoryUid = 1) {
249 $groupedRows = $this->databaseConnection->exec_SELECTgetRows(
250 'extension_key, max(integer_version) as maxintversion',
251 'tx_extensionmanager_domain_model_extension',
252 'repository=' . intval($repositoryUid),
253 'extension_key'
254 );
255 $extensions = count($groupedRows);
256
257 if ($extensions > 0) {
258 // set all to 0
259 $this->databaseConnection->exec_UPDATEquery(
260 'tx_extensionmanager_domain_model_extension',
261 'current_version=1 AND repository=' . intval($repositoryUid),
262 array('current_version' => 0)
263 );
264 // Find latest version of extensions and set current_version to 1 for these
265 foreach ($groupedRows as $row) {
266 $this->databaseConnection->exec_UPDATEquery(
267 'tx_extensionmanager_domain_model_extension',
268 'extension_key=' .
269 $this->databaseConnection->fullQuoteStr($row['extension_key'], 'tx_extensionmanager_domain_model_extension') .
270 ' AND integer_version=' . intval($row['maxintversion']) .
271 ' AND repository=' . intval($repositoryUid),
272 array('current_version' => 1)
273 );
274 }
275 }
276 return $extensions;
277 }
278
279 /**
280 * Adds default constraints to the query - in this case it
281 * enables us to always just search for the latest version of an extension
282 *
283 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Query $query the query to adjust
284 * @return \TYPO3\CMS\Extbase\Persistence\Generic\Query
285 */
286 protected function addDefaultConstraints(\TYPO3\CMS\Extbase\Persistence\Generic\Query $query) {
287 if ($query->getConstraint()) {
288 $query->matching($query->logicalAnd(
289 $query->getConstraint(),
290 $query->equals('current_version', TRUE),
291 $query->greaterThanOrEqual('reviewState', 0)
292 ));
293 } else {
294 $query->matching($query->logicalAnd(
295 $query->equals('current_version', TRUE),
296 $query->greaterThanOrEqual('reviewState', 0)
297 ));
298 }
299 return $query;
300 }
301
302 }
303
304
305 ?>