Project

General

Profile

Bug #15663 » EM_MemFix_2006-08-15.diff

Administrator Admin, 2006-08-15 13:58

View differences:

typo3_src-4.0.em/t3lib/stddb/tables.sql 2006-08-15 13:57:08.452249000 +0200
);
#
# Table structure for table 'cache_extensions'
#
CREATE TABLE cache_extensions (
extkey varchar(60) NOT NULL default '',
version varchar(10) NOT NULL default '',
alldownloadcounter int(11) unsigned NOT NULL default '0',
downloadcounter int(11) unsigned NOT NULL default '0',
title varchar(150) NOT NULL default '',
description mediumtext NOT NULL,
state int(4) NOT NULL default '0',
reviewstate int(4) unsigned NOT NULL default '0',
category int(4) NOT NULL default '0',
lastuploaddate int(11) unsigned NOT NULL default '0',
dependencies mediumtext NOT NULL,
authorname varchar(100) NOT NULL default '',
authoremail varchar(100) NOT NULL default '',
ownerusername varchar(50) NOT NULL default '',
t3xfilemd5 varchar(35) NOT NULL default '',
uploadcomment mediumtext NOT NULL,
authorcompany varchar(100) NOT NULL default '',
intversion int(11) NOT NULL default '0',
lastversion int(3) NOT NULL default '0',
lastreviewedversion int(3) NOT NULL default '0',
PRIMARY KEY (extkey,version)
);
#
# Table structure for table 'cache_hash'
#
CREATE TABLE cache_hash (
typo3_src-4.0.em/typo3/mod/tools/em/class.em_index.php 2006-08-14 22:29:32.873768750 +0200
var $maxUploadSize = 31457280; // Max size in bytes of extension upload to repository
var $kbMax = 500; // Max size in kilobytes for files to be edited.
var $doPrintContent = true; // If set (default), the function printContent() will echo the content which was collected in $this->content. You can set this to FALSE in order to echo content from elsewhere, fx. when using outbut buffering
var $listingLimit = 500; // List that many extension maximally at one time (fixing memory problems)
var $listingLimitAuthor = 250; // List that many extension maximally at one time (fixing memory problems)
/**
* Internal variable loaded with extension categories (for display/listing). Should reflect $categories above
......
$this->detailCols[1]+=6;
// see if we have an extensionlist at all
$this->xmlhandler->loadExtensionsXML();
if (!count($this->xmlhandler->extensionsXML)) {
$this->extensionCount = $this->xmlhandler->countExtensions();
if (!$this->extensionCount) {
$content .= $this->fetchMetaData('extensions');
}
if($this->MOD_SETTINGS['listOrder']=='author_company') {
$this->listingLimit = $this->listingLimitAuthor;
}
$this->pointer = intval(t3lib_div::_GP('pointer'));
$offset = $this->listingLimit*$this->pointer;
if($this->MOD_SETTINGS['display_own'] && strlen($this->fe_user['username'])) {
$this->xmlhandler->searchExtensionsXML($this->listRemote_search, $this->fe_user['username']);
$this->xmlhandler->searchExtensionsXML($this->listRemote_search, $this->fe_user['username'], $this->MOD_SETTINGS['listOrder']);
} else {
$this->xmlhandler->searchExtensionsXML($this->listRemote_search);
$this->xmlhandler->searchExtensionsXML($this->listRemote_search, '', $this->MOD_SETTINGS['listOrder'], false, false, $offset, $this->listingLimit);
}
if (count($this->xmlhandler->extensionsXML)) {
list($list,$cat) = $this->prepareImportExtList();
list($list,$cat) = $this->prepareImportExtList(true);
// Available extensions
if (is_array($cat[$this->MOD_SETTINGS['listOrder']])) {
......
}
$lines[]=$this->extensionListRow($extKey,$ext,array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass,$inst_list,1,'index.php?CMD[importExtInfo]='.rawurlencode($extKey));
unset($list[$extKey]);
}
}
}
unset($list);
// CSH:
$content.= t3lib_BEfunc::cshItem('_MOD_tools_em', 'import_ter', $GLOBALS['BACK_PATH'],'|<br/>');
......
$content.= '</form><form action="index.php" method="post" onsubmit="'.htmlspecialchars($onsubmit).'">List or look up extensions<br />
<input type="text" name="_lookUp" value="'.htmlspecialchars($this->listRemote_search).'" /> <input type="submit" value="Look up" /><br /><br />';
$content .= $this->browseLinks();
$content.= '
<!-- TER Extensions list -->
<table border="0" cellpadding="2" cellspacing="1">'.implode(chr(10),$lines).'</table>';
$content .= '<br />'.$this->browseLinks();
$content.= '<br /><br /><strong>PRIVACY NOTICE:</strong><br /> '.$this->privacyNotice;
$this->content.=$this->doc->section('Extensions in TYPO3 Extension Repository (online) - Grouped by: '.$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']],$content,0,1);
......
$this->content.=$this->doc->spacer(20);
$this->content.=$this->doc->section('Upload extension file directly (.t3x):',$content,0,1);
}
/**
* Generates a link to the next page of extensions
*
* @return void
*/
function browseLinks() {
$content = '';
if ($this->pointer) {
$content .= '<a href="'.t3lib_div::linkThisScript(array('pointer' => $this->pointer-1)).'" class="typo3-prevPage"><img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/pilleft_n.gif','width="14" height="14"').' alt="Prev page" /> Prev page</a>';
}
if ($content) $content .= '&nbsp;&nbsp;&nbsp;';
if (intval($this->extensionCount/$this->listingLimit)>$this->pointer) {
$content .= '<a href="'.t3lib_div::linkThisScript(array('pointer' => $this->pointer+1)).'" class="typo3-nextPage"><img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/pilright_n.gif','width="14" height="14"').' alt="Next page" /> Next page</a>';
}
$upper = (($this->pointer+1)*$this->listingLimit);
if ($upper>$this->extensionCount) {
$upper = $this->extensionCount;
}
if ($content) $content .= '<br /><br />Showing extensions <strong>'.($this->pointer*$this->listingLimit+1).'</strong> to <strong>'.$upper.'</strong>';
if ($content) $content .= '<br /><br />';
return $content;
}
/**
* Allows changing of settings
......
$content = '';
// Fetch remote data:
$this->xmlhandler->loadExtensionsXML();
$this->xmlhandler->extensionsXML = array($extKey => $this->xmlhandler->extensionsXML[$extKey]);
list($fetchData,) = $this->prepareImportExtList();
$this->xmlhandler->searchExtensionsXML($extKey, '', '', true, true);
list($fetchData,) = $this->prepareImportExtList(true);
$versions = array_keys($fetchData[$extKey]['versions']);
$version = ($version == '') ? end($versions) : $version;
......
$content .= '<p>Error: The extension list could not be fetched from '.$extfile.'. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.</p>';
} else {
t3lib_div::writeFile(PATH_site.'typo3temp/extensions.xml.gz', $extXML);
$content .= $this->xmlhandler->parseExtensionsXML(implode(gzfile(PATH_site.'typo3temp/extensions.xml.gz')));
$this->xmlhandler->saveExtensionsXML();
$content .= $this->xmlhandler->parseExtensionsXML(PATH_site.'typo3temp/extensions.xml.gz');
}
}
break;
......
// at this point we know we need to import (a matching version of) the extension from TER2
// see if we have an extensionlist at all
$this->xmlhandler->loadExtensionsXML();
if (!count($this->xmlhandler->extensionsXML)) {
if (!$this->xmlhandler->countExtensions()) {
$this->fetchMetaData('extensions');
}
$this->xmlhandler->searchExtensionsXML($extKey, '', '', true);
// check if extension can be fetched
if(isset($this->xmlhandler->extensionsXML[$extKey])) {
......
} else return 'Wrong file format. No data recognized, '.$fetchData;
} else return 'No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.';
} else {
$this->xmlhandler->loadExtensionsXML();
$this->xmlhandler->searchExtensionsXML($extKey, '', '', true);
// Fetch extension from TER:
if(!strlen($version)) {
......
*
* @return array List array and category index as key 0 / 1 in an array.
*/
function prepareImportExtList() {
function prepareImportExtList($unsetProc = false) {
$list = array();
$cat = $this->defaultCategories;
$filepath = $this->getMirrorURL();
......
);
}
$this->setCat($cat, $list[$extKey]['versions'][$version], $extKey);
if ($unsetProc) {
unset($this->xmlhandler->extensionsXML[$extKey]);
}
}
return array($list,$cat);
}
......
$res = array();
$res['version'] = $parts[0].'.'.$parts[1].'.'.$parts[2];
$res['version_int'] = intval(str_pad($parts[0],3,'0',STR_PAD_LEFT).str_pad($parts[1],3,'0',STR_PAD_LEFT).str_pad($parts[2],3,'0',STR_PAD_LEFT));
$res['version_int'] = intval($parts[0]*1000000+$parts[1]*1000+$parts[2]);
$res['version_main'] = $parts[0];
$res['version_sub'] = $parts[1];
$res['version_dev'] = $parts[2];
typo3_src-4.0.em/typo3/mod/tools/em/class.em_xmlhandler.php 2006-08-14 22:32:54.919853500 +0200
* @param boolean $latest If true, only the latest version is kept in the list
* @return [type] ...
*/
function searchExtensionsXML($search, $owner='') {
if(!count($this->extensionsXML)) $this->loadExtensionsXML();
reset($this->extensionsXML);
while (list($extkey, $data) = each($this->extensionsXML)) {
// Unset extension key in installed keys array (for tracking)
if(isset($this->emObj->inst_keys[$extkey])) unset($this->emObj->inst_keys[$extkey]);
function searchExtensionsXML($search, $owner='', $order = '', $allExt = false, $allVer = false, $offset = 0, $limit = 500) {
$where = '1=1';
if ($search) {
$where .= ' AND extkey LIKE \'%'.$GLOBALS['TYPO3_DB']->quoteStr($search, 'cache_extensions').'%\'';
}
if ($owner) {
$where .= ' AND ownerusername='.$GLOBALS['TYPO3_DB']->fullQuoteStr($owner, 'cache_extensions');
}
if(!(strlen($owner) || $this->useUnsupported || $allExt)) {
$where .= ' AND reviewstate>0';
}
if(!($this->useObsolete || $allExt)) {
$where .= ' AND state!=5'; // 5 == obsolete
}
switch ($order) {
case 'author_company':
$forder = 'authorname, authorcompany';
break;
case 'state':
$forder = 'state';
break;
case 'cat':
default:
$forder = 'category';
break;
}
$order = $forder.', title';
if(strlen($search) && !stristr($extkey,$search)) {
unset($this->extensionsXML[$extkey]);
continue;
if (!$allVer) {
if ($this->useUnsupported) {
$where .= ' AND lastversion>0';
} else {
$where .= ' AND lastreviewedversion>0';
}
}
$this->catArr = array();
$idx = 0;
foreach ($this->emObj->defaultCategories['cat'] as $catKey => $tmp) {
$this->catArr[$idx] = $catKey;
$idx++;
}
$this->stateArr = array();
$idx = 0;
foreach ($this->emObj->states as $state => $tmp) {
$this->stateArr[$idx] = $state;
$idx++;
}
if(strlen($owner) && !$this->checkOwner($extkey, $owner)) {
unset($this->extensionsXML[$extkey]);
continue;
}
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'cache_extensions', $where, $groupby, $order, $offset.','.$limit);
if(!strlen($owner)) {
$this->checkReviewState($this->extensionsXML[$extkey]['versions']); // if showing only own extensions, never hide unreviewed
$this->extensionsXML = array();
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
$row['category'] = $this->catArr[$row['category']];
$row['state'] = $this->stateArr[$row['state']];
if (!is_array($this->extensionsXML[$row['extkey']])) {
$this->extensionsXML[$row['extkey']] = array();
$this->extensionsXML[$row['extkey']]['downloadcounter'] = $row['alldownloadcounter'];
}
$this->removeObsolete($this->extensionsXML[$extkey]['versions']);
uksort($data['versions'], array($this->emObj, 'versionDifference')); // needed? or will the extensions always be sorted in the XML anyway? Robert?
if(!count($this->extensionsXML[$extkey]['versions'])) {
unset($this->extensionsXML[$extkey]);
if (!is_array($this->extensionsXML[$row['extkey']]['versions'])) {
$this->extensionsXML[$row['extkey']]['versions'] = array();
}
$row['dependencies'] = unserialize($row['dependencies']);
$this->extensionsXML[$row['extkey']]['versions'][$row['version']] = $row;
}
}
/**
* Checks whether at least one of the extension versions is owned by the given username
*
* @param string $extkey
* @param string $owner
* @return boolean
*/
function checkOwner($extkey, $owner) {
foreach($this->extensionsXML[$extkey]['versions'] as $ext) {
if($ext['ownerusername'] == $owner) return true;
}
return false;
function countExtensions() {
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('extkey', 'cache_extensions', '1=1', 'extkey');
$cnt = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
$GLOBALS['TYPO3_DB']->sql_free_result($res);
return $cnt;
}
/**
......
* @return boolean true on success, false on error
*/
function loadExtensionsXML() {
if(is_file(PATH_site.'typo3temp/extensions.bin')) {
$this->extensionsXML = unserialize(gzuncompress(t3lib_div::getURL(PATH_site.'typo3temp/extensions.bin')));
return true;
} else {
$this->extensionsXML = array();
return false;
}
}
/**
* Loads the pre-parsed extension list
*
* @return boolean true on success, false on error
*/
function loadReviewStates() {
if(is_file(PATH_site.'typo3temp/reviewstates.bin')) {
$this->reviewStates = unserialize(gzuncompress(t3lib_div::getURL(PATH_site.'typo3temp/reviewstates.bin')));
return true;
} else {
$this->reviewStates = array();
return false;
}
}
/**
* Enter description here...
*
* @return [type] ...
*/
function saveExtensionsXML() {
t3lib_div::writeFile(PATH_site.'typo3temp/extensions.bin',gzcompress(serialize($this->extXMLResult)));
t3lib_div::writeFile(PATH_site.'typo3temp/reviewstates.bin',gzcompress(serialize($this->reviewStates)));
$this->searchExtensionsXML('', '', true);
}
/**
......
}
/**
* Enter description here...
* Returns the reviewstate of a specific extension-key/version
*
* @param unknown_type $extKey
* @param [type] $version: ...
* @return [type] ...
*/
function getReviewState($extKey, $version) {
if(!is_array($this->reviewStates)) $this->loadReviewStates();
if(isset($this->reviewStates[$extKey])) {
return (int)$this->reviewStates[$extKey][$version];
} else {
return 0;
$where = 'extkey='.$GLOBALS['TYPO3_DB']->fullQuoteStr($extkey, 'cache_extensions').' AND version='.$GLOBALS['TYPO3_DB']->fullQuoteStr($version, 'cache_extensions');
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('reviewstate', 'cache_extensions', $where);
if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
return $row['reviewstate'];
}
$GLOBALS['TYPO3_DB']->sql_free_result($res);
return 0;
}
/**
......
if($this->useUnsupported) return;
reset($extensions);
while (list($version, $data) = each($extensions)) {
if($data['reviewstate']<1)
unset($extensions[$version]);
}
while (list($version, $data) = each($extensions)) {
if($data['reviewstate']<1)
unset($extensions[$version]);
}
}
/**
......
* @param string XML data file to parse
* @return string HTLML output informing about result
*/
function parseExtensionsXML($string) {
function parseExtensionsXML($filename) {
global $TYPO3_CONF_VARS;
$parser = xml_parser_create();
......
xml_set_element_handler($parser, array(&$this,'startElement'), array(&$this,'endElement'));
xml_set_character_data_handler($parser, array(&$this,'characterData'));
$fd = gzopen($filename, 'rb');
if (!$fd) {
$content.= 'Error opening XML extension file "'.$filename.'"';
return $content;
}
$string = gzread($fd, 0xffff); // Read 64KB
if ((double)phpversion()>=5) {
$preg_result = array();
preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/',substr($string,0,200),$preg_result);
......
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset); // us-ascii / utf-8 / iso-8859-1
}
// Parse content:
if (!xml_parse($parser, $string)) {
$content.= 'Error in XML parser while decoding extensions XML file. Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
$error = true;
}
$this->revCatArr = array();
$idx = 0;
foreach ($this->emObj->defaultCategories['cat'] as $catKey => $tmp) {
$this->revCatArr[$catKey] = $idx;
$idx++;
}
$this->revStateArr = array();
$idx = 0;
foreach ($this->emObj->states as $state => $tmp) {
$this->revStateArr[$state] = $idx;
$idx++;
}
$GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_extensions', '1=1');
$extcount = 0;
do {
if (preg_match('/.*(<extension\s+extensionkey="[^"]+">.*<\/extension>)/sU', $string, $match)>0) {
// Parse content:
if (!xml_parse($parser, $match[0], 0)) {
$content.= 'Error in XML parser while decoding extensions XML file. Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
$error = true;
break;
}
$this->storeXMLResult();
$this->extXMLResult = array();
$extcount++;
$string = substr($string, strlen($match[0]));
} else {
$len = strlen($string);
$string .= gzread($fd, 0xffff); // Read 64KB
if (strlen($string)==$len) break; // Nothing more can get read
}
} while (true);
xml_parser_free($parser);
gzclose($fd);
if(!$error) {
$content.= '<p>The extensions list has been updated and now contains '.count($this->extXMLResult).' extension entries.</p>';
$content.= '<p>The extensions list has been updated and now contains '.$extcount.' extension entries.</p>';
}
return $content;
}
function storeXMLResult() {
foreach ($this->extXMLResult as $extkey => $extArr) {
$max = -1;
$maxrev = -1;
$last = '';
$lastrev = '';
$usecat = '';
$usetitle = '';
$useauthor = '';
$verArr = array();
foreach ($extArr['versions'] as $version => $vArr) {
$iv = $this->emObj->makeVersion($version, 'int');
if ($vArr['title']&&!$usetitle) {
$usetitle = $vArr['title'];
}
if ($vArr['state']&&!$usestate) {
$usestate = $vArr['state'];
}
if ($vArr['authorcompany']&&!$useauthorcompany) {
$useauthorcompany = $vArr['authorcompany'];
}
if ($vArr['authorname']&&!$useauthorname) {
$useauthorname = $vArr['authorname'];
}
$verArr[$version] = $iv;
if ($iv>$max) {
$max = $iv;
$last = $version;
if ($vArr['title']) {
$usetitle = $vArr['title'];
}
if ($vArr['state']) {
$usestate = $vArr['state'];
}
if ($vArr['authorcompany']) {
$useauthorcompany = $vArr['authorcompany'];
}
if ($vArr['authorname']) {
$useauthorname = $vArr['authorname'];
}
$usecat = $vArr['category'];
}
if ($vArr['reviewstate'] && ($iv>$maxrev)) {
$maxrev = $iv;
$lastrev = $version;
}
}
if (!strlen($usecat)) {
$usecat = 4; // Extensions without a category end up in "misc"
} else {
if (isset($this->revCatArr[$usecat])) {
$usecat = $this->revCatArr[$usecat];
} else {
$usecat = 4; // Extensions without a category end up in "misc"
}
}
if (isset($this->revStateArr[$usestate])) {
$usestate = $this->revCatArr[$usestate];
} else {
$usestate = 999; // Extensions without a category end up in "misc"
}
foreach ($extArr['versions'] as $version => $vArr) {
$vArr['version'] = $version;
$vArr['intversion'] = $verArr[$version];
$vArr['extkey'] = $extkey;
$vArr['alldownloadcounter'] = $extArr['downloadcounter'];
$vArr['dependencies'] = serialize($vArr['dependencies']);
$vArr['category'] = $usecat;
$vArr['title'] = $usetitle;
if ($version==$last) {
$vArr['lastversion'] = 1;
}
if ($version==$lastrev) {
$vArr['lastreviewedversion'] = 1;
}
$vArr['state'] = isset($this->revStateArr[$vArr['state']])?$this->revStateArr[$vArr['state']]:$usestate; // 999 = not set category
$GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_extensions', $vArr);
}
}
}
/**
* Parses content of mirrors.xml into a suitable array
*
(4-4/8)