class.em_terconnection.php

Go to the documentation of this file.
00001 <?php
00002 /* **************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  (c) 2006-2008 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 if (!defined('SOAP_1_2'))   {
00031     require_once('class.nusoap.php');
00032 #   require_once('/usr/share/php/SOAP/Client.php');
00033 }
00034 require_once('class.em_soap.php');
00035 
00036 /**
00037  * TER2 connection handling class for the TYPO3 Extension Manager.
00038  *
00039  * It contains methods for downloading and uploading extensions and related code
00040  *
00041  * @author Karsten Dambekalns <karsten@typo3.org>
00042  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00043  * @package TYPO3
00044  * @subpackage EM
00045  */
00046 class SC_mod_tools_em_terconnection {
00047     var $wsdlURL;
00048 
00049     /**
00050      * Extension manager module
00051      *
00052      * @var SC_mod_tools_em_index
00053      */
00054     var $emObj;
00055 
00056     /**
00057      * Fetches an extension from the given mirror
00058      *
00059      * @param   string      $extKey Extension Key
00060      * @param   string      $version    Version to install
00061      * @param   string      $expectedMD5    Expected MD5 hash of extension file
00062      * @param   string      $mirrorURL  URL of mirror to use
00063      * @return  mixed       T3X data (array) or error message (string)
00064      */
00065     function fetchExtension($extKey, $version, $expectedMD5, $mirrorURL) {
00066         $extPath = t3lib_div::strtolower($extKey);
00067         $mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '_' . $version . '.t3x';
00068         $t3x = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent));
00069         $MD5 = md5($t3x);
00070 
00071         if($t3x===false) return 'The T3X file could not be fetched. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.';
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      * Fetches extension l10n status from the given mirror
00103      *
00104      * @param string    $extKey Extension Key
00105      * @param string    $mirrorURL  URL of mirror to use
00106      * @return mixed    Array containing l10n status data or FALSE if no status could be fetched
00107      */
00108     function fetchTranslationStatus($extKey, $mirrorURL) {
00109         $extPath = t3lib_div::strtolower($extKey);
00110         $mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '-l10n/' . $extPath . '-l10n.xml';
00111         $remote = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent));
00112 
00113         if($remote !== false) {
00114             $parsed = $this->emObj->xmlhandler->parseL10nXML($remote);
00115             return $parsed['languagePackIndex'];
00116         }
00117 
00118         return FALSE;
00119     }
00120 
00121     /**
00122      * Decode server data
00123      * This is information like the extension list, extension information etc., return data after uploads (new em_conf)
00124      *
00125      * @param   string      Data stream from remove server
00126      * @return  mixed       On success, returns an array with data array and stats array as key 0 and 1. Otherwise returns error string
00127      * @see fetchServerData(), processRepositoryReturnData()
00128      */
00129     function decodeServerData($externalData)    {
00130         $parts = explode(':',$externalData,4);
00131         $dat = base64_decode($parts[2]);
00132             // compare hashes ignoring any leading whitespace. See bug #0000365.
00133         if (ltrim($parts[0])==md5($dat))    {
00134             if ($parts[1]=='gzcompress')    {
00135                 if (function_exists('gzuncompress'))    {
00136                     $dat = gzuncompress($dat);
00137                 } else return 'Decoding Error: No decompressor available for compressed content. gzuncompress() function is not available!';
00138             }
00139             $listArr = unserialize($dat);
00140 
00141             if (is_array($listArr)) {
00142                 return $listArr;
00143             } else {
00144                 return 'Error: Unserialized information was not an array - strange!';
00145             }
00146         } else return 'Error: MD5 hashes in T3X data did not match!';
00147     }
00148 
00149     /**
00150      * Decodes extension upload array.
00151      * This kind of data is when an extension is uploaded to TER
00152      *
00153      * @param   string      Data stream
00154      * @return  mixed       Array with result on success, otherwise an error string.
00155      */
00156     function decodeExchangeData($str)   {
00157         $parts = explode(':',$str,3);
00158         if ($parts[1]=='gzcompress')    {
00159             if (function_exists('gzuncompress'))    {
00160                 $parts[2] = gzuncompress($parts[2]);
00161             } else return 'Decoding Error: No decompressor available for compressed content. gzcompress()/gzuncompress() functions are not available!';
00162         }
00163         if (md5($parts[2]) == $parts[0])    {
00164             $output = unserialize($parts[2]);
00165             if (is_array($output))  {
00166                 return array($output,'');
00167             } else return 'Error: Content could not be unserialized to an array. Strange (since MD5 hashes match!)';
00168         } else 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)';
00169     }
00170 
00171 
00172     /**
00173      * Encodes extension upload array
00174      *
00175      * @param   array       Array containing extension
00176      * @return  string      Content stream
00177      */
00178     function makeUploadDataFromArray($uploadArray)  {
00179         if (is_array($uploadArray)) {
00180             $serialized = serialize($uploadArray);
00181             $md5 = md5($serialized);
00182 
00183             $content = $md5.':';
00184             $content.= 'gzcompress:';
00185             $content.= gzcompress($serialized);
00186         }
00187         return $content;
00188     }
00189 
00190     /**
00191      * [Describe function...]
00192      *
00193      * @param   [type]      $em: ...
00194      * @return  [type]      ...
00195      */
00196     function uploadToTER($em) {
00197         $uArr = $this->emObj->makeUploadArray($em['extKey'],$em['extInfo']);
00198         if(!is_array($uArr)) return $uArr;
00199 
00200             // Render new version number:
00201         $newVersionBase = $em['extInfo']['EM_CONF']['version'];
00202         switch((string)$em['upload']['mode']) {
00203             case 'new_dev':
00204                 $cmd='dev';
00205                 break;
00206             case 'new_sub':
00207                 $cmd='sub';
00208                 break;
00209             case 'new_main':
00210                 $cmd='main';
00211                 break;
00212             case 'custom':
00213                 $newVersionBase = $em['upload']['version'];
00214             case 'latest':
00215             default:
00216                 $cmd='';
00217                 break;
00218         }
00219         $versionArr = $this->emObj->renderVersion($newVersionBase, $cmd);
00220         $em['version'] = $versionArr['version'];
00221 
00222             // Create dependency / conflict information:
00223         $dependenciesArr = array ();
00224         $extKeysArr = $uArr['EM_CONF']['constraints']['depends'];
00225 
00226         if (is_array($extKeysArr)) {
00227             foreach ($extKeysArr as $extKey => $version) {
00228                 if (strlen($extKey)) {
00229                     $dependenciesArr[] = array (
00230                         'kind' => 'depends',
00231                         'extensionKey' => utf8_encode($extKey),
00232                         'versionRange' => utf8_encode($version),
00233                     );
00234                 }
00235             }
00236         }
00237 
00238         $extKeysArr = $uArr['EM_CONF']['constraints']['conflicts'];
00239         if (is_array($extKeysArr)) {
00240             foreach ($extKeysArr as $extKey => $version) {
00241                 if (strlen($extKey)) {
00242                     $dependenciesArr[] = array (
00243                         'kind' => 'conflicts',
00244                         'extensionKey' => utf8_encode($extKey),
00245                         'versionRange' => utf8_encode($version),
00246                     );
00247                 }
00248             }
00249         }
00250         // FIXME: This part must be removed, when the problem is solved on the TER-Server #5919
00251         if (count($dependenciesArr) == 1) {
00252             $dependenciesArr[] = array (
00253                 'kind' => 'depends',
00254                 'extensionKey' => '',
00255                 'versionRange' => '',
00256             );
00257         }
00258         // END for Bug #5919
00259 
00260             // Compile data for SOAP call:
00261         $accountData = array(
00262             'username' => $em['user']['fe_u'],
00263             'password' => $em['user']['fe_p']
00264         );
00265         $extensionData = array (
00266             'extensionKey' => utf8_encode($em['extKey']),
00267             'version' => utf8_encode($em['version']),
00268             'metaData' => array (
00269                 'title' => utf8_encode($uArr['EM_CONF']['title']),
00270                 'description' => utf8_encode($uArr['EM_CONF']['description']),
00271                 'category' => utf8_encode($uArr['EM_CONF']['category']),
00272                 'state' => utf8_encode($uArr['EM_CONF']['state']),
00273                 'authorName' => utf8_encode($uArr['EM_CONF']['author']),
00274                 'authorEmail' => utf8_encode($uArr['EM_CONF']['author_email']),
00275                 'authorCompany' => utf8_encode($uArr['EM_CONF']['author_company']),
00276             ),
00277             'technicalData' => array (
00278                 'dependencies' => $dependenciesArr,
00279                 'loadOrder' => utf8_encode($uArr['EM_CONF']['loadOrder']),
00280                 'uploadFolder' => (boolean) intval($uArr['EM_CONF']['uploadfolder']),
00281                 'createDirs' => utf8_encode($uArr['EM_CONF']['createDirs']),
00282                 'shy' => (boolean) intval($uArr['EM_CONF']['shy']),
00283                 'modules' => utf8_encode($uArr['EM_CONF']['module']),
00284                 'modifyTables' => utf8_encode($uArr['EM_CONF']['modify_tables']),
00285                 'priority' => utf8_encode($uArr['EM_CONF']['priority']),
00286                 'clearCacheOnLoad' => (boolean) intval($uArr['EM_CONF']['clearCacheOnLoad']),
00287                 'lockType' => utf8_encode($uArr['EM_CONF']['lockType']),
00288             ),
00289             'infoData' => array(
00290                 'codeLines' => intval($uArr['misc']['codelines']),
00291                 'codeBytes' => intval($uArr['misc']['codebytes']),
00292                 'codingGuidelinesCompliance' => utf8_encode($uArr['EM_CONF']['CGLcompliance']),
00293                 'codingGuidelinesComplianceNotes' => utf8_encode($uArr['EM_CONF']['CGLcompliance_note']),
00294                 'uploadComment' => utf8_encode($em['upload']['comment']),
00295                 'techInfo' => $uArr['techInfo'],
00296             ),
00297         );
00298 
00299         $filesData = array();
00300         foreach ($uArr['FILES'] as $filename => $infoArr) {
00301             $content = (!defined('SOAP_1_2') && class_exists('soapclient')) ? base64_encode($infoArr['content']) : $infoArr['content']; // bug in NuSOAP - no automatic encoding
00302             $filesData['fileData'][] = array (
00303                 'name' => utf8_encode($infoArr['name']),
00304                 'size' => intval($infoArr['size']),
00305                 'modificationTime' => intval($infoArr['mtime']),
00306                 'isExecutable' => intval($infoArr['is_executable']),
00307                 'content' => $content,
00308                 'contentMD5' => $infoArr['content_md5'],
00309             );
00310         }
00311 
00312         $soap = t3lib_div::makeInstance('em_soap');
00313         $soap->init(array('wsdl'=>$this->wsdlURL,'soapoptions'=> array('trace'=>1,'exceptions'=>0)));
00314         $response = $soap->call('uploadExtension', array('accountData' => $accountData, 'extensionData' => $extensionData, 'filesData' => $filesData));
00315 
00316         if($response===false) {
00317             switch(true) {
00318             case is_string($soap->error):
00319                 return $soap->error;
00320                 break;
00321             default:
00322                 return $soap->error->faultstring;
00323             }
00324         }
00325 
00326         return $response;
00327     }
00328 }
00329 
00330 ?>

Generated on Sat Jan 3 04:23:29 2009 for TYPO3 API by  doxygen 1.4.7