Commit 126f5ace authored by speedprogs_de's avatar speedprogs_de

added mirror service, added file extension provider

git-svn-id: https://svn.typo3.org/TYPO3v4/Extensions/terfe/branches/ter_fe2@51512 735d13b6-9817-0410-8766-e36946ffe9aa
parent 06b24311
...@@ -28,30 +28,21 @@ ...@@ -28,30 +28,21 @@
*/ */
class Tx_TerFe2_ExtensionProvider_ExtensionManagerProvider extends Tx_TerFe2_ExtensionProvider_AbstractProvider { class Tx_TerFe2_ExtensionProvider_ExtensionManagerProvider extends Tx_TerFe2_ExtensionProvider_AbstractProvider {
/**
* @var string
*/
protected $extensionRootPath = 'fileadmin/ter/';
/**
* @var string
*/
protected $extensionListFile = 'typo3temp/extensions.xml.gz';
/** /**
* @var integer * @var integer
*/ */
protected $maxMirrorChecks = 2; protected $repositoryId = 1;
/** /**
* @var string * @var Tx_TerFe2_Domain_Repository_ExtensionManagerCacheEntryRepository
*/ */
protected $mirrorUrl; protected $extensionRepository;
/** /**
* @var Tx_TerFe2_Domain_Repository_ExtensionManagerCacheEntryRepository * @var Tx_TerFe2_Service_Mirror
*/ */
protected $cacheEntryRepository; protected $mirrorService;
/** /**
...@@ -65,23 +56,17 @@ ...@@ -65,23 +56,17 @@
throw new Exception('Requierd system extension "em" is not loaded'); throw new Exception('Requierd system extension "em" is not loaded');
} }
// Set extension root path // Set repository id
if (!empty($this->configuration['extensionRootPath'])) { if (!empty($this->configuration['repositoryId'])) {
$this->extensionRootPath = rtrim($this->configuration['extensionRootPath'], '/ ') . '/'; $this->repositoryId = (int) $this->configuration['repositoryId'];
}
// Set extension list file
if (!empty($this->configuration['extensionListFile'])) {
$this->extensionListFile = $this->configuration['extensionListFile'];
}
// Set maximal mirror check count
if (!empty($this->configuration['maxMirrorChecks'])) {
$this->maxMirrorChecks = (int) $this->configuration['maxMirrorChecks'];
} }
// Get repository for extension manager cache entries // Get repository for extension manager cache entries
$this->extensionRepository = t3lib_div::makeInstance('Tx_TerFe2_Domain_Repository_ExtensionManagerCacheEntryRepository'); $this->extensionRepository = t3lib_div::makeInstance('Tx_TerFe2_Domain_Repository_ExtensionManagerCacheEntryRepository');
// Get mirror service
$this->mirrorService = t3lib_div::makeInstance('Tx_TerFe2_Service_Mirror');
$this->mirrorService->setRepositoryId($this->repositoryId);
} }
...@@ -125,7 +110,7 @@ ...@@ -125,7 +110,7 @@
$filename = $this->getFileName($version, $fileType); $filename = $this->getFileName($version, $fileType);
// Get filename on mirror server // Get filename on mirror server
$filename = $this->getMirrorFileUrl($filename); $filename = $this->mirrorService->getUrlToFile($filename);
if (Tx_TerFe2_Utility_File::isLocalUrl($filename)) { if (Tx_TerFe2_Utility_File::isLocalUrl($filename)) {
$filename = Tx_TerFe2_Utility_File::getAbsolutePathFromUrl($filename); $filename = Tx_TerFe2_Utility_File::getAbsolutePathFromUrl($filename);
} }
...@@ -223,7 +208,7 @@ ...@@ -223,7 +208,7 @@
'cgl_compliance' => $extension['CGLcompliance'], 'cgl_compliance' => $extension['CGLcompliance'],
'cgl_compliance_note' => $extension['CGLcompliance_note'], 'cgl_compliance_note' => $extension['CGLcompliance_note'],
'download_counter' => (int) $extension['downloadcounter'], 'download_counter' => (int) $extension['downloadcounter'],
'manual' => NULL, 'manual' => NULL, // TODO: Implement
'name' => $extension['authorname'], 'name' => $extension['authorname'],
'email' => $extension['authoremail'], 'email' => $extension['authoremail'],
'company' => $extension['authorcompany'], 'company' => $extension['authorcompany'],
...@@ -231,8 +216,6 @@ ...@@ -231,8 +216,6 @@
'repository' => $extension['repository'], 'repository' => $extension['repository'],
'review_state' => $extension['reviewstate'], 'review_state' => $extension['reviewstate'],
'file_hash' => $extension['t3xfilemd5'], 'file_hash' => $extension['t3xfilemd5'],
'is_last_version' => $extension['lastversion'],
'last_reviewed_version' => $extension['lastreviewedversion'],
'relations' => array(), 'relations' => array(),
); );
...@@ -256,88 +239,6 @@ ...@@ -256,88 +239,6 @@
} }
/**
* Returns mirror url from local extension manager
*
* @param integer $repositoryId Id of the repository to fetch mirrors from
* @return string Mirror url
*/
protected function getMirror($repositoryId = 1) {
// Get extension manager settings
$emSettings = array(
'rep_url' => '',
'extMirrors' => '',
'selectedRepository' => (int) $repositoryId,
'selectedMirror' => 0,
);
if (!empty($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em'])) {
$extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['em']);
$emSettings = array_merge($emSettings, $extConf);
}
if (!empty($emSettings['rep_url'])) {
// Force manually added url
$mirrorUrl = $emSettings['rep_url'];
} else {
// Set selected repository to "1" if no mirrors found
$mirrors = unserialize($emSettings['extMirrors']);
if (!is_array($mirrors)) {
if ($emSettings['selectedRepository'] < 1) {
$emSettings['selectedRepository'] = 1;
}
}
// Get mirrors from repository object
$repository = t3lib_div::makeInstance('tx_em_Repository', $emSettings['selectedRepository']);
if ($repository->getMirrorListUrl()) {
$repositoryUtility = t3lib_div::makeInstance('tx_em_Repository_Utility', $repository);
$mirrors = $repositoryUtility->getMirrors(TRUE)->getMirrors();
unset($repositoryUtility);
if (!is_array($mirrors)) {
return '';
}
}
// Build url
$selectedMirror = (!empty($emSettings['selectedMirror']) ? $emSettings['selectedMirror'] : array_rand($mirrors));
$mirrorUrl = 'http://' . $mirrors[$selectedMirror]['host'] . $mirrors[$selectedMirror]['path'];
}
return rtrim($mirrorUrl, '/ ') . '/';
}
/**
* Generate the url a file on mirror server
*
* @param string $filename File name to fetch
* @return string Url to file on mirror server
*/
protected function getMirrorFileUrl($filename) {
if (empty($filename)) {
throw new Exception('No filename given to generate url');
}
// Get first mirror url
if (empty($this->mirrorUrl)) {
$this->mirrorUrl = $this->getMirror();
}
// Check mirrors if file exits
$count = 1;
while (!Tx_TerFe2_Utility_File::fileExists($this->mirrorUrl . $filename)) {
$count++;
if ($count > $this->maxMirrorChecks) {
throw new Exception('File "' . $filename . '" could not be found on ' . $this->maxMirrorChecks . ' mirrors, break');
break;
}
$this->mirrorUrl = $this->getMirror();
}
return $this->mirrorUrl . $filename;
}
/** /**
* Returns the content of an ext_emconf.php file * Returns the content of an ext_emconf.php file
* *
...@@ -352,16 +253,7 @@ ...@@ -352,16 +253,7 @@
// Fetch file from server // Fetch file from server
$filename = $this->generateFileName($extension, $version, 't3x'); $filename = $this->generateFileName($extension, $version, 't3x');
$filename = $this->getMirrorFileUrl($filename); $content = $this->mirrorService->getFile($filename);
if (Tx_TerFe2_Utility_File::isLocalUrl($filename)) {
$filename = Tx_TerFe2_Utility_File::getAbsolutePathFromUrl($filename);
$content = t3lib_div::getURL($filename);
} else {
$content = t3lib_div::getURL($filename, 0, array(TYPO3_user_agent));
}
if (empty($content)) {
throw new Exception('Can not fetch file "' . $filename . '"');
}
// Check file hash // Check file hash
if ($fileHash !== md5($content)) { if ($fileHash !== md5($content)) {
......
<?php
/*******************************************************************
* Copyright notice
*
* (c) 2011 Kai Vogel <kai.vogel@speedprogs.de>, Speedprogs.de
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
******************************************************************/
/**
* Extension provider using local files
*/
class Tx_TerFe2_ExtensionProvider_FileProvider extends Tx_TerFe2_ExtensionProvider_AbstractProvider {
/**
* @var string
*/
protected $extensionRootPath = 'fileadmin/ter/';
/**
* @var string
*/
protected $extensionListFile = 'typo3temp/extensions.xml.gz';
/**
* Initialize provider
*
* @return void
*/
public function initializeProvider() {
// Set extension root path
if (!empty($this->configuration['extensionRootPath'])) {
$this->extensionRootPath = rtrim($this->configuration['extensionRootPath'], '/ ') . '/';
}
// Set extension list file
if (!empty($this->configuration['extensionListFile'])) {
$this->extensionListFile = $this->configuration['extensionListFile'];
}
}
/**
* Returns all extensions since last run
*
* @param integer $lastRun Timestamp of last update
* @param integer $offset Offset to start with
* @param integer $count Extension count to load
* @return array Extension rows
*/
public function getExtensions($lastRun, $offset, $count) {
// Get extension list
$filename = PATH_site . $this->extensionListFile;
$extensions = $this->getExtensionsFromFile($filename, $lastRun, $offset, $count);
if (empty($extensions)) {
return array();
}
// Load missing information from ext_emconf.php
foreach ($extensions as $extensionKey => $extension) {
foreach ($extension['versions'] as $versionKey => $version) {
$info = $this->getExtensionInfo($extension['ext_key'], $version['version_string'], $version['file_hash']);
foreach ($info as $key => $value) {
if (empty($version[$key])) {
$extensions[$extensionKey]['versions'][$versionKey][$key] = $value;
}
}
}
}
return $extensions;
}
/**
* Returns the url to an extension related file
*
* @param Tx_TerFe2_Domain_Model_Version $version Version object
* @param string $fileType File type
* @return string Url to file
*/
public function getFileUrl(Tx_TerFe2_Domain_Model_Version $version, $fileType) {
$filename = $this->getFileName($version, $fileType);
$filename = PATH_site . $this->extensionRootPath . $filename;
// Check if file exists
if (!Tx_TerFe2_Utility_File::fileExists($filename)) {
throw new Exception('File "' . $filename . '" not found');
}
// Get local url from absolute path
return Tx_TerFe2_Utility_File::getUrlFromAbsolutePath($filename);
}
/**
* Returns name of an extension related file
*
* @param Tx_TerFe2_Domain_Model_Version $version Version object
* @param string $fileType File type
* @return string File name
*/
public function getFileName(Tx_TerFe2_Domain_Model_Version $version, $fileType) {
$extension = $version->getExtension()->getExtKey();
$version = $version->getVersionString();
$this->generateFileName($extension, $version, $fileType);
}
/**
* Generates the name of an extension related file
*
* @param string $extension Extension key
* @param string $version Version string
* @param string $fileType File type
* @return string File name
*/
protected function generateFileName($extension, $version, $fileType) {
if (empty($extension) || empty($version) || empty($fileType)) {
return '';
}
$extension = strtolower($extension);
$fileType = strtolower(trim($fileType, '. '));
return $extension[0] . '/' . $extension[1] . '/' . $extension . '_' . $version . '.' . $fileType;
}
/**
* Parse compressed extension list file and return updated extensions
*
* @param string $filename File name
* @param integer $lastRun Timestamp of last update
* @param integer $offset Offset to start with
* @param integer $count Extension count to load
* @return array All extension information
*/
protected function getExtensionsFromFile($filename, $lastRun = 0, $offset = 0, $count = 0) {
if (empty($filename) || !Tx_TerFe2_Utility_File::fileExists($filename)) {
throw new Exception('Given extension file does not exist');
}
$lastRun = (int) $lastRun;
$filename = 'compress.zlib://' . $filename;
$xmlContent = t3lib_div::getURL($filename);
$xml = new SimpleXMLElement($xmlContent);
if (empty($xml->extension)) {
throw new Exception('No extensions found in file');
}
$extensions = array();
$amount = 0;
$versionCount = 0;
foreach ($xml->extension as $extension) {
// Versions
$versions = array();
foreach ($extension->version as $version) {
// Check last update
$uploadDate = (int) $version->lastuploaddate;
if ($uploadDate <= $lastRun) {
continue;
}
// Check offset
$amount++;
if ($amount < $offset) {
continue;
}
// Check count
$versionCount++;
if ($versionCount > $count) {
break 2;
}
$versionString = (string) $version->attributes()->version;
$versions[$versionString] = array(
'title' => (string) $version->title,
'description' => (string) $version->description,
'version_number' => t3lib_div::int_from_ver($versionString),
'version_string' => $versionString,
'upload_date' => $uploadDate,
'upload_comment' => (string) $version->uploadcomment,
'state' => (string) $version->state,
'em_category' => (string) $version->category,
'load_order' => NULL,
'priority' => NULL,
'shy' => NULL,
'internal' => NULL,
'do_not_load_in_fe' => NULL,
'uploadfolder' => NULL,
'clear_cache_on_load' => NULL,
'module' => NULL,
'create_dirs' => NULL,
'modify_tables' => NULL,
'lock_type' => NULL,
'cgl_compliance' => NULL,
'cgl_compliance_note' => NULL,
'download_counter' => (int) $version->downloadcounter,
'manual' => NULL, // TODO: Implement
'name' => (string) $version->authorname,
'email' => (string) $version->authoremail,
'company' => (string) $version->authorcompany,
'username' => (string) $version->ownerusername,
'repository' => NULL,
'review_state' => NULL,
'file_hash' => (string) $version->t3xfilemd5,
'relations' => array(),
);
// Dependencies
$dependencies = unserialize((string) $version->dependencies);
foreach ($dependencies as $dependency) {
if (empty($dependency['extensionKey'])) {
continue;
}
$versionArray = $this->getVersionByRange($dependency['versionRange']);
$versions[$versionString]['relations'][] = array(
'relation_type' => $dependency['kind'],
'software_type' => NULL,
'relation_key' => $dependency['extensionKey'],
'minimum_version' => $versionArray[0],
'maximum_version' => $versionArray[1],
);
}
}
// Extension
if (!empty($versions)) {
$extensionKey = (string) $extension->attributes()->extensionkey;
$extensions[$extensionKey] = array(
'ext_key' => $extensionKey,
'downloads' => (int) $extension->downloadcounter,
'versions' => $versions,
);
}
}
return $extensions;
}
/**
* Returns the content of an ext_emconf.php file
*
* @param string $extension Extension key
* @param string $version Version string
* @return array Extension info array
*/
protected function getExtensionInfo($extension, $version, $fileHash) {
if (empty($extension) || empty($version) || empty($fileHash)) {
throw new Exception('Extension key, version and file hash are required to get extension info');
}
// Fetch file from extension root path
$filename = $this->generateFileName($extension, $version, 't3x');
$filename = PATH_site . $this->extensionRootPath . $filename;
$content = t3lib_div::getURL($filename);
if (empty($content)) {
throw new Exception('Can not fetch file "' . $filename . '"');
}
// Check file hash
if ($fileHash !== md5($content)) {
// TODO: Log the file hash missmatch
return array();
}
// Get EM_CONF array
$extension = Tx_TerFe2_Utility_Archive::decompressT3xStream($content);
$emConf = array();
if (!empty($extension['EM_CONF'])) {
$emConf = $extension['EM_CONF'];
}
unset($extension);
unset($emConf['dependencies'], $emConf['conflicts'], $emConf['TYPO3_version'], $emConf['PHP_version']);
// Remap keys
$keyMap = array(
'version' => 'version_string',
'category' => 'em_category',
'loadOrder' => 'load_order',
'doNotLoadInFE' => 'do_not_load_in_fe',
'clearcacheonload' => 'clear_cache_on_load',
'createDirs' => 'create_dirs',
'lockType' => 'lock_type',
'CGLcompliance' => 'cgl_compliance',
'CGLcompliance_note' => 'cgl_compliance_note',
'author' => 'name',
'author_email' => 'email',
'author_company' => 'company',
);
foreach ($emConf as $key => $value) {
if (!empty($keyMap[$key])) {
$emConf[$keyMap[$key]] = $value;
unset($emConf[$key]);
}
}
return $emConf;
}
}
?>
\ No newline at end of file
<?php
/*******************************************************************
* Copyright notice
*
* (c) 2011 Kai Vogel <kai.vogel@speedprogs.de>, Speedprogs.de
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
******************************************************************/
/**
* Extension provider for soap requests
*/
class Tx_TerFe2_ExtensionProvider_SoapProvider extends Tx_TerFe2_ExtensionProvider_AbstractProvider {
/**
* Returns all extensions since last run
*
* @param integer $lastRun Timestamp of last update
* @param integer $offset Offset to start with
* @param integer $count Extension count to load
* @return array Extension rows
*/
public function getExtensions($lastRun, $offset, $count) {
}
/**
* Returns the url to an extension related file
*
* @param Tx_TerFe2_Domain_Model_Version $version Version object
* @param string $fileType File type