Project

General

Profile

Feature #19503 » extdeveval.patch

Administrator Admin, 2009-04-26 15:59

View differences:

mod1/index.php (working copy)
'6' => 'Display API from "ext_php_api.dat" file',
'7' => 'Convert locallang.php files to XML format',
'8' => 'Moving localizations out of ll-XML files and into csh_*',
'9' => 'Generating ext_autoload.php',
'3' => 'temp_CACHED files confirmed removal',
'10' => 'PHP source code tuning',
'11' => 'Code highlighting',
......
'16' => 'phpinfo()',
),
'extScope' => array(
'L' => 'Local',
'G' => 'Global',
'S' => 'System',
'L' => 'Local Extensions',
'G' => 'Global Extensions',
'S' => 'System Extensions',
'C' => 'Core files (tslib, t3lib)'
),
'extSel' => '',
'phpFile' => '',
......
$this->content.=$this->doc->divider(5);
break;
case 4:
case 9:
$this->content.=$this->doc->section('Select Local Extension:',$this->getSelectForLocalExtensions());
$this->content.=$this->doc->divider(5);
break;
......
$content = $inst->cacheFiles();
$this->content.=$this->doc->section('',$content,0,1);
break;
case 9: // Autoload registry
$content = 'A tool which generates the autoload registry for a given extension or the core.<hr />';
$this->content.=$this->doc->section('Generate autoload registry',$content,0,1);
require_once('./class.tx_extdeveval_buildautoloadregistry.php');
$autoloadRegistryBuilder = t3lib_div::makeInstance('tx_extdeveval_buildautoloadregistry');
$content = '';
if (!t3lib_div::_POST('build')) {
$content = '<form action="'.t3lib_div::linkThisScript().'" method="post">
<p><b>Building the autoload registry can take some seconds. Press "Build" to trigger it.</b></p>
<p>If pressing "build", the ext_autoconf.php / core_autoconf.php file will be replaced without further notice.</p>
<input type="submit" name="build" value="Build" />
</form>';
} else {
if ((string)$this->MOD_SETTINGS['extScope'] === 'C') {
$content = $autoloadRegistryBuilder->createAutoloadRegistryForCore();
} else {
$path = $this->getCurrentExtDir();
if ($path) {
$content = $autoloadRegistryBuilder->createAutoloadRegistryForExtension($this->MOD_SETTINGS['extSel'], $path);
}
}
}
$this->content.=$this->doc->section('',$content,0,1);
break;
case 10:
$content = 'A tool to tune your source code.<br />';
mod1/class.tx_extdeveval_buildautoloadregistry.php (revision 0)
<?php
/* *
* This script is part of the TYPO3 project - inspiring people to share! *
* *
* TYPO3 is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License version 2 as published by *
* the Free Software Foundation. *
* *
* This script is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
* TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
* Public License for more details. *
* */
/**
* This class contains methods to build TYPO3 autoloader registry.
*
* @author Dmitry Dulepov <dmitry@typo3.org>
* @author Sebastian Kurfürst <sebastian@typo3.org>
*/
class tx_extdeveval_buildautoloadregistry {
/**
* Build the autoload registry for a given extension and place it ext_autoload.php.
*
* @param string $extensionName Name of the extension
* @param string $extensionPath full path of the extension
* @return string HTML string which should be outputted
*/
public function createAutoloadRegistryForExtension($extensionName, $extensionPath) {
$classNameToFileMapping = array();
$errors = $this->buildAutoloadRegistryForSinglePath($classNameToFileMapping, $extensionPath, '.*tslib.*', '$extensionPath . \'|\'');
if ($errors) {
return $errors;
}
$globalPrefix = '$extensionPath = t3lib_extMgm::extPath(\'' . $extensionName . '\');';
$extensionPrefix = str_replace('_', '', $extensionName);
$errors = array();
foreach ($classNameToFileMapping as $className => $fileName) {
if (!(strpos($className, 'tx_' . $extensionPrefix) === 0)
&& !(strpos($className, 'user_' . $extensionPrefix) === 0)) {
$errors[] = $className . ' does not start with tx_' . $extensionPrefix . ' or user_' . $extensionPrefix . ' and is not added to the autoloader registry.';
unset($classNameToFileMapping[$className]);
}
}
$autoloadFileString = $this->generateAutoloadPHPFileData($classNameToFileMapping, $globalPrefix);
if (!@file_put_contents($extensionPath . 'ext_autoload.php', $autoloadFileString)) {
$errors[] = '<b>' . $extensionPath . 'ext_autoload.php could not be written!</b>';
}
$errors[] = 'Wrote the following data: <pre>' . htmlspecialchars($autoloadFileString) . '</pre>';
return implode('<br />', $errors);
}
/**
* Build the autoload registry for the core.
* That includes:
* - t3lib/
* - tslib/
* - the "lang" sysext
*
* @return string HTML string which should be outputted
*/
public function createAutoloadRegistryForCore() {
$classNameToFileMapping = array();
$this->buildAutoloadRegistryForSinglePath($classNameToFileMapping, PATH_t3lib, '', 'PATH_t3lib . \'|\'');
$this->buildAutoloadRegistryForSinglePath($classNameToFileMapping, PATH_tslib, '', 'PATH_tslib . \'|\'');
$this->buildAutoloadRegistryForSinglePath($classNameToFileMapping, t3lib_extMgm::extPath('lang'), '', 't3lib_extMgm::extPath(\'lang\') . \'|\'');
$autoloadFileString = $this->generateAutoloadPHPFileData($classNameToFileMapping);
if (!count($classNameToFileMapping)) {
return '<b>Error. No classes found.</b>';
}
if (!@file_put_contents(PATH_t3lib . 'core_autoload.php', $autoloadFileString)) {
return '<b>' . PATH_t3lib . 'core_autoload.php could not be written!</b>';
}
return PATH_t3lib . 'core_autoload.php successfully written.';
}
/**
* Generate autoload PHP file data. Takes an associative array with class name to file mapping, and outputs it as PHP.
* Does NOT escape the values in the associative array. Includes the <?php ... ?> syntax and an optional global prefix.
*
* @param array $classNameToFileMapping class name to file mapping
* @param string $globalPrefix Global prefix which is prepended to all code.
* @return string The full PHP string
*/
protected function generateAutoloadPHPFileData($classNameToFileMapping, $globalPrefix = '') {
$output = '<?php' . PHP_EOL;
$output .= '// DO NOT CHANGE THIS FILE! It is automatically generated by extdeveval::buildAutoloadRegistry.' . PHP_EOL;
$output .= '// This file was generated on ' . date('Y-m-d H:i') . PHP_EOL;
$output .= PHP_EOL;
$output .= $globalPrefix . PHP_EOL;
$output .= 'return array(' . PHP_EOL;
foreach ($classNameToFileMapping as $className => $quotedFileName) {
$output .= ' \'' . $className . '\' => ' . $quotedFileName . ',' . PHP_EOL;
}
$output .= ');' . PHP_EOL;
$output .= '?>';
return $output;
}
/**
* Generate the $classNameToFileMapping for a given filePath.
*
* @param array $classNameToFileMapping (Reference to array) All values are appended to this array.
* @param string $path Path which should be crawled
* @param string $excludeRegularExpression Exclude regular expression, to exclude certain files from being processed
* @param string $valueWrap Wrap for the file name
* @return void
*/
protected function buildAutoloadRegistryForSinglePath(&$classNameToFileMapping, $path, $excludeRegularExpression = '', $valueWrap = '\'|\'') {
if (file_exists($path . 'Classes/')) {
return "<b>This appears to be a new-style extension which has its PHP classes inside the Classes/ subdirectory. It is not needed to generate the autoload registry for these extensions.</b>";
}
$extensionFileNames = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(), $path, 'php', FALSE, 99, $excludeRegularExpression), $path);
foreach ($extensionFileNames as $extensionFileName) {
$classNamesInFile = $this->extractClassNames($path . $extensionFileName);
if (!count($classNamesInFile)) continue;
foreach ($classNamesInFile as $className) {
$classNameToFileMapping[strtolower($className)] = str_replace('|', $extensionFileName, $valueWrap);
}
}
}
/**
* Extracts class names from the given file.
*
* @param string $filePath File path (absolute)
* @return array Class names
*/
protected function extractClassNames($filePath) {
$fileContent = php_strip_whitespace($filePath);
$classNames = array();
if (function_exists('token_get_all')) {
$tokens = token_get_all($fileContent);
while(1) {
// look for "class" or "interface",
$token = $this->findToken($tokens, array(T_ABSTRACT, T_CLASS, T_INTERFACE));
if ($token === false) {
// end of file
break;
}
// look for the name (a string) skipping only whitespace and comments
$token = $this->findToken($tokens, array(T_STRING), array(T_WHITESPACE,T_COMMENT,T_DOC_COMMENT));
if ($token === false) {
// unexpected end of file or token: remove found names because of parse error
t3lib_div::sysLog('Parse error in "' . $file. '".', 'Core', 2);
$classNames = array();
break;
}
$token = t3lib_div::strtolower($token);
// exclude XLASS classes
if (strncmp($token, 'ux_', 3)) {
$classNames[] = $token;
}
}
} else {
// TODO: parse PHP - skip coments and strings, apply regexp only on the remaining PHP code
$matches = array();
preg_match_all('/^[ \t]*(?:(?:abstract|final)?[ \t]*(?:class|interface))[ \t\n\r]+([a-zA-Z][a-zA-Z_0-9]*)/mS', $fileContent, $matches);
$classNames = array_map('t3lib_div::strtolower', $matches[1]);
}
return $classNames;
}
/**
* Find tokens in the tokenList
*
* @param array $tokenList list of tokens as returned by token_get_all()
* @param array $wantedToken the tokens to be found
* @param array $intermediateTokens optional: list of tokens that are allowed to skip when looking for the wanted token
* @return mixed
*/
protected function findToken(array &$tokenList, array $wantedTokens, array $intermediateTokens = array()) {
$skipAllTokens = count($intermediateTokens) ? false : true;
$returnValue = false;
// Iterate with while since we need the current array position:
while (list(,$token) = each($tokenList)) {
// parse token (see http://www.php.net/manual/en/function.token-get-all.php for format of token list)
if (is_array($token)) {
list($id, $text) = $token;
} else {
$id = $text = $token;
}
if (in_array($id, $wantedTokens)) {
$returnValue = $text;
break;
}
// look for another token
if ($skipAllTokens || in_array($id, $intermediateTokens)) {
continue;
}
break;
}
return $returnValue;
}
}
?>
(11-11/14)