[BUGFIX] EXT:documentation should accept other index file names
[Packages/TYPO3.CMS.git] / typo3 / sysext / documentation / Classes / Domain / Repository / DocumentRepository.php
1 <?php
2 namespace TYPO3\CMS\Documentation\Domain\Repository;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2013 Xavier Perseguers <xavier@typo3.org>
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 3 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 /**
28 * An extension helper repository to be used in ext:documentation context
29 *
30 * @author Xavier Perseguers <xavier@typo3.org>
31 */
32 class DocumentRepository {
33
34 /**
35 * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
36 * @inject
37 */
38 protected $objectManager;
39
40 /**
41 * Finds all documents.
42 *
43 * @return \TYPO3\CMS\Documentation\Domain\Model\Document[]
44 */
45 public function findAll() {
46 $documents = $this->findSphinxDocuments();
47 $openOfficeDocuments = $this->findOpenOfficeDocuments();
48
49 // Add OpenOffice documents if there is not already an existing, non OpenOffice version
50 foreach ($openOfficeDocuments as $documentKey => $document) {
51 if (!isset($documents[$documentKey])) {
52 $documents[$documentKey] = $document;
53 }
54 }
55
56 return $documents;
57 }
58
59 /**
60 * Finds documents by language, always falls back to 'default' (English).
61 *
62 * @param string $language
63 * @return \TYPO3\CMS\Documentation\Domain\Model\Document[]
64 */
65 public function findByLanguage($language) {
66 $allDocuments = $this->findAll();
67
68 // Initialize the dependency of languages
69 $languageDependencies = array();
70 /** @var $locales \TYPO3\CMS\Core\Localization\Locales */
71 $locales = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Localization\\Locales');
72 // Language is found. Configure it:
73 $shortLanguage = $language;
74 if (!in_array($shortLanguage, $locales->getLocales()) && strpos($shortLanguage, '_') !== FALSE) {
75 list($shortLanguage, $_) = explode('_', $shortLanguage);
76 }
77 if (in_array($shortLanguage, $locales->getLocales())) {
78 $languageDependencies[] = $language;
79 if ($language !== $shortLanguage) {
80 $languageDependencies[] = $shortLanguage;
81 }
82 foreach ($locales->getLocaleDependencies($shortLanguage) as $languageDependency) {
83 $languageDependencies[] = $languageDependency;
84 }
85 }
86 if ($language !== 'default') {
87 $languageDependencies[] = 'default';
88 }
89
90 foreach ($allDocuments as $document) {
91 // Remove every unwanted translation
92 $selectedTranslation = NULL;
93 $highestPriorityLanguageIndex = count($languageDependencies);
94
95 $translations = $document->getTranslations();
96 foreach ($translations as $translation) {
97 $languageIndex = array_search($translation->getLanguage(), $languageDependencies);
98 if ($languageIndex !== FALSE) {
99 if ($languageIndex < $highestPriorityLanguageIndex) {
100 $selectedTranslation = $translation;
101 $highestPriorityLanguageIndex = $languageIndex;
102 }
103 } else {
104 // No exact translation found, perhaps another locale would fit as well. E.g., when requesting
105 // a documentation as fr_CA but only fr_FR exists
106 if (strpos($translation->getLanguage(), '_') !== FALSE) {
107 list($translationLanguage, $_) = explode('_', $translation->getLanguage());
108 $languageIndex = array_search($translationLanguage, $languageDependencies);
109 if ($languageIndex !== FALSE && $languageIndex < $highestPriorityLanguageIndex) {
110 $selectedTranslation = $translation;
111 $highestPriorityLanguageIndex = $languageIndex;
112 }
113 }
114 }
115 }
116
117 $newTranslations = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
118 $document->setTranslations($newTranslations);
119 if ($selectedTranslation !== NULL) {
120 $document->addTranslation($selectedTranslation);
121 }
122
123 }
124
125 return $allDocuments;
126 }
127
128 /**
129 * Retrieves Sphinx documents.
130 *
131 * @return array
132 */
133 protected function findSphinxDocuments() {
134 $basePath = 'typo3conf/Documentation/';
135
136 $documents = array();
137 $documentKeys = \TYPO3\CMS\Core\Utility\GeneralUtility::get_dirs(PATH_site . $basePath);
138 // Early return in case no document keys were found
139 if (!is_array($documentKeys)) {
140 return $documents;
141 }
142
143 foreach ($documentKeys as $documentKey) {
144 $icon = \TYPO3\CMS\Documentation\Utility\GeneralUtility::getIcon($documentKey);
145
146 /** @var \TYPO3\CMS\Documentation\Domain\Model\Document $document */
147 $document = $this->objectManager->get('TYPO3\\CMS\\Documentation\\Domain\\Model\\Document')
148 ->setPackageKey($documentKey)
149 ->setIcon($icon);
150
151 $languagePath = $basePath . $documentKey . '/';
152 $languages = \TYPO3\CMS\Core\Utility\GeneralUtility::get_dirs(PATH_site . $languagePath);
153 foreach ($languages as $language) {
154 $metadata = $this->getMetadata($documentKey, $language);
155
156 /** @var \TYPO3\CMS\Documentation\Domain\Model\DocumentTranslation $documentTranslation */
157 $documentTranslation = $this->objectManager->get('TYPO3\\CMS\\Documentation\\Domain\\Model\\DocumentTranslation')
158 ->setLanguage($language)
159 ->setTitle($metadata['title'])
160 ->setDescription($metadata['description']);
161
162 $formatPath = $languagePath . $language . '/';
163 $formats = \TYPO3\CMS\Core\Utility\GeneralUtility::get_dirs(PATH_site . $formatPath);
164 foreach ($formats as $format) {
165 $documentFile = '';
166 switch ($format) {
167 case 'html':
168 // Try to find a valid index file
169 $indexFiles = array('Index.html', 'index.html', 'index.htm');
170 foreach ($indexFiles as $indexFile) {
171 if (file_exists(PATH_site . $formatPath . $format . '/' . $indexFile)) {
172 $documentFile = $indexFile;
173 break;
174 }
175 }
176 break;
177 case 'pdf':
178 // Retrieve first PDF
179 $files = \TYPO3\CMS\Core\Utility\GeneralUtility::getFilesInDir(PATH_site . $formatPath . $format, 'pdf');
180 if (count($files) > 0) {
181 $documentFile = current($files);
182 }
183 break;
184 }
185 if (!empty($documentFile)) {
186 /** @var \TYPO3\CMS\Documentation\Domain\Model\DocumentFormat $documentFormat */
187 $documentFormat = $this->objectManager->get('TYPO3\\CMS\\Documentation\\Domain\\Model\\DocumentFormat')
188 ->setFormat($format)
189 ->setPath($formatPath . $format . '/' . $documentFile);
190
191 $documentTranslation->addFormat($documentFormat);
192 }
193 }
194
195 if (count($documentTranslation->getFormats()) > 0) {
196 $document->addTranslation($documentTranslation);
197 $documents[$documentKey] = $document;
198 }
199 }
200 }
201
202 return $documents;
203 }
204
205 /**
206 * Retrieves OpenOffice documents (manual.sxw).
207 *
208 * @return array
209 */
210 protected function findOpenOfficeDocuments() {
211 $documents = array();
212 $language = 'default';
213
214 foreach ($GLOBALS['TYPO3_LOADED_EXT'] as $extensionKey => $extensionData) {
215 $path = $extensionData['siteRelPath'] . 'doc/';
216 if (is_file(PATH_site . $path . 'manual.sxw')) {
217 $documentKey = 'typo3cms.extensions.' . $extensionKey;
218 $icon = \TYPO3\CMS\Documentation\Utility\GeneralUtility::getIcon($documentKey);
219
220 /** @var \TYPO3\CMS\Documentation\Domain\Model\Document $document */
221 $document = $this->objectManager->get('TYPO3\\CMS\\Documentation\\Domain\\Model\\Document')
222 ->setPackageKey($documentKey)
223 ->setIcon($icon);
224
225 $metadata = $this->getMetadata($documentKey, $language);
226 /** @var \TYPO3\CMS\Documentation\Domain\Model\DocumentTranslation $documentTranslation */
227 $documentTranslation = $this->objectManager->get('TYPO3\\CMS\\Documentation\\Domain\\Model\\DocumentTranslation')
228 ->setLanguage($language)
229 ->setTitle($metadata['title'])
230 ->setDescription($metadata['description']);
231
232 /** @var \TYPO3\CMS\Documentation\Domain\Model\DocumentFormat $documentFormat */
233 $documentFormat = $this->objectManager->get('TYPO3\\CMS\\Documentation\\Domain\\Model\\DocumentFormat')
234 ->setFormat('sxw')
235 ->setPath($path . 'manual.sxw');
236
237 $documentTranslation->addFormat($documentFormat);
238 $document->addTranslation($documentTranslation);
239 $documents[$documentKey] = $document;
240 }
241 }
242
243 return $documents;
244 }
245
246 /**
247 * Returns metadata associated to a given document key.
248 *
249 * @param string $documentKey
250 * @param string $language
251 * @return array
252 */
253 protected function getMetadata($documentKey, $language) {
254 $documentPath = PATH_site . 'typo3conf/Documentation/' . $documentKey . '/' . $language . '/';
255 $metadata = array(
256 'title' => $documentKey,
257 'description' => '',
258 );
259 if (\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($documentKey, 'typo3cms.extensions.')) {
260 $extensionKey = substr($documentKey, 20);
261 if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extensionKey)) {
262 $metadata = \TYPO3\CMS\Documentation\Utility\GeneralUtility::getExtensionMetaData($extensionKey);
263 }
264 } elseif (is_file($documentPath . 'composer.json')) {
265 $info = json_decode(file_get_contents($documentPath . 'composer.json'), TRUE);
266 if (is_array($info)) {
267 $metadata['title'] = $info['name'];
268 $metadata['description'] = $info['description'];
269 }
270 }
271 return $metadata;
272 }
273
274 }