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