diff --git a/typo3/sysext/em/classes/class.tx_em_extensionmanager.php b/typo3/sysext/em/classes/class.tx_em_extensionmanager.php
index 4543e74..042ba55 100644
--- a/typo3/sysext/em/classes/class.tx_em_extensionmanager.php
+++ b/typo3/sysext/em/classes/class.tx_em_extensionmanager.php
@@ -261,6 +261,7 @@ class tx_em_ExtensionManager {
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['em/classes/class.tx_em_extensionamager.php']['renderHook'] as $classRef) {
$hookObject = t3lib_div::getUserObj($classRef);
if(!($hookObject instanceof tx_em_renderHook)) {
+ // @review There is no such interface as tx_em_renderHook. So the hook can never be executed.
throw new UnexpectedValueException('$hookObject must implement interface tx_em_renderHook', 1298121373);
}
$hookObject->render(
diff --git a/typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php b/typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php
index 75b8c97..772407e 100644
--- a/typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php
+++ b/typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php
@@ -90,6 +90,8 @@ class tx_em_Connection_ExtDirectServer {
*/
protected function getSettingsObject() {
if (!is_object(self::$objSettings) && !(self::$objSettings instanceof tx_em_Settings)) {
+ // @review This should be a ||, not a && (or we just trust the correct type and do an !== NULL check here
+ // (and add NULL as default value for the static field).
self::$objSettings = t3lib_div::makeInstance('tx_em_Settings');
}
return self::$objSettings;
@@ -105,6 +107,8 @@ class tx_em_Connection_ExtDirectServer {
* Render local extension list
*
* @return string $content
+ *
+ * The return type is wrong - it actually should be array
*/
public function getExtensionList() {
/** @var $list tx_em_Extensions_List */
@@ -140,6 +144,8 @@ class tx_em_Connection_ExtDirectServer {
* Render extensionlist for languages
*
* @return unknown
+ *
+ * No, not unknown, but array.
*/
public function getInstalledExtkeys() {
$list = $this->getExtensionList();
@@ -158,11 +164,15 @@ class tx_em_Connection_ExtDirectServer {
);
$keys[$i]['lang'] = array();
if (count($selectedLanguages)) {
+ // @review You don't need this if because a foreach loop for an empty array
+ // is just a no-op.
foreach ($selectedLanguages as $language) {
$keys[$i]['lang'][] = $GLOBALS['LANG']->sL('LLL:EXT:setup/mod/locallang.xml:lang_' . $language);
}
}
$i++;
+ // @review Is this intentional that non-installed extensions then leave gaps in the array
+ // keys of $keys?
}
}
@@ -178,6 +188,8 @@ class tx_em_Connection_ExtDirectServer {
* @return string $content
*/
public function getExtensionDetails() {
+ // @review The function name does not match the function content
+ // (which is the same as of the function getExtensionList).
/** @var $list tx_em_Extensions_List */
$list = t3lib_div::makeInstance('tx_em_Extensions_List');
$extList = $list->getInstalledExtensions(TRUE);
@@ -198,11 +210,13 @@ class tx_em_Connection_ExtDirectServer {
*/
public function getExtensionUpdate($extKey) {
if (isset($GLOBALS['TYPO3_LOADED_EXT'][$extKey])) {
+ // @review This should be a call to t3lib_extMgm::isLoaded() instead.
/** @var $install tx_em_Install */
$install = t3lib_div::makeInstance('tx_em_Install');
/** @var $extension tx_em_Extensions_List */
$extension = t3lib_div::makeInstance('tx_em_Extensions_List');
-
+ // @review The variable name is misleading: This is not an extension, but a utility class instance
+ // for managing/querying the list of extensions.
$extPath = t3lib_extMgm::extPath($extKey);
$type = tx_em_Tools::getExtTypeFromPath($extPath);
@@ -211,15 +225,22 @@ class tx_em_Connection_ExtDirectServer {
$extension->singleExtInfo($extKey, $typePath, $extInfo);
$extInfo = $extInfo[0];
+ // @review Please use two separate variables for this instead of overwriting $extInfo.
$extInfo['type'] = $extInfo['typeShort'];
$update = $install->checkDBupdates($extKey, $extInfo);
if ($update) {
$update = $GLOBALS['LANG']->getLL('ext_details_new_tables_fields_select') .
+ // @review $update serves two completely different purposes. Please
+ // use separate variables for this.
$update .
'
';
+ // @review You can just use the second parameter of getLL to hsc the return value.
+ // @review However, then you should do this on each and every call to getLL instead of only on "selected, very special places".
}
return $update ? $update : $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_dbUpToDate');
+ // @review This will break when the ext_details_new_tables_fields_select localllang string start with something that
+ // will cast to FALSE, e.g. a zero.
} else {
return sprintf($GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:msg_extNotInstalled') ,htmlspecialchars($extKey));
}
@@ -236,17 +257,22 @@ class tx_em_Connection_ExtDirectServer {
/** @var $extensionList tx_em_Extensions_List */
$extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this);
list($list,) = $extensionList->getInstalledExtensions();
+ // @review array_shift would be more readable.
/** @var $install tx_em_Install */
$install = t3lib_div::makeInstance('tx_em_Install');
$install->setSilentMode(TRUE);
$form = $install->updatesForm($extKey, $list[$extKey], 1, '', '', FALSE, TRUE);
+ // @review The third parameter of updatesForm is a boolean. So it should be TRUE, not 1.
if (!$form) {
+ // @review Basic rule: Never use a boolean operator on a string.
return '
' . $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:msg_extNoConfiguration') . '
'; } else { //$form = preg_replace('/', '', $form); + // @review Let's remove any deleted code. return $form; + // @review Switching the if/else would make this readable because it would remove the negation. } } @@ -254,7 +280,11 @@ class tx_em_Connection_ExtDirectServer { * Save extension configuration * * @formHandler + * @review Say what? @formHandler? * @param array $parameter + * @review Type-hint me ($parameter) + * @review Please rename and document $parameter (the name could mean anything). + * * @return array */ public function saveExtensionConfiguration($parameter) { @@ -262,31 +292,43 @@ class tx_em_Connection_ExtDirectServer { $extKey = $parameter['extkey']; $extType = $parameter['exttype']; $noSave = $parameter['noSave']; + // @review What does "noSave" mean? + // @review I propose to not use non-negated variable names in order to not + // to little decrease the readability of the code. $absPath = tx_em_Tools::getExtPath($extKey, $extType); + // @review Why not use t3lib_emtMgm::extPath here? $relPath = tx_em_Tools::typeRelPath($extType) . $extKey . '/'; + // @review Relative to what? Why doesn't the absolute path to the extension suffice? /** @var $extensionList tx_em_Extensions_List */ $extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this); list($list,) = $extensionList->getInstalledExtensions(); - + // @review I've seen this not-so-readable piece of code before. Please + // refactor it to a nice little function and use it in all places where copies of this code lives. + // The way I read this code, $list is always used as $list[$extKey]. So a function for getting + // the configuration for a single extension would be the way to go. $arr = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$extKey]); $arr = is_array($arr) ? $arr : array(); + // @review Please rename "arr" so the name makes clear what the variable contains. /** @var $tsStyleConfig t3lib_tsStyleConfig */ $tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig'); $tsStyleConfig->doNotSortCategoriesBeforeMakingForm = TRUE; + // @review Please use getters and setters instead of public properties. $theConstants = $tsStyleConfig->ext_initTSstyleConfig( t3lib_div::getUrl($absPath . 'ext_conf_template.txt'), + // @review Please do not use getUrl to read a local file. $relPath, $absPath, $GLOBALS['BACK_PATH'] ); $tsStyleConfig->ext_procesInput($parameter, array(), $theConstants, array()); + // @review That class does not have function ext_procesInput (event without the misspelling). $arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr); - + // @review Please use two separate variables for the two different "arrays of things". /** @var $install tx_em_Install */ $install = t3lib_div::makeInstance('tx_em_Install'); @@ -297,8 +339,11 @@ class tx_em_Connection_ExtDirectServer { $html = ''; if ($noSave) { $html = $install->updatesForm($extKey, $list[$extKey], 1); + // @review The third parameter of updatesForm is a boolean. So it should be TRUE, not 1. } else { $install->writeTsStyleConfig($extKey, $arr); + // @review Why is the output ($html) empty when $noSave it false? + // Is this intentional? } return array( @@ -311,6 +356,8 @@ class tx_em_Connection_ExtDirectServer { /** * Cleans EMConf of extension * + * @review Please document whether this function also directly saves the configuration. + * * @param string $extKey * @return array */ @@ -354,6 +401,8 @@ class tx_em_Connection_ExtDirectServer { $success = TRUE; if ($res) { + // @review You need to do a !== FALSE here because $res might also be a string that casts to FALSE. + // You'll need to htmlspecialchars $res first because it can contain the extension key. $res = nl2br($res); $error = sprintf($GLOBALS['LANG']->getLL('extDelete_remove_dir_failed'), $absPath); $success = FALSE; @@ -371,20 +420,27 @@ class tx_em_Connection_ExtDirectServer { * * @param object $parameter * @return array + * + * @review Please specificy the exact class of $parameter, add type hinting + * and rename it. */ public function getExtFileTree($parameter) { $type = $parameter->typeShort; + // @review $type is never read and can be removed. $node = substr($parameter->node, 0, 6) !== 'xnode-' ? $parameter->node : $parameter->baseNode; $path = PATH_site . $node; + // @review Is $node guaranteed to be safe? $fileArray = array(); $dirs = t3lib_div::get_dirs($path); + // @review $dirs will be an error string in case of an error. You need to check for that case. $files = t3lib_div::getFilesInDir($path, '', FALSE, '', ''); if (!is_array($dirs) && !is_array($files)) { + // @review The check for !is_array($dirs) needs to happen before the getFilesInDir call. return array(); } @@ -401,11 +457,13 @@ class tx_em_Connection_ExtDirectServer { foreach ($files as $key => $file) { + // @review $key is never read and can be removed. $fileInfo = $this->getFileInfo($file); $fileArray[] = array( 'id' => $node . '/' . $file, 'text' => $fileInfo[0], + // @review Why is $dir (see above) htmlspecialchared and $fileInfo[0] isn't? 'leaf' => true, 'qtip' => $fileInfo[1], 'iconCls' => $fileInfo[4], @@ -421,23 +479,45 @@ class tx_em_Connection_ExtDirectServer { /** * Read extension file and send content * + * @review Actually, the function is not specific to *extension* files at all. + * So the name and the documentation in this regard are incorrect. + * + * @review Thsi function does not *send* the content; it just returns it. + * So either the documentation or the function content are incorrect. + * * @param string $path + * + * @review Please document that $path must be relative to PATH_site. + * * @return string file content */ public function readExtFile($path) { $path = PATH_site . $path; if (@file_exists($path)) { return t3lib_div::getURL($path); + // @review Please do not use getURL for reading local files. } return ''; + // @review This does not allow the caller to differentiate between empty files and non-readable files. + // I propose to use exceptions for error cases. } /** * Save extension file * + * @review The documentation is incorrect. This function does not just save a file - + * it writes $content to $file. + * + * @review Actually, the function is not specific to *extension* files at all. + * So the name and the documentation in this regard are incorrect. + * * @param string $file * @param string $content + * @review Please document that $path must be relative to PATH_site. + * * @return boolean success + * + * @review No, this function returns an array, not a boolean. */ public function saveExtFile($file, $content) { $path = PATH_site . $file; @@ -456,6 +536,7 @@ class tx_em_Connection_ExtDirectServer { : $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:msg_fileWriteProtected', TRUE) ) : $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:ext_details_saving_disabled', TRUE); + // @review Please don't use two ternary operators in one statement. } if ($success) { @@ -466,6 +547,8 @@ class tx_em_Connection_ExtDirectServer { 'path' => $path, 'file' => basename($path), 'content' => $content, + // @review Why return the content if it has been passed as a parameter anyway, + // i.e., the caller already has it? 'error' => $error ); } @@ -495,8 +578,11 @@ class tx_em_Connection_ExtDirectServer { $fileInfo = $this->getFileInfo($result[1]); $node = array( 'id' => substr($fileInfo[0], strlen(PATH_site)), + // @review Why are only some parts htmlspecialchard, e.g., + // only in the isFolder case? 'text' => basename($fileInfo[0]), 'leaf' => !$isFolder, + // @review Here, !$isFolder always evaluates to TRUE. 'qtip' => $fileInfo[1], 'iconCls' => $fileInfo[4], 'fileType' => $fileInfo[3], @@ -521,6 +607,7 @@ class tx_em_Connection_ExtDirectServer { * @return array result */ public function renameFile($file, $newName, $isFolder) { + // @review The parameter $isFolder is never read and can be removed. $src = basename($file); $newFile = substr($file, 0, -1 * strlen($src)) . $newName; @@ -531,6 +618,7 @@ class tx_em_Connection_ExtDirectServer { 'oldFile' => $file, 'newFile' => $newFile, 'newFilename' => basename($newFile), + // @review The names "newFile" and "newFileName" do not make the differences between the two very clear. ); } @@ -544,6 +632,7 @@ class tx_em_Connection_ExtDirectServer { * @return array */ public function moveFile($file, $destination, $isFolder) { + // @review This function is a no-op, i.e., it does *not* move a file. return array( 'success' => TRUE, 'file' => $file, @@ -560,15 +649,21 @@ class tx_em_Connection_ExtDirectServer { * @return array */ public function deleteFile($file, $isFolder) { + // @review $isFolder is not used (except in the return array). So it + // probably can be dropped. $file = str_replace('//', '/', PATH_site . $file); + // @review Why this replacement? Where does the "bad" data come from, and + // cannot we fix the broken caller instead? $command['delete'][] = array( 'data' => $file ); + // @review $command needs to be declared as an array first. $result = $this->fileOperation($command); return array( 'success' => TRUE, + // @review And what if the delete operation has failed? 'file' => $file, 'isFolder' => $isFolder, 'command' => $command, @@ -587,6 +682,7 @@ class tx_em_Connection_ExtDirectServer { $diff = t3lib_div::makeInstance('t3lib_diff'); $result = $diff->makeDiffDisplay($original, $content); //debug(array($original, $content, $result)); + // @review Please drop the commented-out debug line. return array( 'success' => TRUE, 'diff' => '' . $result . '' @@ -600,6 +696,7 @@ class tx_em_Connection_ExtDirectServer { * @return array */ public function loadUploadExtToTer() { + // @review Actually, this function does not load any form. $settings = $this->getSettings(); return array( 'success' => TRUE, @@ -616,6 +713,10 @@ class tx_em_Connection_ExtDirectServer { * @formHandler * * @param string $parameter + * + * @review Please add type hinting to all array function parameters in all functions. + * @review Please rename and properly document all $parameter parameters. + * * @return array */ public function uploadExtToTer($parameter) { @@ -626,6 +727,9 @@ class tx_em_Connection_ExtDirectServer { $parameter['user']['fe_p'] = $parameter['fe_p']; $parameter['upload']['mode'] = $parameter['newversion']; $parameter['upload']['comment'] = $parameter['uploadcomment']; + // @review You're using $parameter both as the function parameter as well as + // a non-documented variable container for all kinds of purposes. Please use + // separate, well-named variables instead. /** @var $extensionList tx_em_Extensions_List */ $extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this); @@ -638,6 +742,7 @@ class tx_em_Connection_ExtDirectServer { $terConnection->wsdlURL = $wsdlURL; $parameter['extInfo'] = $list[$parameter['extKey']]; + // @review This should be a call to get the information for a single extension instead. $response = $terConnection->uploadToTER($parameter); if (!is_array($response)) { @@ -648,10 +753,12 @@ class tx_em_Connection_ExtDirectServer { ); } if ($response['resultCode'] == 10504) { //success + // @review Please use the constant instead of the magic number. $parameter['extInfo']['EM_CONF']['version'] = $response['version']; $response['resultMessages'][] = sprintf( $GLOBALS['LANG']->sL('LLL:EXT:em/language/locallang.xml:terCommunication_ext_version'), $response['version'] + // @review a hsc is missing here. ); $response['resultMessages'][] = $this->extensionDetails->updateLocalEM_CONF($parameter['extKey'], $parameter['extInfo']); } @@ -668,6 +775,8 @@ class tx_em_Connection_ExtDirectServer { * * @param string $parameter * @return string + * + * @review This function returns an array, not a string. */ public function getExtensionDevelopInfo($extKey) { /** @var $extensionList tx_em_Extensions_List*/ @@ -680,11 +789,13 @@ class tx_em_Connection_ExtDirectServer { } -/** + /** * Prints backupdelete * * @param string $parameter * @return string + * + * @review This function returns an array, not a string. */ public function getExtensionBackupDelete($extKey) { $content=''; @@ -770,6 +881,8 @@ class tx_em_Connection_ExtDirectServer { // mod menu for singleDetails + // @review Instead of having these comments before code blocks, I propose + // moving these code blocks to well-named, smaller functions. $modMenu = $GLOBALS['TBE_MODULES_EXT']['tools_em']['MOD_MENU']['singleDetails']; if (isset($modMenu) && is_array($modMenu)) { $lines[] = '