|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /* ************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com) 00006 * (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org> 00007 * All rights reserved 00008 * 00009 * This script is part of the TYPO3 project. The TYPO3 project is 00010 * free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * The GNU General Public License can be found at 00016 * http://www.gnu.org/copyleft/gpl.html. 00017 * A copy is found in the textfile GPL.txt and important notices to the license 00018 * from the author is found in LICENSE.txt distributed with these scripts. 00019 * 00020 * 00021 * This script is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * This copyright notice MUST APPEAR in all copies of the script! 00027 ***************************************************************/ 00028 00029 00030 /** 00031 * TER2 connection handling class for the TYPO3 Extension Manager. 00032 * 00033 * It contains methods for downloading and uploading extensions and related code 00034 * 00035 * @author Karsten Dambekalns <karsten@typo3.org> 00036 * @author Kasper Skårhøj <kasperYYYY@typo3.com> 00037 * @package TYPO3 00038 * @subpackage EM 00039 */ 00040 class tx_em_Connection_Ter { 00041 var $wsdlURL; 00042 00043 /** 00044 * Extension manager module 00045 * 00046 * @var SC_mod_tools_em_index 00047 */ 00048 var $emObj; 00049 00050 public function __construct($emObj) { 00051 $this->emObj = $emObj; 00052 } 00053 00054 /** 00055 * Fetches an extension from the given mirror 00056 * 00057 * @param string $extKey Extension Key 00058 * @param string $version Version to install 00059 * @param string $expectedMD5 Expected MD5 hash of extension file 00060 * @param string $mirrorURL URL of mirror to use 00061 * @return mixed T3X data (array) or error message (string) 00062 */ 00063 function fetchExtension($extKey, $version, $expectedMD5, $mirrorURL) { 00064 $extPath = t3lib_div::strtolower($extKey); 00065 $mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '_' . $version . '.t3x'; 00066 $t3x = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent)); 00067 $MD5 = md5($t3x); 00068 00069 if ($t3x === FALSE) { 00070 return 'The T3X file could not be fetched. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.'; 00071 } 00072 00073 if ($MD5 == $expectedMD5) { 00074 // Fetch and return: 00075 return $this->decodeExchangeData($t3x); 00076 } else { 00077 return 'Error: MD5 hash of downloaded file not as expected:<br />' . $MD5 . ' != ' . $expectedMD5; 00078 } 00079 } 00080 00081 /** 00082 * Fetches an extensions l10n file from the given mirror 00083 * 00084 * @param string $extKey Extension Key 00085 * @param string $lang The language code of the translation to fetch 00086 * @param string $mirrorURL URL of mirror to use 00087 * @return mixed Array containing l10n data or error message (string) 00088 */ 00089 function fetchTranslation($extKey, $lang, $mirrorURL) { 00090 $extPath = t3lib_div::strtolower($extKey); 00091 $mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '-l10n/' . $extPath . '-l10n-' . $lang . '.zip'; 00092 $l10n = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent)); 00093 00094 if ($l10n !== false) { 00095 return array($l10n); 00096 } else { 00097 return 'Error: Translation could not be fetched.'; 00098 } 00099 } 00100 00101 /** 00102 * Install translations for all selected languages for an extension 00103 * 00104 * @param string $extKey The extension key to install the translations for 00105 * @param string $lang Language code of translation to fetch 00106 * @param string $mirrorURL Mirror URL to fetch data from 00107 * @return mixed true on success, error string on fauilure 00108 */ 00109 function updateTranslation($extKey, $lang, $mirrorURL) { 00110 $l10n = $this->fetchTranslation($extKey, $lang, $mirrorURL); 00111 if (is_array($l10n)) { 00112 $file = PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip'; 00113 $path = 'l10n/' . $lang . '/'; 00114 if (!is_dir(PATH_typo3conf . $path)) { 00115 t3lib_div::mkdir_deep(PATH_typo3conf, $path); 00116 } 00117 t3lib_div::writeFile($file, $l10n[0]); 00118 if (tx_em_Tools::unzip($file, PATH_typo3conf . $path)) { 00119 return TRUE; 00120 } 00121 } 00122 return FALSE; 00123 } 00124 00125 /** 00126 * Fetches extension l10n status from the given mirror 00127 * 00128 * @param string $extKey Extension Key 00129 * @param string $mirrorURL URL of mirror to use 00130 * @return mixed Array containing l10n status data or FALSE if no status could be fetched 00131 */ 00132 function fetchTranslationStatus($extKey, $mirrorURL) { 00133 $extPath = t3lib_div::strtolower($extKey); 00134 $mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '-l10n/' . $extPath . '-l10n.xml'; 00135 $remote = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent)); 00136 00137 if ($remote !== false) { 00138 $parsed = $this->emObj->xmlHandler->parseL10nXML($remote); 00139 return $parsed['languagePackIndex']; 00140 } 00141 00142 return FALSE; 00143 } 00144 00145 /** 00146 * Decode server data 00147 * This is information like the extension list, extension information etc., return data after uploads (new em_conf) 00148 * 00149 * @param string Data stream from remove server 00150 * @return mixed On success, returns an array with data array and stats array as key 0 and 1. Otherwise returns error string 00151 * @see fetchServerData(), processRepositoryReturnData() 00152 */ 00153 function decodeServerData($externalData) { 00154 $parts = explode(':', $externalData, 4); 00155 $dat = base64_decode($parts[2]); 00156 // compare hashes ignoring any leading whitespace. See bug #0000365. 00157 if (ltrim($parts[0]) == md5($dat)) { 00158 if ($parts[1] == 'gzcompress') { 00159 if (function_exists('gzuncompress')) { 00160 $dat = gzuncompress($dat); 00161 } else { 00162 return 'Decoding Error: No decompressor available for compressed content. gzuncompress() function is not available!'; 00163 } 00164 } 00165 $listArr = unserialize($dat); 00166 00167 if (is_array($listArr)) { 00168 return $listArr; 00169 } else { 00170 return 'Error: Unserialized information was not an array - strange!'; 00171 } 00172 } else { 00173 return 'Error: MD5 hashes in T3X data did not match!'; 00174 } 00175 } 00176 00177 /** 00178 * Decodes extension upload array. 00179 * This kind of data is when an extension is uploaded to TER 00180 * 00181 * @param string Data stream 00182 * @return mixed Array with result on success, otherwise an error string. 00183 */ 00184 function decodeExchangeData($str) { 00185 $parts = explode(':', $str, 3); 00186 if ($parts[1] == 'gzcompress') { 00187 if (function_exists('gzuncompress')) { 00188 $parts[2] = gzuncompress($parts[2]); 00189 } else { 00190 return 'Decoding Error: No decompressor available for compressed content. gzcompress()/gzuncompress() functions are not available!'; 00191 } 00192 } 00193 if (md5($parts[2]) == $parts[0]) { 00194 $output = unserialize($parts[2]); 00195 if (is_array($output)) { 00196 return array($output, ''); 00197 } else { 00198 return 'Error: Content could not be unserialized to an array. Strange (since MD5 hashes match!)'; 00199 } 00200 } else { 00201 return 'Error: MD5 mismatch. Maybe the extension file was downloaded and saved as a text file by the browser and thereby corrupted!? (Always select "All" filetype when saving extensions)'; 00202 } 00203 } 00204 00205 00206 /** 00207 * Encodes extension upload array 00208 * 00209 * @param array Array containing extension 00210 * @return string Content stream 00211 */ 00212 function makeUploadDataFromarray($uploadArray) { 00213 $content = ''; 00214 if (is_array($uploadArray)) { 00215 $serialized = serialize($uploadArray); 00216 $md5 = md5($serialized); 00217 00218 $content = $md5 . ':'; 00219 $content .= 'gzcompress:'; 00220 $content .= gzcompress($serialized); 00221 } 00222 return $content; 00223 } 00224 00225 /** 00226 * Upload extension to ter 00227 * @param $em 00228 * @return 00229 */ 00230 function uploadToTER($em) { 00231 $uArr = $this->emObj->extensionDetails->makeUploadarray($em['extKey'], $em['extInfo']); 00232 if (!is_array($uArr)) { 00233 return $uArr; 00234 } 00235 00236 // Render new version number: 00237 $newVersionBase = $em['extInfo']['EM_CONF']['version']; 00238 switch ((string) $em['upload']['mode']) { 00239 case 'new_dev': 00240 $cmd = 'dev'; 00241 break; 00242 case 'new_sub': 00243 $cmd = 'sub'; 00244 break; 00245 case 'new_main': 00246 $cmd = 'main'; 00247 break; 00248 case 'custom': 00249 $newVersionBase = $em['upload']['version']; 00250 case 'latest': 00251 default: 00252 $cmd = ''; 00253 break; 00254 } 00255 $versionArr = tx_em_Tools::renderVersion($newVersionBase, $cmd); 00256 $em['version'] = $versionArr['version']; 00257 00258 // Create dependency / conflict information: 00259 $dependenciesArr = array(); 00260 $extKeysArr = $uArr['EM_CONF']['constraints']['depends']; 00261 00262 if (is_array($extKeysArr)) { 00263 foreach ($extKeysArr as $extKey => $version) { 00264 if (strlen($extKey)) { 00265 $dependenciesArr[] = array( 00266 'kind' => 'depends', 00267 'extensionKey' => utf8_encode($extKey), 00268 'versionRange' => utf8_encode($version), 00269 ); 00270 } 00271 } 00272 } 00273 00274 $extKeysArr = $uArr['EM_CONF']['constraints']['conflicts']; 00275 if (is_array($extKeysArr)) { 00276 foreach ($extKeysArr as $extKey => $version) { 00277 if (strlen($extKey)) { 00278 $dependenciesArr[] = array( 00279 'kind' => 'conflicts', 00280 'extensionKey' => utf8_encode($extKey), 00281 'versionRange' => utf8_encode($version), 00282 ); 00283 } 00284 } 00285 } 00286 // FIXME: This part must be removed, when the problem is solved on the TER-Server #5919 00287 if (count($dependenciesArr) == 1) { 00288 $dependenciesArr[] = array( 00289 'kind' => 'depends', 00290 'extensionKey' => '', 00291 'versionRange' => '', 00292 ); 00293 } 00294 // END for Bug #5919 00295 00296 // Compile data for SOAP call: 00297 $accountData = array( 00298 'username' => $em['user']['fe_u'], 00299 'password' => $em['user']['fe_p'] 00300 ); 00301 $extensionData = array( 00302 'extensionKey' => utf8_encode($em['extKey']), 00303 'version' => utf8_encode($em['version']), 00304 'metaData' => array( 00305 'title' => utf8_encode($uArr['EM_CONF']['title']), 00306 'description' => utf8_encode($uArr['EM_CONF']['description']), 00307 'category' => utf8_encode($uArr['EM_CONF']['category']), 00308 'state' => utf8_encode($uArr['EM_CONF']['state']), 00309 'authorName' => utf8_encode($uArr['EM_CONF']['author']), 00310 'authorEmail' => utf8_encode($uArr['EM_CONF']['author_email']), 00311 'authorCompany' => utf8_encode($uArr['EM_CONF']['author_company']), 00312 ), 00313 'technicalData' => array( 00314 'dependencies' => $dependenciesArr, 00315 'loadOrder' => utf8_encode($uArr['EM_CONF']['loadOrder']), 00316 'uploadFolder' => (boolean) intval($uArr['EM_CONF']['uploadfolder']), 00317 'createDirs' => utf8_encode($uArr['EM_CONF']['createDirs']), 00318 'shy' => (boolean) intval($uArr['EM_CONF']['shy']), 00319 'modules' => utf8_encode($uArr['EM_CONF']['module']), 00320 'modifyTables' => utf8_encode($uArr['EM_CONF']['modify_tables']), 00321 'priority' => utf8_encode($uArr['EM_CONF']['priority']), 00322 'clearCacheOnLoad' => (boolean) intval($uArr['EM_CONF']['clearCacheOnLoad']), 00323 'lockType' => utf8_encode($uArr['EM_CONF']['lockType']), 00324 'doNotLoadInFEe' => utf8_encode($uArr['EM_CONF']['doNotLoadInFE']), 00325 'docPath' => utf8_encode($uArr['EM_CONF']['docPath']), 00326 ), 00327 'infoData' => array( 00328 'codeLines' => intval($uArr['misc']['codelines']), 00329 'codeBytes' => intval($uArr['misc']['codebytes']), 00330 'codingGuidelinesCompliance' => utf8_encode($uArr['EM_CONF']['CGLcompliance']), 00331 'codingGuidelinesComplianceNotes' => utf8_encode($uArr['EM_CONF']['CGLcompliance_note']), 00332 'uploadComment' => utf8_encode($em['upload']['comment']), 00333 'techInfo' => $uArr['techInfo'], 00334 ), 00335 ); 00336 00337 $filesData = array(); 00338 foreach ($uArr['FILES'] as $filename => $infoArr) { 00339 $filesData[] = array( 00340 'name' => utf8_encode($infoArr['name']), 00341 'size' => intval($infoArr['size']), 00342 'modificationTime' => intval($infoArr['mtime']), 00343 'isExecutable' => intval($infoArr['is_executable']), 00344 'content' => $infoArr['content'], 00345 'contentMD5' => $infoArr['content_md5'], 00346 ); 00347 } 00348 00349 $soap = t3lib_div::makeInstance('tx_em_Connection_Soap'); 00350 $soap->init(array('wsdl' => $this->wsdlURL, 'soapoptions' => array('trace' => 1, 'exceptions' => 0))); 00351 $response = $soap->call( 00352 'uploadExtension', 00353 array( 00354 'accountData' => $accountData, 00355 'extensionData' => $extensionData, 00356 'filesData' => $filesData 00357 ) 00358 ); 00359 00360 if ($response === FALSE) { 00361 switch (TRUE) { 00362 case is_string($soap->error): 00363 return $soap->error; 00364 break; 00365 default: 00366 return $soap->error->faultstring; 00367 } 00368 } 00369 00370 return $response; 00371 } 00372 } 00373 00374 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/connection/class.tx_em_connection_ter.php'])) { 00375 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/connection/class.tx_em_connection_ter.php']); 00376 } 00377 ?>
1.8.0