[TASK] Turn todos into @todo to find them easier
[Packages/TYPO3.CMS.git] / typo3 / sysext / extensionmanager / Classes / Utility / Importer / ExtensionListUtility.php
1 <?php
2 namespace TYPO3\CMS\Extensionmanager\Utility\Importer;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16 /**
17 * Module: Extension manager - Extension list importer
18 *
19 * @author Marcus Krause <marcus#exp2010@t3sec.info>
20 * @author Steffen Kamper <info@sk-typo3.de>
21 */
22 /**
23 * Importer object for extension list
24 *
25 * @author Marcus Krause <marcus#exp2010@t3sec.info>
26 * @author Steffen Kamper <info@sk-typo3.de>
27 * @since 2010-02-10
28 */
29 class ExtensionListUtility implements \SplObserver {
30
31 /**
32 * Keeps instance of a XML parser.
33 *
34 * @var \TYPO3\CMS\Extensionmanager\Utility\Parser\AbstractExtensionXmlParser
35 */
36 protected $parser;
37
38 /**
39 * Keeps number of processed version records.
40 *
41 * @var int
42 */
43 protected $sumRecords = 0;
44
45 /**
46 * Keeps record values to be inserted into database.
47 *
48 * @var array
49 */
50 protected $arrRows = array();
51
52 /**
53 * Keeps fieldnames of tx_extensionmanager_domain_model_extension table.
54 *
55 * @var array
56 */
57 static protected $fieldNames = array(
58 'extension_key',
59 'version',
60 'integer_version',
61 'current_version',
62 'alldownloadcounter',
63 'downloadcounter',
64 'title',
65 'ownerusername',
66 'author_name',
67 'author_email',
68 'authorcompany',
69 'last_updated',
70 'md5hash',
71 'repository',
72 'state',
73 'review_state',
74 'category',
75 'description',
76 'serialized_dependencies',
77 'update_comment'
78 );
79
80 /**
81 * Keeps indexes of fields that should not be quoted.
82 *
83 * @var array
84 */
85 static protected $fieldIndicesNoQuote = array(2, 3, 5, 11, 13, 14, 15, 16);
86
87 /**
88 * Keeps repository UID.
89 *
90 * The UID is necessary for inserting records.
91 *
92 * @var int
93 */
94 protected $repositoryUid = 1;
95
96 /**
97 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository
98 */
99 protected $repositoryRepository;
100
101 /**
102 * @var \TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository
103 */
104 protected $extensionRepository;
105
106 /**
107 * @var \TYPO3\CMS\Extensionmanager\Domain\Model\Extension
108 */
109 protected $extensionModel;
110
111 /**
112 * Class constructor.
113 *
114 * Method retrieves and initializes extension XML parser instance.
115 *
116 * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
117 */
118 public function __construct() {
119 /** @var $objectManager \TYPO3\CMS\Extbase\Object\ObjectManager */
120 $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
121 $this->repositoryRepository = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Repository\RepositoryRepository::class);
122 $this->extensionRepository = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository::class);
123 $this->extensionModel = $this->objectManager->get(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension::class);
124 // @todo catch parser exception
125 $this->parser = \TYPO3\CMS\Extensionmanager\Utility\Parser\XmlParserFactory::getParserInstance('extension');
126 if (is_object($this->parser)) {
127 $this->parser->attach($this);
128 } else {
129 throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(get_class($this) . ': No XML parser available.');
130 }
131 }
132
133 /**
134 * Method initializes parsing of extension.xml.gz file.
135 *
136 * @param string $localExtensionListFile absolute path to extension list xml.gz
137 * @param int $repositoryUid UID of repository when inserting records into DB
138 * @return int total number of imported extension versions
139 */
140 public function import($localExtensionListFile, $repositoryUid = NULL) {
141 if (!is_null($repositoryUid) && is_int($repositoryUid)) {
142 $this->repositoryUid = $repositoryUid;
143 }
144 $zlibStream = 'compress.zlib://';
145 $this->sumRecords = 0;
146 $this->parser->parseXML($zlibStream . $localExtensionListFile);
147 // flush last rows to database if existing
148 if (count($this->arrRows)) {
149 $GLOBALS['TYPO3_DB']->exec_INSERTmultipleRows('tx_extensionmanager_domain_model_extension', self::$fieldNames, $this->arrRows, self::$fieldIndicesNoQuote);
150 }
151 $extensions = $this->extensionRepository->insertLastVersion($this->repositoryUid);
152 $this->repositoryRepository->updateRepositoryCount($extensions, $this->repositoryUid);
153 return $this->sumRecords;
154 }
155
156 /**
157 * Method collects and stores extension version details into the database.
158 *
159 * @param \SplSubject|\TYPO3\CMS\Extensionmanager\Utility\Parser\AbstractExtensionXmlParser &$subject a subject notifying this observer
160 * @return void
161 */
162 protected function loadIntoDatabase(\SplSubject &$subject) {
163 // flush every 50 rows to database
164 if ($this->sumRecords !== 0 && $this->sumRecords % 50 === 0) {
165 $GLOBALS['TYPO3_DB']->exec_INSERTmultipleRows('tx_extensionmanager_domain_model_extension', self::$fieldNames, $this->arrRows, self::$fieldIndicesNoQuote);
166 $this->arrRows = array();
167 }
168 $versionRepresentations = \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionStringToArray($subject->getVersion());
169 // order must match that of self::$fieldNames!
170 $this->arrRows[] = array(
171 $subject->getExtkey(),
172 $subject->getVersion(),
173 $versionRepresentations['version_int'],
174 // initialize current_version, correct value computed later:
175 0,
176 (int)$subject->getAlldownloadcounter(),
177 (int)$subject->getDownloadcounter(),
178 !is_null($subject->getTitle()) ? $subject->getTitle() : '',
179 $subject->getOwnerusername(),
180 !is_null($subject->getAuthorname()) ? $subject->getAuthorname() : '',
181 !is_null($subject->getAuthoremail()) ? $subject->getAuthoremail() : '',
182 !is_null($subject->getAuthorcompany()) ? $subject->getAuthorcompany() : '',
183 (int)$subject->getLastuploaddate(),
184 $subject->getT3xfilemd5(),
185 $this->repositoryUid,
186 $this->extensionModel->getDefaultState($subject->getState() ?: ''),
187 (int)$subject->getReviewstate(),
188 $this->extensionModel->getCategoryIndexFromStringOrNumber($subject->getCategory() ?: ''),
189 $subject->getDescription() ?: '',
190 $subject->getDependencies() ?: '',
191 $subject->getUploadcomment() ?: ''
192 );
193 ++$this->sumRecords;
194 }
195
196 /**
197 * Method receives an update from a subject.
198 *
199 * @param \SplSubject $subject a subject notifying this observer
200 * @return void
201 */
202 public function update(\SplSubject $subject) {
203 if (is_subclass_of($subject, \TYPO3\CMS\Extensionmanager\Utility\Parser\AbstractExtensionXmlParser::class)) {
204 $this->loadIntoDatabase($subject);
205 }
206 }
207
208 }