b82054153b38250b6602f2565330619534b912a4
[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 } else {
164 $data = array_intersect_key($file->getProperties(), array_flip($this->fields));
165 $this->getDatabase()->exec_INSERTquery($this->table, $data);
166 $file->updateProperties(array('uid' => $this->getDatabase()->sql_insert_id()));
167 }
168 }
169
170 /**
171 * Checks if a file is indexed
172 *
173 * @param File $file
174 * @return bool
175 */
176 public function hasIndexRecord(File $file) {
177 if (intval($file->getUid()) > 0) {
178 $where = 'uid=' . intval($file->getUid());
179
180 } else {
181 $where = sprintf(
182 'storage=%u AND identifier=%s',
183 intval($file->getStorage()->getUid()),
184 $this->getDatabase()->fullQuoteStr($file->getIdentifier(), $this->table)
185 );
186 }
187 return $this->getDatabase()->exec_SELECTcountRows('uid', $this->table, $where) === 1;
188 }
189
190 /**
191 * Updates the index record in the database
192 *
193 * @param File $file
194 */
195 public function update(File $file) {
196 $updatedProperties = array_intersect($this->fields, $file->getUpdatedProperties());
197 $updateRow = array();
198 foreach ($updatedProperties as $key) {
199 $updateRow[$key] = $file->getProperty($key);
200 }
201 if (count($updateRow) > 0) {
202 $updateRow['tstamp'] = time();
203 $this->getDatabase()->exec_UPDATEquery($this->table, 'uid=' . intval($file->getUid()), $updateRow);
204 }
205 }
206 }