[BUGFIX] Adapt IndexerService to new table structures
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / Index / FileIndexRepository.php
1 <?php
2
3 namespace TYPO3\CMS\Core\Resource\Index;
4
5 /***************************************************************
6 * Copyright notice
7 *
8 * (c) 2013 Steffen Ritter <steffen.ritter@typo3.org>
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 * A copy is found in the textfile GPL.txt and important notices to the license
20 * from the author is found in LICENSE.txt distributed with these scripts.
21 *
22 *
23 * This script is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * This copyright notice MUST APPEAR in all copies of the script!
29 ***************************************************************/
30
31 use TYPO3\CMS\Core\SingletonInterface;
32 use TYPO3\CMS\Core\Utility\GeneralUtility;
33 use TYPO3\CMS\Core\Resource\File;
34
35 /**
36 * Repository Class as an abstraction layer to sys_file
37 *
38 * Every access to table sys_file_metadata which is not handled by TCEmain
39 * has to use this Repository class.
40 *
41 * This is meant for FAL internal use only!.
42 */
43 class FileIndexRepository implements SingletonInterface {
44
45 /**
46 * @var string
47 */
48 protected $table = 'sys_file';
49
50 /**
51 * A list of properties which are to be persisted
52 *
53 * @var array
54 */
55 protected $fields = array(
56 'uid', 'pid', 'missing', 'type', 'storage', 'identifier', 'extension',
57 'mime_type', 'name', 'sha1', 'size', 'creation_date', 'modification_date',
58 );
59
60 /**
61 * Gets database instance
62 *
63 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
64 */
65 protected function getDatabase() {
66 return $GLOBALS['TYPO3_DB'];
67 }
68
69 /**
70 * Returns an Instance of the Repository
71 *
72 * @return FileIndexRepository
73 */
74 public static function getInstance() {
75 return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
76 }
77
78 /**
79 * Retrieves Index record for a given $combinedIdentifier
80 *
81 * @param string $combinedIdentifier
82 * @return array|bool
83 */
84 public function findOneByCombinedIdentifier($combinedIdentifier) {
85 list($storageUid, $identifier) = GeneralUtility::trimExplode(':', $combinedIdentifier, FALSE, 2);
86 return $this->findOneByStorageUidAndIdentifier($storageUid, $identifier);
87 }
88
89 /**
90 * Retrieves Index record for a given $fileUid
91 *
92 * @param int $fileUid
93 * @return array|bool
94 */
95 public function findOneByUid($fileUid) {
96 $row = $this->getDatabase()->exec_SELECTgetSingleRow(
97 implode(',', $this->fields),
98 $this->table,
99 'uid=' . intval($fileUid)
100 );
101 return is_array($row) ? $row : FALSE;
102 }
103
104 /**
105 * Retrieves Index record for a given $storageUid and $identifier
106 *
107 * @param int $storageUid
108 * @param string $identifier
109 * @return array|bool
110 *
111 * @internal only for use from FileRepository
112 */
113 public function findOneByStorageUidAndIdentifier($storageUid, $identifier) {
114 $row = $this->getDatabase()->exec_SELECTgetSingleRow(
115 implode(',', $this->fields),
116 $this->table,
117 sprintf('storage=%u AND identifier=%s', intval($storageUid), $this->getDatabase()->fullQuoteStr($identifier, $this->table))
118 );
119 return is_array($row) ? $row : FALSE;
120 }
121
122 /**
123 * Retrieves Index record for a given $fileObject
124 *
125 * @param \TYPO3\CMS\Core\Resource\FileInterface $fileObject
126 * @return array|bool
127 *
128 * @internal only for use from FileRepository
129 */
130 public function findOneByFileObject(\TYPO3\CMS\Core\Resource\FileInterface $fileObject) {
131 $storageUid = $fileObject->getStorage()->getUid();
132 $identifier = $fileObject->getIdentifier();
133 return $this->findOneByStorageUidAndIdentifier($storageUid, $identifier);
134 }
135
136 /**
137 * Returns all indexed files which match the content hash
138 * Used by the indexer to detect already present files
139 *
140 * @param string $hash
141 * @return mixed
142 */
143 public function findByContentHash($hash) {
144 if (!preg_match('/^[0-9a-f]{40}$/i', $hash)) {
145 return array();
146 }
147 $resultRows = $this->getDatabase()->exec_SELECTgetRows(
148 implode(',', $this->fields),
149 $this->table,
150 'sha1=' . $this->getDatabase()->fullQuoteStr($hash, $this->table)
151 );
152 return $resultRows;
153 }
154
155 /**
156 * Adds a file to the index
157 *
158 * @param File $file
159 */
160 public function add(File $file) {
161 if ($this->hasIndexRecord($file)) {
162 $this->update($file);
163 if ($file->_getPropertyRaw('uid') === NULL) {
164 $file->updateProperties($this->findOneByFileObject($file));
165 }
166 } else {
167 $data = array_intersect_key($file->getProperties(), array_flip($this->fields));
168 $this->getDatabase()->exec_INSERTquery($this->table, $data);
169 $file->updateProperties(array('uid' => $this->getDatabase()->sql_insert_id()));
170 }
171 }
172
173 /**
174 * Checks if a file is indexed
175 *
176 * @param File $file
177 * @return bool
178 */
179 public function hasIndexRecord(File $file) {
180 return $this->getDatabase()->exec_SELECTcountRows('uid', $this->table, $this->getWhereClauseForFile($file)) === 1;
181 }
182
183 /**
184 * Updates the index record in the database
185 *
186 * @param File $file
187 */
188 public function update(File $file) {
189 $updatedProperties = array_intersect($this->fields, $file->getUpdatedProperties());
190 $updateRow = array();
191 foreach ($updatedProperties as $key) {
192 $updateRow[$key] = $file->getProperty($key);
193 }
194 if (count($updateRow) > 0) {
195 $updateRow['tstamp'] = time();
196 $this->getDatabase()->exec_UPDATEquery($this->table, $this->getWhereClauseForFile($file), $updateRow);
197 }
198 }
199
200 /**
201 * Returns a where clause to find a file in database
202 *
203 * @param File $file
204 *
205 * @return string
206 */
207 protected function getWhereClauseForFile(File $file) {
208 if (intval($file->_getPropertyRaw('uid')) > 0) {
209 $where = 'uid=' . intval($file->getUid());
210 } else {
211 $where = sprintf(
212 'storage=%u AND identifier=%s',
213 intval($file->getStorage()->getUid()),
214 $this->getDatabase()->fullQuoteStr($file->_getPropertyRaw('identifier'), $this->table)
215 );
216 }
217 return $where;
218 }
219 }