TYPO3 API  SVNRelease
Extension.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *
00017 *  This script is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  This copyright notice MUST APPEAR in all copies of the script!
00023 ***************************************************************/
00024 
00025 /**
00026  * Utilities to manage plugins and  modules of an extension. Also useful to auto-generate the autoloader registry
00027  * file ext_autoload.php.
00028  *
00029  * @package Extbase
00030  * @subpackage Utility
00031  * @version $ID:$
00032  */
00033 class Tx_Extbase_Utility_Extension {
00034 
00035     const PLUGIN_TYPE_PLUGIN = 'list_type';
00036     const PLUGIN_TYPE_CONTENT_ELEMENT = 'CType';
00037 
00038     /**
00039      * Add auto-generated TypoScript to configure the Extbase Dispatcher.
00040      *
00041      * When adding a frontend plugin you will have to add both an entry to the TCA definition
00042      * of tt_content table AND to the TypoScript template which must initiate the rendering.
00043      * Since the static template with uid 43 is the "content.default" and practically always
00044      * used for rendering the content elements it's very useful to have this function automatically
00045      * adding the necessary TypoScript for calling the appropriate controller and action of your plugin.
00046      * It will also work for the extension "css_styled_content"
00047      * FOR USE IN ext_localconf.php FILES
00048      * Usage: 2
00049      *
00050      * @param string $extensionName The extension name (in UpperCamelCase) or the extension key (in lower_underscore)
00051      * @param string $pluginName must be a unique id for your plugin in UpperCamelCase (the string length of the extension key added to the length of the plugin name should be less than 32!)
00052      * @param string $controllerActions is an array of allowed combinations of controller and action stored in an array (controller name as key and a comma separated list of action names as value, the first controller and its first action is chosen as default)
00053      * @param string $nonCacheableControllerActions is an optional array of controller name and  action names which should not be cached (array as defined in $controllerActions)
00054      * @param string $defaultControllerAction is an optional array controller name (as array key) and action name (as array value) that should be called as default
00055      * @param string $pluginType either Tx_Extbase_Utility_Extension::TYPE_PLUGIN (default) or Tx_Extbase_Utility_Extension::TYPE_CONTENT_ELEMENT
00056      * @return void
00057      */
00058     static public function configurePlugin($extensionName, $pluginName, array $controllerActions, array $nonCacheableControllerActions = array(), $pluginType = self::PLUGIN_TYPE_PLUGIN) {
00059         if (empty($pluginName)) {
00060             throw new InvalidArgumentException('The plugin name must not be empty', 1239891987);
00061         }
00062         if (empty($extensionName)) {
00063             throw new InvalidArgumentException('The extension name was invalid (must not be empty and must match /[A-Za-z][_A-Za-z0-9]/)', 1239891989);
00064         }
00065         $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName)));
00066         $pluginSignature = strtolower($extensionName) . '_' . strtolower($pluginName);
00067         if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName])) {
00068             $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName] = array();
00069         }
00070 
00071         foreach ($controllerActions as $controllerName => $actionsList) {
00072             $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'][$controllerName] = array('actions' => t3lib_div::trimExplode(',', $actionsList));
00073             if (!empty($nonCacheableControllerActions[$controllerName])) {
00074                 $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['controllers'][$controllerName]['nonCacheableActions'] = t3lib_div::trimExplode(',', $nonCacheableControllerActions[$controllerName]);
00075             }
00076         }
00077 
00078         $pluginTemplate = 'plugin.tx_' . strtolower($extensionName) . ' {
00079     settings {
00080     }
00081     persistence {
00082         storagePid =
00083         classes {
00084         }
00085     }
00086     view {
00087         templateRootPath =
00088         layoutRootPath =
00089         partialRootPath =
00090          # with defaultPid you can specify the default page uid of this plugin. If you set this to the string "auto" the target page will be determined automatically. Defaults to an empty string that expects the target page to be the current page.
00091         defaultPid =
00092     }
00093 }';
00094         t3lib_extMgm::addTypoScript($extensionName, 'setup', '
00095 # Setting ' . $extensionName . ' plugin TypoScript
00096 ' . $pluginTemplate);
00097 
00098         switch ($pluginType) {
00099             case self::PLUGIN_TYPE_PLUGIN:
00100                 $pluginContent = trim('
00101 tt_content.list.20.' . $pluginSignature . ' = USER
00102 tt_content.list.20.' . $pluginSignature . ' {
00103     userFunc = tx_extbase_core_bootstrap->run
00104     extensionName = ' . $extensionName . '
00105     pluginName = ' . $pluginName . '
00106 }');
00107             break;
00108             case self::PLUGIN_TYPE_CONTENT_ELEMENT:
00109                 $pluginContent = trim('
00110 tt_content.' . $pluginSignature . ' = COA
00111 tt_content.' . $pluginSignature . ' {
00112     10 = < lib.stdheader
00113     20 = USER
00114     20 {
00115         userFunc = tx_extbase_core_bootstrap->run
00116         extensionName = ' . $extensionName . '
00117         pluginName = ' . $pluginName . '
00118     }
00119 }');
00120             break;
00121             default:
00122                 throw new InvalidArgumentException('The pluginType "' . $pluginType .'" is not suported', 1289858856);
00123         }
00124         $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['pluginType'] = $pluginType;
00125 
00126         t3lib_extMgm::addTypoScript($extensionName, 'setup', '
00127 # Setting ' . $extensionName . ' plugin TypoScript
00128 ' . $pluginContent, 43);
00129     }
00130 
00131     /**
00132      * Register an Extbase PlugIn into backend's list of plugins
00133      * FOR USE IN ext_tables.php FILES
00134      *
00135      * @param string $extensionName The extension name (in UpperCamelCase) or the extension key (in lower_underscore)
00136      * @param string $pluginName must be a unique id for your plugin in UpperCamelCase (the string length of the extension key added to the length of the plugin name should be less than 32!)
00137      * @param string $pluginTitle is a speaking title of the plugin that will be displayed in the drop down menu in the backend
00138      * @param string $pluginIconPathAndFilename is a path to an icon file (relative to TYPO3_mainDir), that will be displayed in the drop down menu in the backend (optional)
00139      * @return void
00140      */
00141     static public function registerPlugin($extensionName, $pluginName, $pluginTitle, $pluginIconPathAndFilename = NULL) {
00142         if (empty($pluginName)) {
00143             throw new InvalidArgumentException('The plugin name must not be empty', 1239891987);
00144         }
00145         if (empty($extensionName)) {
00146             throw new InvalidArgumentException('The extension name was invalid (must not be empty and must match /[A-Za-z][_A-Za-z0-9]/)', 1239891989);
00147         }
00148         $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName)));
00149         $pluginSignature = strtolower($extensionName) . '_' . strtolower($pluginName);
00150 
00151         t3lib_extMgm::addPlugin(array($pluginTitle, $pluginSignature, $pluginIconPathAndFilename), $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'][$pluginName]['pluginType']);
00152     }
00153 
00154     /**
00155      * This method is called from t3lib_loadModules::checkMod and it replaces old conf.php.
00156      *
00157      * @param string $moduleSignature The module name
00158      * @param string $modulePath Absolute path to module (not used by Extbase currently)
00159      * @return array Configuration of the module
00160      */
00161     public function configureModule($moduleSignature, $modulePath) {
00162         $moduleConfiguration = $GLOBALS['TBE_MODULES']['_configuration'][$moduleSignature];
00163         $iconPathAndFilename = $moduleConfiguration['icon'];
00164         if (substr($iconPathAndFilename, 0, 4) === 'EXT:') {
00165             list($extensionKey, $relativePath) = explode('/', substr($iconPathAndFilename, 4), 2);
00166             $iconPathAndFilename = t3lib_extMgm::extPath($extensionKey) . $relativePath;
00167         }
00168         // TODO: skin support
00169 
00170         $moduleLabels = array(
00171             'tabs_images' => array(
00172                 'tab' => $iconPathAndFilename,
00173             ),
00174             'labels' => array(
00175                 'tablabel' => $GLOBALS['LANG']->sL($moduleConfiguration['labels'] . ':mlang_labels_tablabel'),
00176                 'tabdescr' => $GLOBALS['LANG']->sL($moduleConfiguration['labels'] . ':mlang_labels_tabdescr'),
00177             ),
00178             'tabs' => array(
00179                 'tab' => $GLOBALS['LANG']->sL($moduleConfiguration['labels'] . ':mlang_tabs_tab')
00180             )
00181         );
00182         $GLOBALS['LANG']->addModuleLabels($moduleLabels, $moduleSignature . '_');
00183 
00184         return $moduleConfiguration;
00185     }
00186 
00187     /**
00188      * Registers an Extbase module (main or sub) to the backend interface.
00189      * FOR USE IN ext_tables.php FILES
00190      *
00191      * @param string $extensionName The extension name (in UpperCamelCase) or the extension key (in lower_underscore)
00192      * @param string $mainModuleName The main module key, $sub is the submodule key. So $main would be an index in the $TBE_MODULES array and $sub could be an element in the lists there. If $main is not set a blank $extensionName module is created
00193      * @param string $subModuleName The submodule key. If $sub is not set a blank $main module is created
00194      * @param string $position This can be used to set the position of the $sub module within the list of existing submodules for the main module. $position has this syntax: [cmd]:[submodule-key]. cmd can be "after", "before" or "top" (or blank which is default). If "after"/"before" then submodule will be inserted after/before the existing submodule with [submodule-key] if found. If not found, the bottom of list. If "top" the module is inserted in the top of the submodule list.
00195      * @param array $controllerActions is an array of allowed combinations of controller and action stored in an array (controller name as key and a comma separated list of action names as value, the first controller and its first action is chosen as default)
00196      * @param array $moduleConfiguration The configuration options of the module (icon, locallang.xml file)
00197      * @return void
00198      */
00199     static public function registerModule($extensionName, $mainModuleName = '', $subModuleName = '', $position = '', array $controllerActions, array $moduleConfiguration = array()) {
00200         if (empty($extensionName)) {
00201             throw new InvalidArgumentException('The extension name must not be empty', 1239891989);
00202         }
00203         $extensionKey = t3lib_div::camelCaseToLowerCaseUnderscored($extensionName);
00204         $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionName)));
00205 
00206         $defaultModuleConfiguration = array(
00207             'access' => 'admin',
00208             'icon' => 'EXT:extbase/ext_icon.gif',
00209             'labels' => '',
00210             'extRelPath' => t3lib_extMgm::extRelPath($extensionKey) . 'Classes/'
00211         );
00212         $moduleConfiguration = t3lib_div::array_merge_recursive_overrule($defaultModuleConfiguration, $moduleConfiguration);
00213 
00214         if ((strlen($mainModuleName) > 0) && !array_key_exists($mainModuleName, $GLOBALS['TBE_MODULES'])) {
00215             $mainModuleName = $extensionName . self::convertLowerUnderscoreToUpperCamelCase($mainModuleName);
00216         } else {
00217             $mainModuleName = (strlen($mainModuleName) > 0) ? $mainModuleName : 'web';
00218         }
00219         $moduleSignature = $mainModuleName;
00220 
00221         if ((strlen($subModuleName) > 0)) {
00222             $subModuleName = $extensionName . self::convertLowerUnderscoreToUpperCamelCase($subModuleName);
00223             $moduleSignature .= '_' . $subModuleName;
00224         }
00225 
00226         $moduleConfiguration['name'] = $moduleSignature;
00227         $moduleConfiguration['script'] = 'mod.php?M=' . rawurlencode($moduleSignature);
00228         $moduleConfiguration['extensionName'] = $extensionName;
00229         $moduleConfiguration['configureModuleFunction'] = array('Tx_Extbase_Utility_Extension', 'configureModule');
00230 
00231         $GLOBALS['TBE_MODULES']['_configuration'][$moduleSignature] = $moduleConfiguration;
00232 
00233         if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$moduleSignature])) {
00234             $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$moduleSignature] = array();
00235         }
00236         foreach($controllerActions as $controllerName => $actions) {
00237             $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$moduleSignature]['controllers'][$controllerName] = array(
00238                 'actions' => t3lib_div::trimExplode(',' , $actions)
00239             );
00240         }
00241 
00242         t3lib_extMgm::addModule($mainModuleName, $subModuleName, $position);
00243     }
00244 
00245     /**
00246      * Returns a given CamelCasedString as an lowercase string with underscores.
00247      * Example: Converts BlogExample to blog_example, and minimalValue to minimal_value
00248      *
00249      * @param string $string
00250      * @return mixed
00251      * @see t3lib_div::underscoredToLowerCamelCase()
00252      * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
00253      */
00254     static public function convertCamelCaseToLowerCaseUnderscored($string) {
00255         return t3lib_div::camelCaseToLowerCaseUnderscored($string);
00256     }
00257 
00258     /**
00259      * Returns a given string with underscores as lowerCamelCase.
00260      * Example: Converts minimal_value to minimalValue
00261      *
00262      * @param string $string
00263      * @return mixed
00264      * @see t3lib_div::underscoredToLowerCamelCase()
00265      * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
00266      */
00267     static public function convertUnderscoredToLowerCamelCase($string) {
00268         return t3lib_div::underscoredToLowerCamelCase($string);
00269     }
00270 
00271     /**
00272      * Returns a given string with underscores as UpperCamelCase.
00273      * Example: Converts blog_example to BlogExample
00274      *
00275      * @param string $string
00276      * @return string
00277      * @see t3lib_div::underscoredToUpperCamelCase()
00278      * @deprecated since Extbase 1.3.0; will be removed in Extbase 1.5.0
00279      */
00280     static public function convertLowerUnderscoreToUpperCamelCase($string) {
00281         return t3lib_div::underscoredToUpperCamelCase($string);
00282     }
00283 
00284     /**
00285      * Build the autoload registry for a given extension and place it ext_autoload.php.
00286      *
00287      * @param   string  $extensionKey   Key of the extension
00288      * @param   string  $extensionPath  full path of the extension
00289      * @param   array   $additionalAutoloadClasses additional classes to be added to the autoloader. The key must be the classname all-lowercase, the value must be the entry to be inserted
00290      * @return  string  HTML string which should be outputted
00291      */
00292     static public function createAutoloadRegistryForExtension($extensionKey, $extensionPath, $additionalAutoloadClasses = array()) {
00293         $classNameToFileMapping = array();
00294         $extensionName = str_replace(' ', '', ucwords(str_replace('_', ' ', $extensionKey)));
00295         $errors = self::buildAutoloadRegistryForSinglePath($classNameToFileMapping, $extensionPath . 'Classes/', '.*tslib.*', '$extensionClassesPath . \'|\'');
00296         if ($errors) {
00297             return $errors;
00298         }
00299         $globalPrefix = '$extensionClassesPath = t3lib_extMgm::extPath(\'' . $extensionKey . '\') . \'Classes/\';';
00300 
00301         $errors = array();
00302         foreach ($classNameToFileMapping as $className => $fileName) {
00303             if (!(strpos($className, 'tx_' . strtolower($extensionName)) === 0)) {
00304                 $errors[] = $className . ' does not start with Tx_' . $extensionName . ' and was not added to the autoloader registry.';
00305                 unset($classNameToFileMapping[$className]);
00306             }
00307         }
00308         $classNameToFileMapping = array_merge($classNameToFileMapping, $additionalAutoloadClasses);
00309         $autoloadFileString = self::generateAutoloadPHPFileData($classNameToFileMapping, $globalPrefix);
00310         if (!@file_put_contents($extensionPath . 'ext_autoload.php', $autoloadFileString)) {
00311             $errors[] = '<b>' . $extensionPath . 'ext_autoload.php could not be written!</b>';
00312         }
00313         $errors[] = 'Wrote the following data: <pre>' . htmlspecialchars($autoloadFileString) . '</pre>';
00314         return implode('<br />', $errors);
00315     }
00316 
00317     /**
00318      * Generate autoload PHP file data. Takes an associative array with class name to file mapping, and outputs it as PHP.
00319      * Does NOT escape the values in the associative array. Includes the <?php ... ?> syntax and an optional global prefix.
00320      *
00321      * @param   array   $classNameToFileMapping class name to file mapping
00322      * @param   string  $globalPrefix   Global prefix which is prepended to all code.
00323      * @return  string  The full PHP string
00324      */
00325     protected function generateAutoloadPHPFileData($classNameToFileMapping, $globalPrefix = '') {
00326         $output = '<?php' . PHP_EOL;
00327         $output .= '// DO NOT CHANGE THIS FILE! It is automatically generated by Tx_Extbase_Utility_Extension::createAutoloadRegistryForExtension.' . PHP_EOL;
00328         $output .= '// This file was generated on ' . date('Y-m-d H:i') . PHP_EOL;
00329         $output .= PHP_EOL;
00330         $output .= $globalPrefix . PHP_EOL;
00331         $output .= 'return array(' . PHP_EOL;
00332         foreach ($classNameToFileMapping as $className => $quotedFileName) {
00333             $output .= '    \'' . $className . '\' => ' . $quotedFileName . ',' . PHP_EOL;
00334         }
00335         $output .= ');' . PHP_EOL;
00336         $output .= '?>';
00337         return $output;
00338     }
00339 
00340     /**
00341      * Generate the $classNameToFileMapping for a given filePath.
00342      *
00343      * @param   array   $classNameToFileMapping (Reference to array) All values are appended to this array.
00344      * @param   string  $path   Path which should be crawled
00345      * @param   string  $excludeRegularExpression   Exclude regular expression, to exclude certain files from being processed
00346      * @param   string  $valueWrap  Wrap for the file name
00347      * @return void
00348      */
00349     static protected function buildAutoloadRegistryForSinglePath(&$classNameToFileMapping, $path, $excludeRegularExpression = '', $valueWrap = '\'|\'') {
00350 //      if (file_exists($path . 'Classes/')) {
00351 //          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>";
00352 //      }
00353         $extensionFileNames = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(), $path, 'php', FALSE, 99, $excludeRegularExpression), $path);
00354 
00355         foreach ($extensionFileNames as $extensionFileName) {
00356             $classNamesInFile = self::extractClassNames($path . $extensionFileName);
00357             if (!count($classNamesInFile)) continue;
00358             foreach ($classNamesInFile as $className) {
00359                 $classNameToFileMapping[strtolower($className)] = str_replace('|', $extensionFileName, $valueWrap);
00360             }
00361         }
00362     }
00363 
00364     /**
00365      * Extracts class names from the given file.
00366      *
00367      * @param   string  $filePath   File path (absolute)
00368      * @return  array   Class names
00369      */
00370     static protected function extractClassNames($filePath) {
00371         $fileContent = php_strip_whitespace($filePath);
00372         $classNames = array();
00373         if (FALSE) {
00374             $tokens = token_get_all($fileContent);
00375             while(1) {
00376                 // look for "class" or "interface"
00377                 $token = self::findToken($tokens, array(T_ABSTRACT, T_CLASS, T_INTERFACE));
00378                 // fetch "class" token if "abstract" was found
00379                 if ($token === 'abstract') {
00380                     $token = self::findToken($tokens, array(T_CLASS));
00381                 }
00382                 if ($token === false) {
00383                     // end of file
00384                     break;
00385                 }
00386                 // look for the name (a string) skipping only whitespace and comments
00387                 $token = self::findToken($tokens, array(T_STRING), array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT));
00388                 if ($token === false) {
00389                     // unexpected end of file or token: remove found names because of parse error
00390                     t3lib_div::sysLog('Parse error in "' . $filePath. '".', 'Core', 2);
00391                     $classNames = array();
00392                     break;
00393                 }
00394                 $token = t3lib_div::strtolower($token);
00395                 // exclude XLASS classes
00396                 if (strncmp($token, 'ux_', 3)) {
00397                     $classNames[] = $token;
00398                 }
00399             }
00400         } else {
00401             // TODO: parse PHP - skip coments and strings, apply regexp only on the remaining PHP code
00402             $matches = array();
00403             preg_match_all('/^[ \t]*(?:(?:abstract|final)?[ \t]*(?:class|interface))[ \t\n\r]+([a-zA-Z][a-zA-Z_0-9]*)/mS', $fileContent, $matches);
00404             $classNames = array_map('t3lib_div::strtolower', $matches[1]);
00405         }
00406         return $classNames;
00407     }
00408 
00409     /**
00410      * Find tokens in the tokenList
00411      *
00412      * @param   array   $tokenList  list of tokens as returned by token_get_all()
00413      * @param   array   $wantedToken    the tokens to be found
00414      * @param   array   $intermediateTokens optional: list of tokens that are allowed to skip when looking for the wanted token
00415      * @return  mixed
00416      */
00417     static protected function findToken(array &$tokenList, array $wantedTokens, array $intermediateTokens = array()) {
00418         $skipAllTokens = count($intermediateTokens) ? false : true;
00419 
00420         $returnValue = false;
00421         // Iterate with while since we need the current array position:
00422         foreach ($tokenList as $token) {
00423             // parse token (see http://www.php.net/manual/en/function.token-get-all.php for format of token list)
00424             if (is_array($token)) {
00425                 list($id, $text) = $token;
00426             } else {
00427                 $id = $text = $token;
00428             }
00429             if (in_array($id, $wantedTokens)) {
00430                 $returnValue = $text;
00431                 break;
00432             }
00433             // look for another token
00434             if ($skipAllTokens || in_array($id, $intermediateTokens)) {
00435                 continue;
00436             }
00437             break;
00438         }
00439         return $returnValue;
00440     }
00441 
00442     /**
00443      * Determines the plugin namespace of the specified plugin (defaults to "tx_[extensionname]_[pluginname]")
00444      * If plugin.tx_$pluginSignature.view.pluginNamespace is set, this value is returned
00445      * If pluginNamespace is not specified "tx_[extensionname]_[pluginname]" is returned.
00446      *
00447      * @param string $extensionName name of the extension to retrieve the namespace for
00448      * @param string $pluginName name of the plugin to retrieve the namespace for
00449      * @return string plugin namespace
00450      */
00451     static public function getPluginNamespace($extensionName, $pluginName) {
00452         $pluginSignature = strtolower($extensionName . '_' . $pluginName);
00453         $defaultPluginNamespace = 'tx_' . $pluginSignature;
00454         $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
00455         $configurationManager = $objectManager->get('Tx_Extbase_Configuration_ConfigurationManagerInterface');
00456         $frameworkConfiguration = $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, $extensionName, $pluginName);
00457         if (!isset($frameworkConfiguration['view']['pluginNamespace']) || empty($frameworkConfiguration['view']['pluginNamespace'])) {
00458             return $defaultPluginNamespace;
00459         }
00460         return $frameworkConfiguration['view']['pluginNamespace'];
00461     }
00462 
00463     /**
00464      * Iterates through the global TypoScript configuration and returns the name of the plugin
00465      * that matches specified extensionName, controllerName and actionName.
00466      * If no matching plugin was found, NULL is returned.
00467      * If more than one plugin matches and the current plugin is not configured to handle the action,
00468      * an Exception will be thrown
00469      *
00470      * @param string $extensionName name of the target extension (UpperCamelCase)
00471      * @param string $controllerName name of the target controller (UpperCamelCase)
00472      * @param string $actionName name of the target action (lowerCamelCase)
00473      * @return string name of the target plugin (UpperCamelCase) or NULL if no matching plugin configuration was found
00474      */
00475     static public function getPluginNameByAction($extensionName, $controllerName, $actionName) {
00476         $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
00477         $configurationManager = $objectManager->get('Tx_Extbase_Configuration_ConfigurationManagerInterface');
00478         $frameworkConfiguration = $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
00479             // check, whether the current plugin is configured to handle the action
00480         if ($extensionName === $frameworkConfiguration['extensionName']) {
00481             if (isset($frameworkConfiguration['controllerConfiguration'][$controllerName])
00482                 && in_array($actionName, $frameworkConfiguration['controllerConfiguration'][$controllerName]['actions'])) {
00483                 return $frameworkConfiguration['pluginName'];
00484             }
00485         }
00486         if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'])) {
00487             return NULL;
00488         }
00489         $pluginNames = array();
00490         foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['plugins'] as $pluginName => $pluginConfiguration) {
00491             if (!is_array($pluginConfiguration['controllers'])) {
00492                 continue;
00493             }
00494             foreach($pluginConfiguration['controllers'] as $pluginControllerName => $pluginControllerActions) {
00495                 if (strtolower($pluginControllerName) !== strtolower($controllerName)) {
00496                     continue;
00497                 }
00498                 if (in_array($actionName, $pluginControllerActions['actions'])) {
00499                     $pluginNames[] = $pluginName;
00500                 }
00501             }
00502         }
00503         if (count($pluginNames) > 1) {
00504             throw new Tx_Extbase_Exception('There is more than one plugin that can handle this request (Extension: "' . $extensionName . '", Controller: "' . $controllerName . '", action: "' . $actionName . '"). Please specify "pluginName" argument' , 1280825466);
00505         }
00506         return count($pluginNames) > 0 ? $pluginNames[0] : NULL;
00507     }
00508 
00509     /**
00510      * Checks if the given action is cacheable or not.
00511      *
00512      * @param string $extensionName Name of the target extension, without underscores
00513      * @param string $pluginName Name of the target plugin
00514      * @param string $controllerName Name of the target controller
00515      * @param string $actionName Name of the action to be called
00516      * @return boolean TRUE if the specified plugin action is cacheable, otherwise FALSE
00517      */
00518     static public function isActionCacheable($extensionName, $pluginName, $controllerName, $actionName) {
00519         $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
00520         $configurationManager = $objectManager->get('Tx_Extbase_Configuration_ConfigurationManagerInterface');
00521         $frameworkConfiguration = $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, $extensionName, $pluginName);
00522 
00523         if (isset($frameworkConfiguration['controllerConfiguration'][$controllerName])
00524             && is_array($frameworkConfiguration['controllerConfiguration'][$controllerName])
00525             && is_array($frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'])
00526             && in_array($actionName, $frameworkConfiguration['controllerConfiguration'][$controllerName]['nonCacheableActions'])) {
00527                 return FALSE;
00528         }
00529         return TRUE;
00530     }
00531 
00532     /**
00533      * Determines the target page of the specified plugin.
00534      * If plugin.tx_$pluginSignature.view.defaultPid is set, this value is used as target page id
00535      * If defaultPid is set to "auto", a the target pid is determined by loading the tt_content record that contains this plugin
00536      * If the page could not be determined, NULL is returned
00537      * If defaultPid is "auto" and more than one page contains the specified plugin, an Exception is thrown
00538      *
00539      * @param string $extensionName name of the extension to retrieve the target PID for
00540      * @param string $pluginName name of the plugin to retrieve the target PID for
00541      * @return integer uid of the target page or NULL if target page could not be determined
00542      */
00543     static public function getTargetPidByPlugin($extensionName, $pluginName) {
00544         $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
00545         $configurationManager = $objectManager->get('Tx_Extbase_Configuration_ConfigurationManagerInterface');
00546         $frameworkConfiguration = $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK, $extensionName, $pluginName);
00547         if (!isset($frameworkConfiguration['view']['defaultPid']) || empty($frameworkConfiguration['view']['defaultPid'])) {
00548             return NULL;
00549         }
00550         $pluginSignature = strtolower($extensionName . '_' . $pluginName);
00551         if ($frameworkConfiguration['view']['defaultPid'] === 'auto') {
00552             $pages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
00553                 'pid',
00554                 'tt_content',
00555                 'list_type=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($pluginSignature, 'tt_content') . ' AND CType="list"' . $GLOBALS['TSFE']->sys_page->enableFields('tt_content'),
00556                 '',
00557                 '',
00558                 2
00559             );
00560             if (count($pages) > 1) {
00561                 throw new Tx_Extbase_Exception('There is more than one "' . $pluginSignature . '" plugin in the current page tree. Please remove one plugin or set the TypoScript configuration "plugin.tx_' . $pluginSignature . '.view.defaultPid" to a fixed page id' , 1280773643);
00562             }
00563             return count($pages) > 0 ? $pages[0]['pid'] : NULL;
00564         }
00565         return (integer)$frameworkConfiguration['view']['defaultPid'];
00566     }
00567 }
00568 
00569 ?>