Feature #19503 » extdeveval.patch
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;
|
||
}
|
||
}
|
||
?>
|