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