/** * Get extensions that have category plugin or category fe * * @param boolean $onlyKeys If true, only the extension keys are returned. * * @return array Array of frontend extension keys */ public static function getFrontendExtensions($onlyKeys = TRUE) { $extensions = array(); if (t3lib_div::int_from_ver(TYPO3_version) < 6001000) { $list = array(); /** @var $extensionList tx_em_Extensions_List */ $extensionList = t3lib_div::makeInstance('tx_em_Extensions_List'); $cat = tx_em_Tools::getDefaultCategory(); $path = PATH_typo3conf . 'ext/'; $extensionList->getInstExtList($path, $list, $cat, 'L'); } else { $list = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray(); } foreach ($list as $extensionName => $extensionData) { if (isset($extensionData['EM_CONF']['category'])) { if (trim($extensionData['EM_CONF']['category']) === 'plugin' || trim($extensionData['EM_CONF']['category']) === 'fe') { if ((bool) $onlyKeys) { array_push($extensions, $extensionName); } else { $extensions[$extensionName] = $extensionData; } } } } return $extensions; }
/** * Method collects and stores extension version details into the database. * * @access protected * @param SplSubject $subject a subject notifying this observer * @return void */ protected function loadIntoDB(SplSubject &$subject) { // flush every 50 rows to database if ($this->sumRecords !== 0 && $this->sumRecords % 50 === 0) { $GLOBALS['TYPO3_DB']->exec_INSERTmultipleRows('cache_extensions', self::$fieldNames, $this->arrRows, self::$fieldIndicesNoQuote); $this->arrRows = array(); } // order must match that of self::$fieldNamses! $this->arrRows[] = array($subject->getExtkey(), $subject->getVersion(), tx_em_Tools::makeVersion($subject->getVersion(), 'int'), intval($subject->getAlldownloadcounter()), intval($subject->getDownloadcounter()), !is_null($subject->getTitle()) ? $subject->getTitle() : '', $subject->getOwnerusername(), !is_null($subject->getAuthorname()) ? $subject->getAuthorname() : '', !is_null($subject->getAuthoremail()) ? $subject->getAuthoremail() : '', !is_null($subject->getAuthorcompany()) ? $subject->getAuthorcompany() : '', intval($subject->getLastuploaddate()), $subject->getT3xfilemd5(), $this->repositoryUID, tx_em_Tools::getDefaultState($subject->getState() ? $subject->getState() : ''), intval($subject->getReviewstate()), tx_em_Tools::getDefaultCategory($subject->getCategory() ? $subject->getCategory() : ''), $subject->getDescription() ? $subject->getDescription() : '', $subject->getDependencies() ? $subject->getDependencies() : '', $subject->getUploadcomment() ? $subject->getUploadcomment() : ''); ++$this->sumRecords; }
/** * Upload extension to ter * @param $em * @return */ function uploadToTER($em) { $uArr = $this->emObj->extensionDetails->makeUploadarray($em['extKey'], $em['extInfo']); if (!is_array($uArr)) { return $uArr; } // Render new version number: $newVersionBase = $em['extInfo']['EM_CONF']['version']; switch ((string) $em['upload']['mode']) { case 'new_dev': $cmd = 'dev'; break; case 'new_sub': $cmd = 'sub'; break; case 'new_main': $cmd = 'main'; break; case 'custom': $newVersionBase = $em['upload']['version']; case 'latest': default: $cmd = ''; break; } $versionArr = tx_em_Tools::renderVersion($newVersionBase, $cmd); $em['version'] = $versionArr['version']; // Create dependency / conflict information: $dependenciesArr = array(); $extKeysArr = $uArr['EM_CONF']['constraints']['depends']; if (is_array($extKeysArr)) { foreach ($extKeysArr as $extKey => $version) { if (strlen($extKey)) { $dependenciesArr[] = array('kind' => 'depends', 'extensionKey' => utf8_encode($extKey), 'versionRange' => utf8_encode($version)); } } } $extKeysArr = $uArr['EM_CONF']['constraints']['conflicts']; if (is_array($extKeysArr)) { foreach ($extKeysArr as $extKey => $version) { if (strlen($extKey)) { $dependenciesArr[] = array('kind' => 'conflicts', 'extensionKey' => utf8_encode($extKey), 'versionRange' => utf8_encode($version)); } } } // FIXME: This part must be removed, when the problem is solved on the TER-Server #5919 if (count($dependenciesArr) == 1) { $dependenciesArr[] = array('kind' => 'depends', 'extensionKey' => '', 'versionRange' => ''); } // END for Bug #5919 // Compile data for SOAP call: $accountData = array('username' => $em['user']['fe_u'], 'password' => $em['user']['fe_p']); $extensionData = array('extensionKey' => utf8_encode($em['extKey']), 'version' => utf8_encode($em['version']), 'metaData' => array('title' => utf8_encode($uArr['EM_CONF']['title']), 'description' => utf8_encode($uArr['EM_CONF']['description']), 'category' => utf8_encode($uArr['EM_CONF']['category']), 'state' => utf8_encode($uArr['EM_CONF']['state']), 'authorName' => utf8_encode($uArr['EM_CONF']['author']), 'authorEmail' => utf8_encode($uArr['EM_CONF']['author_email']), 'authorCompany' => utf8_encode($uArr['EM_CONF']['author_company'])), 'technicalData' => array('dependencies' => $dependenciesArr, 'loadOrder' => utf8_encode($uArr['EM_CONF']['loadOrder']), 'uploadFolder' => (bool) intval($uArr['EM_CONF']['uploadfolder']), 'createDirs' => utf8_encode($uArr['EM_CONF']['createDirs']), 'shy' => (bool) intval($uArr['EM_CONF']['shy']), 'modules' => utf8_encode($uArr['EM_CONF']['module']), 'modifyTables' => utf8_encode($uArr['EM_CONF']['modify_tables']), 'priority' => utf8_encode($uArr['EM_CONF']['priority']), 'clearCacheOnLoad' => (bool) intval($uArr['EM_CONF']['clearCacheOnLoad']), 'lockType' => utf8_encode($uArr['EM_CONF']['lockType']), 'doNotLoadInFEe' => utf8_encode($uArr['EM_CONF']['doNotLoadInFE']), 'docPath' => utf8_encode($uArr['EM_CONF']['docPath'])), 'infoData' => array('codeLines' => intval($uArr['misc']['codelines']), 'codeBytes' => intval($uArr['misc']['codebytes']), 'codingGuidelinesCompliance' => utf8_encode($uArr['EM_CONF']['CGLcompliance']), 'codingGuidelinesComplianceNotes' => utf8_encode($uArr['EM_CONF']['CGLcompliance_note']), 'uploadComment' => utf8_encode($em['upload']['comment']), 'techInfo' => $uArr['techInfo'])); $filesData = array(); foreach ($uArr['FILES'] as $filename => $infoArr) { $filesData[] = array('name' => utf8_encode($infoArr['name']), 'size' => intval($infoArr['size']), 'modificationTime' => intval($infoArr['mtime']), 'isExecutable' => intval($infoArr['is_executable']), 'content' => $infoArr['content'], 'contentMD5' => $infoArr['content_md5']); } $soap = t3lib_div::makeInstance('tx_em_Connection_Soap'); $soap->init(array('wsdl' => $this->wsdlURL, 'soapoptions' => array('trace' => 1, 'exceptions' => 0))); $response = $soap->call('uploadExtension', array('accountData' => $accountData, 'extensionData' => $extensionData, 'filesData' => $filesData)); if ($response === FALSE) { switch (TRUE) { case is_string($soap->error): return $soap->error; break; default: return $soap->error->faultstring; } } return $response; }
/** * Adds extension to extension list and returns new list. If -1 is returned, an error happend. * Checks dependencies etc. * * @param string Extension key * @param array Extension information array - information about installed extensions * @return string New list of installed extensions or -1 if error * @see showExtDetails() */ function addExtToList($extKey, $instExtInfo) { global $TYPO3_LOADED_EXT; // ext_emconf.php information: $conf = $instExtInfo[$extKey]['EM_CONF']; // Get list of installed extensions and add this one. $listArr = array_keys($TYPO3_LOADED_EXT); if ($conf['priority'] == 'top') { array_unshift($listArr, $extKey); } else { $listArr[] = $extKey; } // Manage other circumstances: $listArr = tx_em_Tools::managesPriorities($listArr, $instExtInfo); $listArr = $this->removeRequiredExtFromListArr($listArr); // Implode unique list of extensions to load and return: $list = implode(',', array_unique($listArr)); return $list; }
function storeXMLResult() { foreach ($this->extXMLResult as $extkey => $extArr) { $max = -1; $maxrev = -1; $last = ''; $lastrev = ''; $usecat = ''; $usetitle = ''; $usestate = ''; $useauthorcompany = ''; $useauthorname = ''; $verArr = array(); foreach ($extArr['versions'] as $version => $vArr) { $iv = tx_em_Tools::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); } } }
/** * Analyses the php-scripts of an available extension on server * * @param string Absolute path to extension * @param string Prefix for tables/classes. * @param string Extension key * @return array Information array. * @see makeDetailedExtensionAnalysis() */ public static function getClassIndexLocallangFiles($absPath, $table_class_prefix, $extKey) { $excludeForPackaging = $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging']; $filesInside = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(), $absPath, 'php,inc', 0, 99, $excludeForPackaging), $absPath); $out = array(); $reg = array(); foreach ($filesInside as $fileName) { if (substr($fileName, 0, 4) != 'ext_' && substr($fileName, 0, 6) != 'tests/') { // ignore supposed-to-be unit tests as well $baseName = basename($fileName); if (substr($baseName, 0, 9) == 'locallang' && substr($baseName, -4) == '.php') { $out['locallang'][] = $fileName; } elseif ($baseName != 'conf.php') { if (filesize($absPath . $fileName) < 500 * 1024) { $fContent = t3lib_div::getUrl($absPath . $fileName); unset($reg); if (preg_match('/\\n[[:space:]]*class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/', $fContent, $reg)) { // Find classes: $lines = explode(LF, $fContent); foreach ($lines as $l) { $line = trim($l); unset($reg); if (preg_match('/^class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/', $line, $reg)) { $out['classes'][] = $reg[1]; $out['files'][$fileName]['classes'][] = $reg[1]; if ($reg[1] !== 'ext_update' && substr($reg[1], 0, 3) != 'ux_' && !t3lib_div::isFirstPartOfStr($reg[1], $table_class_prefix) && strcmp(substr($table_class_prefix, 0, -1), $reg[1])) { $out['NSerrors']['classname'][] = $reg[1]; } else { $out['NSok']['classname'][] = $reg[1]; } } } // If class file prefixed 'class.'.... if (substr($baseName, 0, 6) == 'class.') { $fI = pathinfo($baseName); $testName = substr($baseName, 6, -(1 + strlen($fI['extension']))); if ($testName !== 'ext_update' && substr($testName, 0, 3) != 'ux_' && !t3lib_div::isFirstPartOfStr($testName, $table_class_prefix) && strcmp(substr($table_class_prefix, 0, -1), $testName)) { $out['NSerrors']['classfilename'][] = $baseName; } else { $out['NSok']['classfilename'][] = $baseName; if (is_array($out['files'][$fileName]['classes']) && tx_em_Tools::first_in_array($testName, $out['files'][$fileName]['classes'], 1)) { $out['msg'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_class_ok'), $fileName, $testName); } else { $out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_class_not_ok'), $fileName, $testName); } } } // Check for proper XCLASS definition // Match $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS'] with single or doublequotes $XclassSearch = '\\$TYPO3_CONF_VARS\\[TYPO3_MODE\\]\\[[\'"]XCLASS[\'"]\\]'; $XclassParts = preg_split('/if \\(defined\\([\'"]TYPO3_MODE[\'"]\\)(.*)' . $XclassSearch . '/', $fContent, 2); if (count($XclassParts) !== 2) { // Match $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'] with single or doublequotes $XclassSearch = '\\$GLOBALS\\[[\'"]TYPO3_CONF_VARS[\'"]\\]\\[TYPO3_MODE\\]\\[[\'"]XCLASS[\'"]\\]'; $XclassParts = preg_split('/if \\(defined\\([\'"]TYPO3_MODE[\'"]\\)(.*)' . $XclassSearch . '/', $fContent, 2); } if (count($XclassParts) == 2) { unset($reg); preg_match('/^\\[[\'"]([[:alnum:]_\\/\\.]*)[\'"]\\]/', $XclassParts[1], $reg); if ($reg[1]) { $cmpF = 'ext/' . $extKey . '/' . $fileName; if (!strcmp($reg[1], $cmpF)) { if (preg_match('/_once[[:space:]]*\\(' . $XclassSearch . '\\[[\'"]' . preg_quote($cmpF, '/') . '[\'"]\\]\\);/', $XclassParts[1])) { $out['msg'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_xclass_ok'), $fileName); } else { $out['errors'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_xclass_no_include'); } } else { $out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_xclass_incorrect'), $reg[1], $cmpF); } } else { $out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_xclass_filename'), $fileName); } } elseif (!tx_em_Tools::first_in_array('ux_', $out['files'][$fileName]['classes'])) { // No Xclass definition required if classname starts with 'ux_' $out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_xclass_found'), $fileName); } } } } } } return $out; }
/** * Double install warning. * * @param string Double-install string, eg. "LG" etc. * @param string Current scope, eg. "L" or "G" or "S" * @return string Message */ function extInformationArray_dbInst($dbInst, $current) { if (strlen($dbInst) > 1) { $others = array(); for ($a = 0; $a < strlen($dbInst); $a++) { if (substr($dbInst, $a, 1) != $current) { $others[] = '"' . $this->api->typeLabels[substr($dbInst, $a, 1)] . '"'; } } return tx_em_Tools::rfw(sprintf($GLOBALS['LANG']->getLL('extInfoArray_double_installation_infotext'), implode(' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ', $others), $this->api->typeLabels[$current])); } else { return ''; } }
/** * Returns the absolute path where the extension $extKey is installed (based on 'type' (SGL)) * * @param string Extension key * @param string Install scope type: L, G, S * @return string Returns the absolute path to the install scope given by input $type variable. It is checked if the path is a directory. Slash is appended. */ public function getExtPath($extKey, $type, $returnWithoutExtKey = FALSE) { return tx_em_Tools::getExtPath($extKey, $type, $returnWithoutExtKey); }
/** * Updates the database according to extension requirements * DBAL compliant (based on Install Tool code) * * @param string Extension key * @param array Extension information array * @return void */ function forceDBupdates($extKey, $extInfo) { $instObj = new t3lib_install(); // Updating tables and fields? if (is_array($extInfo['files']) && in_array('ext_tables.sql', $extInfo['files'])) { $fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables.sql'); $FDfile = $instObj->getFieldDefinitions_fileContent($fileContent); if (count($FDfile)) { $FDdb = $instObj->getFieldDefinitions_database(TYPO3_db); $diff = $instObj->getDatabaseExtra($FDfile, $FDdb); $update_statements = $instObj->getUpdateSuggestions($diff); foreach ((array) $update_statements['add'] as $string) { $GLOBALS['TYPO3_DB']->admin_query($string); } foreach ((array) $update_statements['change'] as $string) { $GLOBALS['TYPO3_DB']->admin_query($string); } foreach ((array) $update_statements['create_table'] as $string) { $GLOBALS['TYPO3_DB']->admin_query($string); } } } // Importing static tables? if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql', $extInfo['files'])) { $fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables_static+adt.sql'); $statements = $instObj->getStatementarray($fileContent, 1); list($statements_table, $insertCount) = $instObj->getCreateTables($statements, 1); // Traverse the tables foreach ($statements_table as $table => $query) { $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table); $GLOBALS['TYPO3_DB']->admin_query($query); if ($insertCount[$table]) { $statements_insert = $instObj->getTableInsertStatements($statements, $table); foreach ($statements_insert as $v) { $GLOBALS['TYPO3_DB']->admin_query($v); } } } } }
/** * Install translations for all selected languages for an extension * * @param string $extKey The extension key to install the translations for * @param string $lang Language code of translation to fetch * @param string $mirrorURL Mirror URL to fetch data from * @return mixed true on success, error string on fauilure */ function updateTranslation($extKey, $lang, $mirrorURL) { $l10n = $this->parentObject->terConnection->fetchTranslation($extKey, $lang, $mirrorURL); if (is_array($l10n)) { $file = PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip'; $path = 'l10n/' . $lang . '/'; if (!is_dir(PATH_typo3conf . $path)) { t3lib_div::mkdir_deep(PATH_typo3conf, $path); } t3lib_div::writeFile($file, $l10n[0]); // this prevent first update having errors t3lib_div::rmdir(PATH_typo3conf . $path . $extKey, TRUE); if (tx_em_Tools::unzip($file, PATH_typo3conf . $path)) { return TRUE; } else { return $GLOBALS['LANG']->getLL('translation_unpacking_failed'); } } else { return $l10n; } }
/** * Enables an extension * * @param $extensionKey * @return void */ public function enableExtension($extensionKey) { $this->extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this); $install = t3lib_div::makeInstance('tx_em_Install', $this); list($installedList, ) = $this->extensionList->getInstalledExtensions(); $newExtensionList = $this->extensionList->addExtToList($extensionKey, $installedList); $install->writeNewExtensionList($newExtensionList); tx_em_Tools::refreshGlobalExtList(); $install->forceDBupdates($extensionKey, $installedList[$extensionKey]); }
/** * performs various compatibility modifications * and fixes/workarounds for wireit limitations * * @param array $extensionConfigurationJSON * @param boolean $prepareForModeler * * @return array the modified configuration */ public function fixExtensionBuilderJSON($extensionConfigurationJSON, $prepareForModeler) { $extBuilderVersion = tx_em_Tools::renderVersion($extensionConfigurationJSON['log']['extension_builder_version']); $extensionConfigurationJSON['modules'] = $this->mapOldRelationTypesToNewRelationTypes($extensionConfigurationJSON['modules']); $extensionConfigurationJSON['modules'] = $this->generateUniqueIDs($extensionConfigurationJSON['modules']); $extensionConfigurationJSON['modules'] = $this->resetOutboundedPositions($extensionConfigurationJSON['modules']); $extensionConfigurationJSON['modules'] = $this->mapAdvancedMode($extensionConfigurationJSON['modules'], $prepareForModeler); $extensionConfigurationJSON['modules'] = $this->mapOldActions($extensionConfigurationJSON['modules']); if ($extBuilderVersion['version_int'] < 2000100) { $extensionConfigurationJSON = $this->importExistingActionConfiguration($extensionConfigurationJSON); } $extensionConfigurationJSON = $this->reArrangeRelations($extensionConfigurationJSON); return $extensionConfigurationJSON; }