/** * Writes exception to different logs * * @param Exception $exception The exception * @param string the context where the exception was thrown, WEB or CLI * @return void * @see t3lib_div::sysLog(), t3lib_div::devLog() */ protected function writeLogEntries(Exception $exception, $context) { $filePathAndName = $exception->getFile(); $exceptionCodeNumber = $exception->getCode() > 0 ? '#' . $exception->getCode() . ': ' : ''; $logTitle = 'Core: Exception handler (' . $context . ')'; $logMessage = 'Uncaught TYPO3 Exception: ' . $exceptionCodeNumber . $exception->getMessage() . ' | ' . get_class($exception) . ' thrown in file ' . $filePathAndName . ' in line ' . $exception->getLine(); $backtrace = $exception->getTrace(); // write error message to the configured syslogs t3lib_div::sysLog($logMessage, $logTitle, 4); // When database credentials are wrong, the exception is probably // caused by this. Therefor we cannot do any database operation, // otherwise this will lead into recurring exceptions. try { // In case an error occurs before a database connection exists, try // to connect to the DB to be able to write the devlog/sys_log entry if (isset($GLOBALS['TYPO3_DB']) && is_object($GLOBALS['TYPO3_DB']) && empty($GLOBALS['TYPO3_DB']->link)) { $GLOBALS['TYPO3_DB']->connectDB(); } // write error message to devlog // see: $TYPO3_CONF_VARS['SYS']['enable_exceptionDLOG'] if (TYPO3_EXCEPTION_DLOG) { t3lib_div::devLog($logMessage, $logTitle, 3, array('TYPO3_MODE' => TYPO3_MODE, 'backtrace' => $backtrace)); } // write error message to sys_log table $this->writeLog($logTitle . ': ' . $logMessage); } catch (Exception $exception) { // Nothing happens here. It seems the database credentials are wrong } }
/** * Checks if a given string is a valid frame URL to be loaded in the * backend. * * @param string $url potential URL to check * * @return string either $url if $url is considered to be harmless, or an * empty string otherwise */ private static function internalSanitizeLocalUrl($url = '') { $sanitizedUrl = ''; $decodedUrl = rawurldecode($url); if ($decodedUrl !== t3lib_div::removeXSS($decodedUrl)) { $decodedUrl = ''; } if (!empty($url) && $decodedUrl !== '') { $testAbsoluteUrl = t3lib_div::resolveBackPath($decodedUrl); $testRelativeUrl = t3lib_div::resolveBackPath(t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')) . '/' . $decodedUrl); // That's what's usually carried in TYPO3_SITE_PATH $typo3_site_path = substr(t3lib_div::getIndpEnv('TYPO3_SITE_URL'), strlen(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST'))); // Pass if URL is on the current host: if (self::isValidUrl($decodedUrl)) { if (self::isOnCurrentHost($decodedUrl) && strpos($decodedUrl, t3lib_div::getIndpEnv('TYPO3_SITE_URL')) === 0) { $sanitizedUrl = $url; } // Pass if URL is an absolute file path: } elseif (t3lib_div::isAbsPath($decodedUrl) && t3lib_div::isAllowedAbsPath($decodedUrl)) { $sanitizedUrl = $url; // Pass if URL is absolute and below TYPO3 base directory: } elseif (strpos($testAbsoluteUrl, $typo3_site_path) === 0 && substr($decodedUrl, 0, 1) === '/') { $sanitizedUrl = $url; // Pass if URL is relative and below TYPO3 base directory: } elseif (strpos($testRelativeUrl, $typo3_site_path) === 0 && substr($decodedUrl, 0, 1) !== '/') { $sanitizedUrl = $url; } } if (!empty($url) && empty($sanitizedUrl)) { t3lib_div::sysLog('The URL "' . $url . '" is not considered to be local and was denied.', 'Core', t3lib_div::SYSLOG_SEVERITY_NOTICE); } return $sanitizedUrl; }
/** * Default action. * * @return array * @throws RuntimeException */ public function main() { $this->init(); $allowedIps = t3lib_div::trimExplode(',', $this->config['allowedIps'], true); if ($this->config['debug']) { t3lib_div::sysLog('Connection from ' . t3lib_div::getIndpEnv('REMOTE_ADDR'), self::$extKey); } if ($this->config['mode'] !== 'M' || count($allowedIps) && !t3lib_div::inArray($allowedIps, t3lib_div::getIndpEnv('REMOTE_ADDR'))) { $this->denyAccess(); } $this->initTSFE(); if (!empty($this->config['synchronizeDeletedAccounts']) && $this->config['synchronizeDeletedAccounts']) { $additionalFields = ', deleted'; $additionalWhere = ''; } else { $additionalFields = ''; $additionalWhere = ' AND deleted=0'; } $administrators = $this->getDatabaseConnection()->exec_SELECTgetRows('username, admin, disable, realName, email, TSconfig, starttime, endtime, lang, tx_openid_openid' . $additionalFields, 'be_users', 'admin=1 AND tx_openid_openid<>\'\'' . $additionalWhere); if (count($administrators)) { $key = $this->config['preSharedKey']; $data = json_encode($administrators); $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $data, MCRYPT_MODE_CBC, md5(md5($key))); $encrypted = base64_encode($encrypted); return $encrypted; } else { throw new RuntimeException('No administrators found', 1327586994); } }
/** * * @return string */ public function indexAction() { try { $options = $this->widgetConfiguration['options']; $apiKey = $this->widgetConfiguration['apiKey']; if (!empty($this->widgetConfiguration['templatePathAndName'])) { $this->view->setTemplatePathAndFilename(t3lib_div::getFileAbsFileName($this->widgetConfiguration['templatePathAndName'])); } $flickr = new Tx_T3orgFlickrfeed_Utility_Flickr($apiKey); if ($this->widgetConfiguration['type'] == 1 || $this->widgetConfiguration['type'] === 'tag') { // tagSearch $this->view->assign('result', $flickr->tagSearch($this->widgetConfiguration['tags'], $options)); if (is_array($this->widgetConfiguration['tags']) || $this->widgetConfiguration['tags'] instanceof Traversable) { $tags = $this->widgetConfiguration['tags']; } else { $tags = t3lib_div::trimExplode(',', $this->widgetConfiguration['tags'], true); } $this->view->assign('tags', $tags); } elseif ($this->widgetConfiguration['type'] == 2 || $this->widgetConfiguration['type'] === 'user') { // people.getPublicPhotos $this->view->assign('result', $flickr->userSearch($this->widgetConfiguration['user_id'], $options)); } else { $this->view->assign('result', $flickr->groupPoolGetPhotos($this->widgetConfiguration['group_id'], $options)); } } catch (Exception $e) { t3lib_div::sysLog($e->getMessage(), $this->request->getControllerExtensionKey(), LOG_ERR); $this->view->assign('error', $e->getMessage()); } }
/** * Renders Lorem Ipsum paragraphs. If $lipsum is provided it * will be used as source text. If not provided as an argument * or as inline argument, $lipsum is fetched from TypoScript settings. * * @param string $lipsum String of paragraphs file path or EXT:myext/path/to/file * @return string */ public function render($lipsum = NULL) { if (strlen($lipsum) === 0) { $this->getDefaultLoremIpsum(); } if (strlen($lipsum) < 255 && !preg_match('/[^a-z0-9_\\./]/i', $lipsum)) { // argument is most likely a file reference. $sourceFile = t3lib_div::getFileAbsFileName($lipsum); if (file_exists($sourceFile) === TRUE) { $lipsum = file_get_contents($sourceFile); } else { t3lib_div::sysLog('Vhs LipsumViewHelper was asked to load Lorem Ipsum from a file which does not exist. ' . 'The file was: ' . $sourceFile, 'Vhs'); $lipsum = $this->getDefaultLoremIpsum(); } } $lipsum = preg_replace('/[\\r\\n]{1,}/i', "\n", $lipsum); $paragraphs = explode("\n", $lipsum); $paragraphs = array_slice($paragraphs, 0, intval($settings['paragraphs'])); foreach ($paragraphs as $index => $paragraph) { $length = $settings['wordsPerParagraph'] + rand(0 - intval($settings['skew']), intval($settings['skew'])); $words = explode(' ', $paragraph); $paragraphs[$index] = implode(' ', array_slice($words, 0, $length)); } $lipsum = implode("\n", $paragraphs); if ((bool) $settings['html'] === TRUE) { $lipsum = $this->contentObject->parseFunc($lipsum, array(), '< ' . $settings['parseFuncTSPath']); } return $lipsum; }
/** * Writes log message. * Destination log depends on the current system mode. * For FE the function writes to the admin panel log. For BE messages are * sent to the system log. If developer log is enabled, messages are also * sent there. * * This function accepts variable number of arguments and can format * parameters. The syntax is the same as for sprintf() * * @param string $message: * to output * @return void * @see sprintf() * @see t3lib::divLog() * @see t3lib_div::sysLog() * @see t3lib_timeTrack::setTSlogMessage() */ public static function writeLogMessage($message) { if (func_num_args() > 1) { $params = func_get_args(); array_shift($params); $message = vsprintf($message, $params); } if (TYPO3_MODE === 'BE') { t3lib_div::sysLog($message, self::$extKey, 1); } if (TYPO3_DLOG) { t3lib_div::devLog($message, self::$extKey, 1); } }
/** * the only action the extbase dispatcher knows of * * @return null */ public function dispatchAction() { if (!$this->controllerName) { t3lib_div::sysLog(sprintf('There was no controller name set for class %s.', get_class($this)), 'cz_simple_cal', 2); return ''; } if (!isset($this->settings[$this->controllerName]) || !is_array($this->settings[$this->controllerName]) || !isset($this->settings[$this->controllerName]['allowedActions'])) { t3lib_div::sysLog(sprintf('There were no allowedActions set on pageId %d, so there was nothing to display for the calendar.', $GLOBALS['TSFE']->id), 'cz_simple_cal', 2); return ''; } $actions = t3lib_div::trimExplode(',', $this->settings[$this->controllerName]['allowedActions'], true); reset($actions); $this->forward(current($actions)); }
/** * Proxy for the PHP mail() function. Adds possibility to hook in and send the mails in a different way. * The hook can be used by adding function to the configuration array: * $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'] * * @param string Email address to send to. * @param string Subject line, non-encoded. (see PHP function mail()) * @param string Message content, non-encoded. (see PHP function mail()) * @param string Additional headers for the mail (see PHP function mail()) * @param string Additional flags for the sending mail tool (see PHP function mail()) * @return boolean Indicates whether the mail has been sent or not * @see PHP function mail() [] * @link http://www.php.net/manual/en/function.mail.php */ public static function mail($to, $subject, $messageBody, $additionalHeaders = null, $additionalParameters = null) { $success = TRUE; if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'])) { $parameters = array('to' => $to, 'subject' => $subject, 'messageBody' => $messageBody, 'additionalHeaders' => $additionalHeaders, 'additionalParameters' => $additionalParameters); $fakeThis = FALSE; foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'] as $hookMethod) { $success = $success && t3lib_div::callUserFunction($hookMethod, $parameters, $fakeThis); } } else { $success = @mail($to, $subject, $messageBody, $additionalHeaders, $additionalParameters); } if (!$success) { t3lib_div::sysLog('Mail to "' . $email . '" could not be sent (Subject: "' . $subject . '").', 'Core', 3); } return $success; }
/** * listAction * * @see http://www.flickr.com/services/api/flickr.photos.search.html * @see http://www.flickr.com/services/api/flickr.groups.pools.getPhotos.html * @see http://www.flickr.com/services/api/flickr.people.getPublicPhotos.html * */ public function listAction() { try { $options = $this->buildOptions(); $apiKey = $this->settings['apiKey']; $flickr = new Tx_T3orgFlickrfeed_Utility_Flickr($apiKey); if ($this->settings['type'] == 1) { // tagSearch $this->view->assign('result', $flickr->tagSearch($this->settings['tags'], $options)); $tags = t3lib_div::trimExplode(',', $this->settings['tags'], true); $this->view->assign('tags', $tags); } elseif ($this->settings['type'] == 2) { // people.getPublicPhotos $this->view->assign('result', $flickr->userSearch($this->settings['user_id'], $options)); } else { $this->view->assign('result', $flickr->groupPoolGetPhotos($this->settings['group_id'], $options)); } } catch (Exception $e) { t3lib_div::sysLog($e->getMessage(), $this->request->getControllerExtensionKey(), LOG_ERR); $this->view->assign('error', $e->getMessage()); } }
/** * This is the main method that is called when a task is executed * It MUST be implemented by all classes inheriting from this one * Note that there is no error handling, errors and failures are expected * to be handled and logged by the client implementations. * Should return true on successful execution, false on error. * * @return boolean Returns true on successful execution, false on error */ public function execute() { $success = false; $this->init(); $content = t3lib_div::getUrl($this->config['masterUrl']); if ($content) { $response = json_decode($content, true); if ($response['success']) { $key = $this->config['preSharedKey']; $encrypted = $response['data']; $data = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), ""); $records = json_decode($data, true); if (count($records)) { $this->synchronizeUsers($records); $success = true; } else { t3lib_div::sysLog('No users to be synchronized', self::$extKey, 3); } } else { t3lib_div::sysLog($response['errors'][0], self::$extKey, 3); } } return $success; }
/** * Decrypts the password for auto-login on confirmation or invitation acceptation * * @param array $dataArray: table row containing the password to be decrypted * @param array $row: incoming data containing the auto-login private key * @return void */ public function decryptPasswordForAutoLogin(array &$dataArray, array $row) { if (isset($row['auto_login_key'])) { $privateKey = $row['auto_login_key']; if ($privateKey !== '') { $password = $dataArray['tx_srfeuserregister_password']; if ($password != '') { $backend = tx_rsaauth_backendfactory::getBackend(); if (is_object($backend) && $backend->isAvailable()) { $decryptedPassword = $backend->decrypt($privateKey, $password); if ($decryptedPassword) { $dataArray['password'] = $decryptedPassword; } else { // Failed to decrypt auto login password $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_decrypt_auto_login_failed'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); } } else { // Required RSA auth backend not available // Should not happen: checked in tx_srfeuserregister_pi1_base::checkRequirements } } } } }
/** * Handles an error. * If the error is registered as exceptionalError it will by converted into an exception, to be handled * by the configured exceptionhandler. Additionall the error message is written to the configured logs. * If TYPO3_MODE is 'BE' the error message is also added to the flashMessageQueue, in FE the error message * is displayed in the admin panel (as TsLog message) * * @param integer The error level - one of the E_* constants * @param string The error message * @param string Name of the file the error occurred in * @param integer Line number where the error occurred * @return void * @throws t3lib_error_Exception with the data passed to this method if the error is registered as exceptionalError */ public function handleError($errorLevel, $errorMessage, $errorFile, $errorLine) { // don't do anything if error_reporting is disabled by an @ sign if (error_reporting() == 0) { return TRUE; } $errorLevels = array(E_WARNING => 'Warning', E_NOTICE => 'Notice', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice', E_RECOVERABLE_ERROR => 'Catchable Fatal Error'); $message = 'PHP ' . $errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine; if ($errorLevel & $this->exceptionalErrors) { throw new t3lib_error_Exception($message, 1); } else { switch ($errorLevel) { case E_USER_ERROR: case E_RECOVERABLE_ERROR: $severity = 2; break; case E_USER_WARNING: case E_WARNING: $severity = 1; break; default: $severity = 0; break; } $logTitle = 'Core: Error handler (' . TYPO3_MODE . ')'; // Write error message to the configured syslogs, // see: $TYPO3_CONF_VARS['SYS']['systemLog'] if ($errorLevel & $GLOBALS['TYPO3_CONF_VARS']['SYS']['syslogErrorReporting']) { t3lib_div::sysLog($message, $logTitle, $severity); } // In case an error occurs before a database connection exists, try // to connect to the DB to be able to write an entry to devlog/sys_log if (is_object($GLOBALS['TYPO3_DB']) && empty($GLOBALS['TYPO3_DB']->link)) { try { $GLOBALS['TYPO3_DB']->connectDB(); } catch (Exception $e) { // There's nothing more we can do at this point if the // database failed. It is up to the various log writers // to check for themselves whether the have a DB connection // available or not. } } // Write error message to devlog extension(s), // see: $TYPO3_CONF_VARS['SYS']['enable_errorDLOG'] if (TYPO3_ERROR_DLOG) { t3lib_div::devLog($message, $logTitle, $severity + 1); } // Write error message to TSlog (admin panel) if (is_object($GLOBALS['TT'])) { $GLOBALS['TT']->setTSlogMessage($logTitle . ': ' . $message, $severity + 1); } // Write error message to sys_log table (ext: belog, Tools->Log) if ($errorLevel & $GLOBALS['TYPO3_CONF_VARS']['SYS']['belogErrorReporting']) { $this->writeLog($logTitle . ': ' . $message, $severity); } // Add error message to the flashmessageQueue if (defined('TYPO3_ERRORHANDLER_MODE') && TYPO3_ERRORHANDLER_MODE == 'debug') { $flashMessage = t3lib_div::makeInstance('t3lib_FlashMessage', $message, 'PHP ' . $errorLevels[$errorLevel], $severity); t3lib_FlashMessageQueue::addMessage($flashMessage); } } // Don't execute PHP internal error handler return TRUE; }
/** * Checks if the page has a path to override. * * @param int $id * @param string $mpvar * @param int $lang * @return array */ protected function IDtoPagePathThroughOverride($id, $mpvar, $lang) { $result = false; $page = $this->getPage($id, $lang); if ($page['tx_realurl_pathoverride']) { if ($page['tx_realurl_pathsegment']) { $result = array('pagepath' => trim($page['tx_realurl_pathsegment'], '/'), 'langID' => intval($lang), 'rootpage_id' => intval($this->conf['rootpage_id'])); } else { $message = sprintf('Path override is set for page=%d (language=%d) but no segment defined!', $id, $lang); t3lib_div::sysLog($message, 'realurl', 3); $this->pObj->devLog($message, false, 2); } } return $result; }
/** * Authenticate a user (Check various conditions for the user that might invalidate its authentication, eg. password match, domain, IP, etc.) * * @param array Data of user. * @return boolean */ function authUser($user) { $OK = 100; if ($this->login['uident'] && $this->login['uname']) { // Checking password match for user: $OK = $this->compareUident($user, $this->login); if (!$OK) { // Failed login attempt (wrong password) - write that to the log! if ($this->writeAttemptLog) { $this->writelog(255, 3, 3, 1, "Login-attempt from %s (%s), username '%s', password not accepted!", array($this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $this->login['uname'])); t3lib_div::sysLog(sprintf("Login-attempt from %s (%s), username '%s', password not accepted!", $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $this->login['uname']), 'Core', 0); } if ($this->writeDevLog) { t3lib_div::devLog('Password not accepted: ' . $this->login['uident'], 'tx_sv_auth', 2); } } // Checking the domain (lockToDomain) if ($OK && $user['lockToDomain'] && $user['lockToDomain'] != $this->authInfo['HTTP_HOST']) { // Lock domain didn't match, so error: if ($this->writeAttemptLog) { $this->writelog(255, 3, 3, 1, "Login-attempt from %s (%s), username '%s', locked domain '%s' did not match '%s'!", array($this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $user[$this->db_user['username_column']], $user['lockToDomain'], $this->authInfo['HTTP_HOST'])); t3lib_div::sysLog(sprintf("Login-attempt from %s (%s), username '%s', locked domain '%s' did not match '%s'!", $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $user[$this->db_user['username_column']], $user['lockToDomain'], $this->authInfo['HTTP_HOST']), 'Core', 0); } $OK = false; } } return $OK; }
/** * Adds a common log entry for this locking API using t3lib_div::sysLog(). * Example: 25-02-08 17:58 - cms: Locking [simple::0aeafd2a67a6bb8b9543fb9ea25ecbe2]: Acquired * * @param string $message: The message to be logged * @param integer $severity: Severity - 0 is info (default), 1 is notice, 2 is warning, 3 is error, 4 is fatal error * @return void */ public function sysLog($message, $severity = 0) { if ($this->isLoggingEnabled) { t3lib_div::sysLog('Locking [' . $this->method . '::' . $this->id . ']: ' . trim($message), $this->syslogFacility, $severity); } }
/** * Creates a request an dispatches it to a controller. * * @param string $content The content * @param array $configuration The TS configuration array * @return string $content The processed content */ public function dispatch($content, $configuration) { // FIXME Remove the next lines. These are only there to generate the ext_autoload.php file //$extutil = new Tx_Extbase_Utility_Extension; //$extutil->createAutoloadRegistryForExtension('extbase', t3lib_extMgm::extPath('extbase')); //$extutil->createAutoloadRegistryForExtension('fluid', t3lib_extMgm::extPath('fluid')); $this->timeTrackPush('Extbase is called.', ''); $this->timeTrackPush('Extbase gets initialized.', ''); if (!is_array($configuration)) { t3lib_div::sysLog('Extbase was not able to dispatch the request. No configuration.', 'extbase', t3lib_div::SYSLOG_SEVERITY_ERROR); return $content; } $this->initializeConfigurationManagerAndFrameworkConfiguration($configuration); $requestBuilder = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_RequestBuilder'); $request = $requestBuilder->initialize(self::$extbaseFrameworkConfiguration); $request = $requestBuilder->build(); if (isset($this->cObj->data) && is_array($this->cObj->data)) { // we need to check the above conditions as cObj is not available in Backend. $request->setContentObjectData($this->cObj->data); $request->setIsCached($this->cObj->getUserObjectType() == tslib_cObj::OBJECTTYPE_USER); } $response = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Response'); // Request hash service $requestHashService = t3lib_div::makeInstance('Tx_Extbase_Security_Channel_RequestHashService'); // singleton $requestHashService->verifyRequest($request); $persistenceManager = self::getPersistenceManager(); $this->timeTrackPull(); $this->timeTrackPush('Extbase dispatches request.', ''); $dispatchLoopCount = 0; while (!$request->isDispatched()) { if ($dispatchLoopCount++ > 99) { throw new Tx_Extbase_MVC_Exception_InfiniteLoop('Could not ultimately dispatch the request after ' . $dispatchLoopCount . ' iterations.', 1217839467); } $controller = $this->getPreparedController($request); try { $controller->processRequest($request, $response); } catch (Tx_Extbase_MVC_Exception_StopAction $ignoredException) { } } $this->timeTrackPull(); $this->timeTrackPush('Extbase persists all changes.', ''); $flashMessages = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_FlashMessages'); // singleton $flashMessages->persist(); $persistenceManager->persistAll(); $this->timeTrackPull(); self::$reflectionService->shutdown(); if (count($response->getAdditionalHeaderData()) > 0) { $GLOBALS['TSFE']->additionalHeaderData[$request->getControllerExtensionName()] = implode("\n", $response->getAdditionalHeaderData()); } $response->sendHeaders(); $this->timeTrackPull(); return $response->getContent(); }
/** * Clears page cache. Takes into account file cache. * * @return void */ function internal_clearPageCache() { if (TYPO3_UseCachingFramework) { if (t3lib_extMgm::isLoaded('cms')) { $GLOBALS['typo3CacheManager']->getCache('cache_pages')->flush(); } } else { if (t3lib_extMgm::isLoaded('cms')) { if ($GLOBALS['TYPO3_CONF_VARS']['FE']['pageCacheToExternalFiles']) { $cacheDir = PATH_site . 'typo3temp/cache_pages'; $retVal = t3lib_div::rmdir($cacheDir, TRUE); if (!$retVal) { t3lib_div::sysLog('Could not remove page cache files in "' . $cacheDir . '"', 'Core/t3lib_tcemain', 2); } } $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_pages'); } } }
/** * Fetches RealURl configuration for the given page * * @param int $pageId * @return void */ protected function fetchRealURLConfiguration($pageId) { $rootLine = t3lib_BEfunc::BEgetRootLine($pageId); $rootPageId = $rootLine[1]['uid']; $this->config = array(); if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] as $config) { if (is_array($config) && $config['pagePath']['rootpage_id'] == $rootPageId) { $this->config = $config; return; } } if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT'])) { $this->config = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']; } } else { t3lib_div::sysLog('RealURL is not configured! Please, configure it or uninstall.', 'RealURL', 3); } }
/** * Returns a valid and XSS cleaned url for redirect, checked against configuration "allowedRedirectHosts" * * @param string $url * @return string cleaned referer or empty string if not valid */ protected function validateRedirectUrl($url) { $url = strval($url); if ($url === '') { return ''; } $decodedUrl = rawurldecode($url); $sanitizedUrl = t3lib_div::removeXSS($decodedUrl); if ($decodedUrl !== $sanitizedUrl || preg_match('#["<>\\\\]+#', $url)) { t3lib_div::sysLog(sprintf($this->pi_getLL('xssAttackDetected'), $url), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING); return ''; } // Validate the URL: if ($this->isRelativeUrl($url) || $this->isInCurrentDomain($url) || $this->isInLocalDomain($url)) { return $url; } // URL is not allowed t3lib_div::sysLog(sprintf($this->pi_getLL('noValidRedirectUrl'), $url), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING); return ''; }
/** * Start function * This class is able to generate a mail in formmail-style from the data in $V * Fields: * * [recipient]: email-adress of the one to receive the mail. If array, then all values are expected to be recipients * [attachment]: .... * * [subject]: The subject of the mail * [from_email]: Sender email. If not set, [email] is used * [from_name]: Sender name. If not set, [name] is used * [replyto_email]: Reply-to email. If not set [from_email] is used * [replyto_name]: Reply-to name. If not set [from_name] is used * [organisation]: Organization (header) * [priority]: Priority, 1-5, default 3 * [html_enabled]: If mail is sent as html * [use_base64]: If set, base64 encoding will be used instead of quoted-printable * * @param array Contains values for the field names listed above (with slashes removed if from POST input) * @param boolean Whether to base64 encode the mail content * @return void */ function start($V, $base64 = false) { $convCharset = FALSE; // do we need to convert form data? if ($GLOBALS['TSFE']->config['config']['formMailCharset']) { // Respect formMailCharset if it was set $this->charset = $GLOBALS['TSFE']->csConvObj->parse_charset($GLOBALS['TSFE']->config['config']['formMailCharset']); $convCharset = TRUE; } elseif ($GLOBALS['TSFE']->metaCharset != $GLOBALS['TSFE']->renderCharset) { // Use metaCharset for mail if different from renderCharset $this->charset = $GLOBALS['TSFE']->metaCharset; $convCharset = TRUE; } parent::start(); if ($base64 || $V['use_base64']) { $this->useBase64(); } if (isset($V['recipient'])) { // convert form data from renderCharset to mail charset $val = $V['subject'] ? $V['subject'] : 'Formmail on ' . t3lib_div::getIndpEnv('HTTP_HOST'); $this->subject = $convCharset && strlen($val) ? $GLOBALS['TSFE']->csConvObj->conv($val, $GLOBALS['TSFE']->renderCharset, $this->charset) : $val; $this->subject = $this->sanitizeHeaderString($this->subject); $val = $V['from_name'] ? $V['from_name'] : ($V['name'] ? $V['name'] : ''); // Be careful when changing $val! It is used again as the fallback value for replyto_name $this->from_name = $convCharset && strlen($val) ? $GLOBALS['TSFE']->csConvObj->conv($val, $GLOBALS['TSFE']->renderCharset, $this->charset) : $val; $this->from_name = $this->sanitizeHeaderString($this->from_name); $this->from_name = preg_match('/\\s|,/', $this->from_name) >= 1 ? '"' . $this->from_name . '"' : $this->from_name; $val = $V['replyto_name'] ? $V['replyto_name'] : $val; $this->replyto_name = $convCharset && strlen($val) ? $GLOBALS['TSFE']->csConvObj->conv($val, $GLOBALS['TSFE']->renderCharset, $this->charset) : $val; $this->replyto_name = $this->sanitizeHeaderString($this->replyto_name); $this->replyto_name = preg_match('/\\s|,/', $this->replyto_name) >= 1 ? '"' . $this->replyto_name . '"' : $this->replyto_name; $val = $V['organisation'] ? $V['organisation'] : ''; $this->organisation = $convCharset && strlen($val) ? $GLOBALS['TSFE']->csConvObj->conv($val, $GLOBALS['TSFE']->renderCharset, $this->charset) : $val; $this->organisation = $this->sanitizeHeaderString($this->organisation); $this->from_email = $V['from_email'] ? $V['from_email'] : ($V['email'] ? $V['email'] : ''); $this->from_email = t3lib_div::validEmail($this->from_email) ? $this->from_email : ''; $this->replyto_email = $V['replyto_email'] ? $V['replyto_email'] : $this->from_email; $this->replyto_email = t3lib_div::validEmail($this->replyto_email) ? $this->replyto_email : ''; $this->priority = $V['priority'] ? t3lib_div::intInRange($V['priority'], 1, 5) : 3; // Auto responder. $this->auto_respond_msg = trim($V['auto_respond_msg']) && $this->from_email ? trim($V['auto_respond_msg']) : ''; $this->auto_respond_msg = $this->sanitizeHeaderString($this->auto_respond_msg); $Plain_content = ''; $HTML_content = '<table border="0" cellpadding="2" cellspacing="2">'; // Runs through $V and generates the mail if (is_array($V)) { foreach ($V as $key => $val) { if (!t3lib_div::inList($this->reserved_names, $key)) { $space = strlen($val) > 60 ? LF : ''; $val = is_array($val) ? implode($val, LF) : $val; // convert form data from renderCharset to mail charset (HTML may use entities) $Plain_val = $convCharset && strlen($val) ? $GLOBALS['TSFE']->csConvObj->conv($val, $GLOBALS['TSFE']->renderCharset, $this->charset, 0) : $val; $HTML_val = $convCharset && strlen($val) ? $GLOBALS['TSFE']->csConvObj->conv(htmlspecialchars($val), $GLOBALS['TSFE']->renderCharset, $this->charset, 1) : htmlspecialchars($val); $Plain_content .= strtoupper($key) . ': ' . $space . $Plain_val . LF . $space; $HTML_content .= '<tr><td bgcolor="#eeeeee"><font face="Verdana" size="1"><strong>' . strtoupper($key) . '</strong></font></td><td bgcolor="#eeeeee"><font face="Verdana" size="1">' . nl2br($HTML_val) . ' </font></td></tr>'; } } } $HTML_content .= '</table>'; if ($V['html_enabled']) { $this->setHTML($this->encodeMsg($HTML_content)); } $this->addPlain($Plain_content); for ($a = 0; $a < 10; $a++) { $varname = 'attachment' . ($a ? $a : ''); if (!isset($_FILES[$varname])) { continue; } if (!is_uploaded_file($_FILES[$varname]['tmp_name'])) { t3lib_div::sysLog('Possible abuse of t3lib_formmail: temporary file "' . $_FILES[$varname]['tmp_name'] . '" ("' . $_FILES[$varname]['name'] . '") was not an uploaded file.', 'Core', 3); } if ($_FILES[$varname]['tmp_name']['error'] !== UPLOAD_ERR_OK) { t3lib_div::sysLog('Error in uploaded file in t3lib_formmail: temporary file "' . $_FILES[$varname]['tmp_name'] . '" ("' . $_FILES[$varname]['name'] . '") Error code: ' . $_FILES[$varname]['tmp_name']['error'], 'Core', 3); } $theFile = t3lib_div::upload_to_tempfile($_FILES[$varname]['tmp_name']); $theName = $_FILES[$varname]['name']; if ($theFile && file_exists($theFile)) { if (filesize($theFile) < $GLOBALS['TYPO3_CONF_VARS']['FE']['formmailMaxAttachmentSize']) { $this->addAttachment($theFile, $theName); } } t3lib_div::unlink_tempfile($theFile); } $this->setHeaders(); $this->setContent(); $this->setRecipient($V['recipient']); if ($V['recipient_copy']) { $this->recipient_copy = trim($V['recipient_copy']); } // log dirty header lines if ($this->dirtyHeaders) { t3lib_div::sysLog('Possible misuse of t3lib_formmail: see TYPO3 devLog', 'Core', 3); if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']) { t3lib_div::devLog('t3lib_formmail: ' . t3lib_div::arrayToLogString($this->dirtyHeaders, '', 200), 'Core', 3); } } } }
/** * Gets the domain to be used on setting cookies. * The information is taken from the value in $TYPO3_CONF_VARS[SYS][cookieDomain]. * * @return string The domain to be used on setting cookies */ protected function getCookieDomain() { $result = ''; $cookieDomain = $GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieDomain']; if ($cookieDomain) { if ($cookieDomain[0] == '/') { $matchCnt = @preg_match($cookieDomain, t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'), $match); if ($matchCnt === FALSE) { t3lib_div::sysLog('The regular expression of $TYPO3_CONF_VARS[SYS][cookieDomain] contains errors. The session is not shared across sub-domains.', 'Core', 3); } elseif ($matchCnt) { $result = $match[0]; } } else { $result = $cookieDomain; } } return $result; }
/** * Start function * This class is able to generate a mail in formmail-style from the data in $V * Fields: * * [recipient]: email-adress of the one to receive the mail. If array, then all values are expected to be recipients * [attachment]: .... * * [subject]: The subject of the mail * [from_email]: Sender email. If not set, [email] is used * [from_name]: Sender name. If not set, [name] is used * [replyto_email]: Reply-to email. If not set [from_email] is used * [replyto_name]: Reply-to name. If not set [from_name] is used * [organisation]: Organization (header) * [priority]: Priority, 1-5, default 3 * [html_enabled]: If mail is sent as html * [use_base64]: If set, base64 encoding will be used instead of quoted-printable * * @param array Contains values for the field names listed above (with slashes removed if from POST input) * @param boolean Whether to base64 encode the mail content * @return void */ function start($valueList, $base64 = false) { $this->mailMessage = t3lib_div::makeInstance('t3lib_mail_Message'); if ($GLOBALS['TSFE']->config['config']['formMailCharset']) { // Respect formMailCharset if it was set $this->characterSet = $GLOBALS['TSFE']->csConvObj->parse_charset($GLOBALS['TSFE']->config['config']['formMailCharset']); } elseif ($GLOBALS['TSFE']->metaCharset != $GLOBALS['TSFE']->renderCharset) { // Use metaCharset for mail if different from renderCharset $this->characterSet = $GLOBALS['TSFE']->metaCharset; } if ($base64 || $valueList['use_base64']) { $this->encoding = 'base64'; } if (isset($valueList['recipient'])) { // convert form data from renderCharset to mail charset $this->subject = $valueList['subject'] ? $valueList['subject'] : 'Formmail on ' . t3lib_div::getIndpEnv('HTTP_HOST'); $this->subject = $this->sanitizeHeaderString($this->subject); $this->fromName = $valueList['from_name'] ? $valueList['from_name'] : ($valueList['name'] ? $valueList['name'] : ''); $this->fromName = $this->sanitizeHeaderString($this->fromName); $this->replyToName = $valueList['replyto_name'] ? $valueList['replyto_name'] : $this->fromName; $this->replyToName = $this->sanitizeHeaderString($this->replyToName); $this->organisation = $valueList['organisation'] ? $valueList['organisation'] : ''; $this->organisation = $this->sanitizeHeaderString($this->organisation); $this->fromAddress = $valueList['from_email'] ? $valueList['from_email'] : ($valueList['email'] ? $valueList['email'] : ''); if (!t3lib_div::validEmail($this->fromAddress)) { $this->fromAddress = t3lib_utility_Mail::getSystemFromAddress(); $this->fromName = t3lib_utility_Mail::getSystemFromName(); } $this->replyToAddress = $valueList['replyto_email'] ? $valueList['replyto_email'] : $this->fromAddress; $this->priority = $valueList['priority'] ? t3lib_div::intInRange($valueList['priority'], 1, 5) : 3; // auto responder $this->autoRespondMessage = trim($valueList['auto_respond_msg']) && $this->fromAddress ? trim($valueList['auto_respond_msg']) : ''; if ($this->autoRespondMessage !== '') { // Check if the value of the auto responder message has been modified with evil intentions $autoRespondChecksum = $valueList['auto_respond_checksum']; $correctHmacChecksum = t3lib_div::hmac($this->autoRespondMessage); if ($autoRespondChecksum !== $correctHmacChecksum) { t3lib_div::sysLog('Possible misuse of t3lib_formmail auto respond method. Subject: ' . $valueList['subject'], 'Core', 3); return; } else { $this->autoRespondMessage = $this->sanitizeHeaderString($this->autoRespondMessage); } } $plainTextContent = ''; $htmlContent = '<table border="0" cellpadding="2" cellspacing="2">'; // Runs through $V and generates the mail if (is_array($valueList)) { foreach ($valueList as $key => $val) { if (!t3lib_div::inList($this->reserved_names, $key)) { $space = strlen($val) > 60 ? LF : ''; $val = is_array($val) ? implode($val, LF) : $val; // convert form data from renderCharset to mail charset (HTML may use entities) $plainTextValue = $val; $HtmlValue = htmlspecialchars($val); $plainTextContent .= strtoupper($key) . ': ' . $space . $plainTextValue . LF . $space; $htmlContent .= '<tr><td bgcolor="#eeeeee"><font face="Verdana" size="1"><strong>' . strtoupper($key) . '</strong></font></td><td bgcolor="#eeeeee"><font face="Verdana" size="1">' . nl2br($HtmlValue) . ' </font></td></tr>'; } } } $htmlContent .= '</table>'; $this->plainContent = $plainTextContent; if ($valueList['html_enabled']) { $this->mailMessage->setBody($htmlContent, 'text/html'); $this->mailMessage->addPart($plainTextContent, 'text/plain'); } else { $this->mailMessage->setBody($plainTextContent, 'text/plain'); } for ($a = 0; $a < 10; $a++) { $variableName = 'attachment' . ($a ? $a : ''); if (!isset($_FILES[$variableName])) { continue; } if (!is_uploaded_file($_FILES[$variableName]['tmp_name'])) { t3lib_div::sysLog('Possible abuse of t3lib_formmail: temporary file "' . $_FILES[$variableName]['tmp_name'] . '" ("' . $_FILES[$variableName]['name'] . '") was not an uploaded file.', 'Core', 3); } if ($_FILES[$variableName]['tmp_name']['error'] !== UPLOAD_ERR_OK) { t3lib_div::sysLog('Error in uploaded file in t3lib_formmail: temporary file "' . $_FILES[$variableName]['tmp_name'] . '" ("' . $_FILES[$variableName]['name'] . '") Error code: ' . $_FILES[$variableName]['tmp_name']['error'], 'Core', 3); } $theFile = t3lib_div::upload_to_tempfile($_FILES[$variableName]['tmp_name']); $theName = $_FILES[$variableName]['name']; if ($theFile && file_exists($theFile)) { if (filesize($theFile) < $GLOBALS['TYPO3_CONF_VARS']['FE']['formmailMaxAttachmentSize']) { $this->mailMessage->attach(Swift_Attachment::fromPath($theFile)->setFilename($theName)); } } $this->temporaryFiles[] = $theFile; } $from = $this->fromName ? array($this->fromAddress => $this->fromName) : array($this->fromAddress); $this->recipient = $this->parseAddresses($valueList['recipient']); $this->mailMessage->setSubject($this->subject)->setFrom($from)->setTo($this->recipient)->setPriority($this->priority); $replyTo = $this->replyToName ? array($this->replyToAddress => $this->replyToName) : array($this->replyToAddress); $this->mailMessage->addReplyTo($replyTo); $this->mailMessage->getHeaders()->addTextHeader('Organization', $this->organisation); if ($valueList['recipient_copy']) { $this->mailMessage->addCc($this->parseAddresses($valueList['recipient_copy'])); } if ($this->characterSet) { $this->mailMessage->setCharset($this->characterSet); } // Ignore target encoding. This is handled automatically by Swift Mailer and overriding the defaults // is not worth the trouble // log dirty header lines if ($this->dirtyHeaders) { t3lib_div::sysLog('Possible misuse of t3lib_formmail: see TYPO3 devLog', 'Core', 3); if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']) { t3lib_div::devLog('t3lib_formmail: ' . t3lib_div::arrayToLogString($this->dirtyHeaders, '', 200), 'Core', 3); } } } }
/** * Proxy for the PHP mail() function. Adds possibility to hook in and send the mails in a different way. * The hook can be used by adding function to the configuration array: * $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'] * * @param string Email address to send to. * @param string Subject line, non-encoded. (see PHP function mail()) * @param string Message content, non-encoded. (see PHP function mail()) * @param string Additional headers for the mail (see PHP function mail()) * @param string Additional flags for the sending mail tool (see PHP function mail()) * @return boolean Indicates whether the mail has been sent or not * @see PHP function mail() [] * @link http://www.php.net/manual/en/function.mail.php */ public static function mail($to, $subject, $messageBody, $additionalHeaders = NULL, $additionalParameters = NULL) { $success = TRUE; // If the mail does not have a From: header, fall back to the default in TYPO3_CONF_VARS. if (!preg_match('/^From:/im', $additionalHeaders) && $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress']) { if (!is_null($additionalHeaders) && substr($additionalHeaders, -1) != LF) { $additionalHeaders .= LF; } if ($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']) { $additionalHeaders .= 'From: "' . $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'] . '" <' . $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'] . '>'; } else { $additionalHeaders .= 'From: ' . $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress']; } } if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'])) { $parameters = array('to' => $to, 'subject' => $subject, 'messageBody' => $messageBody, 'additionalHeaders' => $additionalHeaders, 'additionalParameters' => $additionalParameters); $fakeThis = FALSE; foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'] as $hookSubscriber) { $hookSubscriberContainsArrow = strpos($hookSubscriber, '->'); if ($hookSubscriberContainsArrow !== FALSE) { // deprecated, remove in TYPO3 4.7 t3lib_div::deprecationLog('The usage of user function notation for the substituteMailDelivery hook is deprecated, use the t3lib_mail_MailerAdapter interface instead.'); $success = $success && t3lib_div::callUserFunction($hookSubscriber, $parameters, $fakeThis); } else { $mailerAdapter = t3lib_div::makeInstance($hookSubscriber); if ($mailerAdapter instanceof t3lib_mail_MailerAdapter) { $success = $success && $mailerAdapter->mail($to, $subject, $messageBody, $additionalHeaders, $additionalParameters, $fakeThis); } else { throw new RuntimeException($hookSubscriber . ' is not an implementation of t3lib_mail_MailerAdapter, but must implement that interface to be used in the substituteMailDelivery hook.', 1294062286); } } } } else { if (t3lib_utility_PhpOptions::isSafeModeEnabled() && !is_null($additionalParameters)) { $additionalParameters = null; } if (is_null($additionalParameters)) { $success = @mail($to, $subject, $messageBody, $additionalHeaders); } else { $success = @mail($to, $subject, $messageBody, $additionalHeaders, $additionalParameters); } } if (!$success) { t3lib_div::sysLog('Mail to "' . $to . '" could not be sent (Subject: "' . $subject . '").', 'Core', 3); } return $success; }
/** * Perform user login and redirect to configured url, if any * * @param array $row: incoming setfixed parameters * @param boolen $redirect: whether to redirect after login or not * @return boolean TRUE, if login was successful, FALSE otherwise */ public function login($conf, $langObj, $controlData, array $row, $redirect = TRUE) { $result = TRUE; // Log the user in $loginData = array('uname' => $row['username'], 'uident' => $row['password'], 'uident_text' => $row['password'], 'status' => 'login'); // Check against configured pid (defaulting to current page) $GLOBALS['TSFE']->fe_user->checkPid = TRUE; $GLOBALS['TSFE']->fe_user->checkPid_value = $controlData->getPid(); // Get authentication info array $authInfo = $GLOBALS['TSFE']->fe_user->getAuthInfoArray(); // Get user info $user = $GLOBALS['TSFE']->fe_user->fetchUserRecord($authInfo['db_user'], $loginData['uname']); if (is_array($user)) { // Get the appropriate authentication service $authServiceObj = t3lib_div::makeInstanceService('auth', 'authUserFE'); // Check authentication if (is_object($authServiceObj)) { $ok = $authServiceObj->compareUident($user, $loginData); if ($ok) { // Login successfull: create user session $GLOBALS['TSFE']->fe_user->createUserSession($user); $GLOBALS['TSFE']->initUserGroups(); $GLOBALS['TSFE']->fe_user->user = $GLOBALS['TSFE']->fe_user->fetchUserSession(); $GLOBALS['TSFE']->loginUser = 1; // Delete regHash if ($controlData->getValidRegHash()) { $regHash = $controlData->getRegHash(); $controlData->deleteShortUrl($regHash); } if ($redirect) { // Redirect to configured page, if any $redirectUrl = $controlData->readRedirectUrl(); if (!$redirectUrl) { $redirectUrl = trim($conf['autoLoginRedirect_url']); } if (!$redirectUrl) { if ($conf['loginPID']) { $redirectUrl = $this->urlObj->get('', $conf['loginPID']); } else { $redirectUrl = $controlData->getSiteUrl(); } } header('Location: ' . t3lib_div::locationHeaderUrl($redirectUrl)); } } else { // Login failed... $controlData->clearSessionData(FALSE); $result = FALSE; } } else { // Required authentication service not available $message = $langObj->getLL('internal_required_authentication_service_not_available'); t3lib_div::sysLog($message, $controlData->getExtKey(), t3lib_div::SYSLOG_SEVERITY_ERROR); $controlData->clearSessionData(FALSE); $result = FALSE; } } else { // No enabled user of the given name $controlData->clearSessionData(FALSE); $result = FALSE; } return $result; }
/** * Writes log message. Destination log depends on the current system mode. * For FE the function writes to the admin panel log. For BE messages are * sent to the system log. If developer log is enabled, messages are also * sent there. * * This function accepts variable number of arguments and can format * parameters. The syntax is the same as for sprintf() * * @param string $message Message to output * @return void * @see sprintf() * @see t3lib::divLog() * @see t3lib_div::sysLog() * @see t3lib_timeTrack::setTSlogMessage() */ protected function writeLog($message) { if (func_num_args() > 1) { $params = func_get_args(); array_shift($params); $message = vsprintf($message, $params); } if (TYPO3_MODE == 'BE') { t3lib_div::sysLog($message, $this->extKey, 1); } else { $GLOBALS['TT']->setTSlogMessage($message); } if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']) { t3lib_div::devLog($message, $this->extKey, 1); } }
/** * @param string $msg Message (in English). * @param string $extKey Extension key (from which extension you are calling the log) or "Core * @param int $severity \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_* constant * @return void */ public function sysLog($msg, $extKey, $severity = 0) { /** @noinspection PhpDeprecationInspection PhpUndefinedClassInspection */ t3lib_div::sysLog($msg, $extKey, $severity); }
/** * Checks the input string (un-parsed TypoScript) for include-commands ("<INCLUDE_TYPOSCRIPT: ....") * Use: t3lib_TSparser::checkIncludeLines() * * @param string Unparsed TypoScript * @param integer Counter for detecting endless loops * @param boolean When set an array containing the resulting typoscript and all included files will get returned * @return string Complete TypoScript with includes added. * @static */ function checkIncludeLines($string, $cycle_counter = 1, $returnFiles = false) { $includedFiles = array(); if ($cycle_counter > 100) { t3lib_div::sysLog('It appears like TypoScript code is looping over itself. Check your templates for "<INCLUDE_TYPOSCRIPT: ..." tags', 'Core', 2); if ($returnFiles) { return array('typoscript' => '', 'files' => $includedFiles); } return ''; } $splitStr = '<INCLUDE_TYPOSCRIPT:'; if (strstr($string, $splitStr)) { $newString = ''; $allParts = explode($splitStr, LF . $string . LF); // adds line break char before/after foreach ($allParts as $c => $v) { if (!$c) { // first goes through $newString .= $v; } elseif (preg_match('/\\r?\\n\\s*$/', $allParts[$c - 1])) { // There must be a line-break char before. $subparts = explode('>', $v, 2); if (preg_match('/^\\s*\\r?\\n/', $subparts[1])) { // There must be a line-break char after // SO, the include was positively recognized: $newString .= '### ' . $splitStr . $subparts[0] . '> BEGIN:' . LF; $params = t3lib_div::get_tag_attributes($subparts[0]); if ($params['source']) { $sourceParts = explode(':', $params['source'], 2); switch (strtolower(trim($sourceParts[0]))) { case 'file': $filename = t3lib_div::getFileAbsFileName(trim($sourceParts[1])); if (strcmp($filename, '')) { // Must exist and must not contain '..' and must be relative if (@is_file($filename) && filesize($filename) < 100000) { // Max. 100 KB include files! // check for includes in included text $includedFiles[] = $filename; $included_text = self::checkIncludeLines(t3lib_div::getUrl($filename), $cycle_counter + 1, $returnFiles); // If the method also has to return all included files, merge currently included // files with files included by recursively calling itself if ($returnFiles && is_array($included_text)) { $includedFiles = array_merge($includedFiles, $included_text['files']); $included_text = $included_text['typoscript']; } $newString .= $included_text . LF; } } break; } } $newString .= '### ' . $splitStr . $subparts[0] . '> END:' . LF; $newString .= $subparts[1]; } else { $newString .= $splitStr . $v; } } else { $newString .= $splitStr . $v; } } $string = substr($newString, 1, -1); // not the first/last linebreak char. } // When all included files should get returned, simply return an compound array containing // the TypoScript with all "includes" processed and the files which got included if ($returnFiles) { return array('typoscript' => $string, 'files' => $includedFiles); } return $string; }
/** * Transforms a XML back to RTE / reverse function of RTE2XML * * * @param string XMLString which should be transformed * @return string string with HTML */ function XML2RTE($xmlstring) { //fixed setting of Parser (TO-DO set it via typoscript) //Added because import failed $xmlstring = str_replace('<br/>', '<br>', $xmlstring); $xmlstring = str_replace('<br />', '<br>', $xmlstring); $xmlstring = str_replace('<hr/>', '<hr>', $xmlstring); $xmlstring = str_replace('<hr />', '<hr>', $xmlstring); $xmlstring = str_replace('<p/>', '<p></p>', $xmlstring); // DZ: Added 2011-05-11 to avoid import problem with <p/> elements $this->parseHTML->procOptions['typolist'] = FALSE; $this->parseHTML->procOptions['typohead'] = FALSE; $this->parseHTML->procOptions['keepPDIVattribs'] = TRUE; $this->parseHTML->procOptions['dontConvBRtoParagraph'] = TRUE; if (!is_array($this->parseHTML->procOptions['HTMLparser_db.'])) { $this->parseHTML->procOptions['HTMLparser_db.'] = array(); } $this->parseHTML->procOptions['HTMLparser_db.']['xhtml_cleaning'] = TRUE; //trick to preserve strong tags $this->parseHTML->procOptions['denyTags'] = 'strong'; $this->parseHTML->procOptions['preserveTables'] = TRUE; //$parseHTML->procOptions['disableUnifyLineBreaks']=TRUE; $this->parseHTML->procOptions['dontRemoveUnknownTags_db'] = TRUE; //Writes debug information for CLI import to syslog if $TYPO3_CONF_VARS['SYS']['enable_DLOG'] is set. if (TYPO3_DLOG) { t3lib_div::sysLog(__FILE__ . ': Before RTE transformation:' . LF . $xmlstring . LF, 'l10nmgr'); } $content = $this->parseHTML->TS_transform_db($xmlstring, $css = 0); // removes links from content if not called first! $content = $this->parseHTML->TS_images_db($content); $content = $this->parseHTML->TS_links_db($content); // Last call special transformations (registered using hooks) if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['l10nmgr']['transformation'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['l10nmgr']['transformation'] as $classReference) { $processingObject = t3lib_div::getUserObj($classReference); $content = $processingObject->transform_db($content, $this->parseHTML); } } //substitute URL in <link> for CLI import $content = preg_replace('/<link http(s)?:\\/\\/[\\w\\.\\/]*\\?id=/', '<link ', $content); //Writes debug information for CLI import to syslog if $TYPO3_CONF_VARS['SYS']['enable_DLOG'] is set. if (TYPO3_DLOG) { t3lib_div::sysLog(__FILE__ . ': After RTE transformation:' . LF . $content . LF, 'l10nmgr'); } return $content; }
/** * Parsing the $this->raw TypoScript lines from pointer, $this->rawP * * @param array Reference to the setup array in which to accumulate the values. * @return string Returns the string of the condition found, the exit signal or possible nothing (if it completed parsing with no interruptions) */ function parseSub(&$setup) { global $TYPO3_CONF_VARS; while (isset($this->raw[$this->rawP])) { $line = ltrim($this->raw[$this->rawP]); $lineP = $this->rawP; $this->rawP++; if ($this->syntaxHighLight) { $this->regHighLight("prespace", $lineP, strlen($line)); } // Breakpoint? if ($this->breakPointLN && $this->lineNumberOffset + $this->rawP - 1 == $this->breakPointLN + 1) { // by adding 1 we get that line processed return '[_BREAK]'; } // Set comment flag? if (!$this->multiLineEnabled && substr($line, 0, 2) == '/*') { $this->commentSet = 1; } if (!$this->commentSet && ($line || $this->multiLineEnabled)) { // If $this->multiLineEnabled we will go and get the line values here because we know, the first if() will be true. if ($this->multiLineEnabled) { // If multiline is enabled. Escape by ')' if ($this->multiLineHeredoc === FALSE && substr($line, 0, 1) == ')' || $this->multiLineHeredoc !== FALSE && substr($line, 0, strlen($this->multiLineHeredoc . ";")) === $this->multiLineHeredoc . ";") { // Multiline ends... if ($this->syntaxHighLight) { $this->regHighLight("operator", $lineP, strlen($line) - 1); } $this->multiLineEnabled = 0; // Disable multiline $this->multiLineHeredoc = FALSE; $theValue = implode($this->multiLineValue, chr(10)); if (strstr($this->multiLineObject, '.')) { $this->setVal($this->multiLineObject, $setup, array($theValue)); // Set the value deeper. } else { $setup[$this->multiLineObject] = $theValue; // Set value regularly if ($this->lastComment && $this->regComments) { $setup[$this->multiLineObject . '..'] .= $this->lastComment; } if ($this->regLinenumbers) { $setup[$this->multiLineObject . '.ln..'][] = $this->lineNumberOffset + $this->rawP - 1; } } } else { if ($this->syntaxHighLight) { $this->regHighLight("value", $lineP); } $this->multiLineValue[] = $this->raw[$this->rawP - 1]; } } elseif ($this->inBrace == 0 && substr($line, 0, 1) == '[') { // Beginning of condition (only on level zero compared to brace-levels if ($this->syntaxHighLight) { $this->regHighLight("condition", $lineP); } return $line; } else { if (substr($line, 0, 1) == '[' && strtoupper(trim($line)) == '[GLOBAL]') { // Return if GLOBAL condition is set - no matter what. if ($this->syntaxHighLight) { $this->regHighLight("condition", $lineP); } $this->error('Line ' . ($this->lineNumberOffset + $this->rawP - 1) . ': On return to [GLOBAL] scope, the script was short of ' . $this->inBrace . ' end brace(s)', 1); $this->inBrace = 0; return $line; } elseif (strcspn($line, '}#/') != 0) { // If not brace-end or comment $varL = strcspn($line, ' {=<>:('); // Find object name string until we meet an operator $objStrName = trim(substr($line, 0, $varL)); if ($this->syntaxHighLight) { $this->regHighLight("objstr", $lineP, strlen(substr($line, $varL))); } if (strlen($objStrName)) { $r = array(); if ($this->strict && preg_match('/[^[:alnum:]_\\.-]/i', $objStrName, $r)) { $this->error('Line ' . ($this->lineNumberOffset + $this->rawP - 1) . ': Object Name String, "' . htmlspecialchars($objStrName) . '" contains invalid character "' . $r[0] . '". Must be alphanumeric or one of: "_-."'); } else { $line = ltrim(substr($line, $varL)); if ($this->syntaxHighLight) { $this->regHighLight("objstr_postspace", $lineP, strlen($line)); if (strlen($line) > 0) { $this->regHighLight("operator", $lineP, strlen($line) - 1); $this->regHighLight("operator_postspace", $lineP, strlen(ltrim(substr($line, 1)))); } } // Checking for special TSparser properties (to change TS values at parsetime) $match = array(); if (preg_match('/^:=([^\\(]+)\\((.+)\\).*/', $line, $match)) { $tsFunc = trim($match[1]); $tsFuncArg = $match[2]; list($currentValue) = $this->getVal($objStrName, $setup); switch ($tsFunc) { case 'prependString': $newValue = $tsFuncArg . $currentValue; break; case 'appendString': $newValue = $currentValue . $tsFuncArg; break; case 'removeString': $newValue = str_replace($tsFuncArg, '', $currentValue); break; case 'replaceString': list($fromStr, $toStr) = explode('|', $tsFuncArg, 2); $newValue = str_replace($fromStr, $toStr, $currentValue); break; case 'addToList': $newValue = (strcmp('', $currentValue) ? $currentValue . ',' : '') . trim($tsFuncArg); break; case 'removeFromList': $existingElements = t3lib_div::trimExplode(',', $currentValue); $removeElements = t3lib_div::trimExplode(',', $tsFuncArg); if (count($removeElements)) { $newValue = implode(',', array_diff($existingElements, $removeElements)); } break; default: if (isset($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tsparser.php']['preParseFunc'][$tsFunc])) { $hookMethod = $TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tsparser.php']['preParseFunc'][$tsFunc]; $params = array('currentValue' => $currentValue, 'functionArgument' => $tsFuncArg); $fakeThis = FALSE; $newValue = t3lib_div::callUserFunction($hookMethod, $params, $fakeThis); } else { t3lib_div::sysLog('Missing function definition for ' . $tsFunc . ' on TypoScript line ' . $lineP, 'Core', 2); } } if (isset($newValue)) { $line = '= ' . $newValue; } } switch (substr($line, 0, 1)) { case '=': if ($this->syntaxHighLight) { $this->regHighLight('value', $lineP, strlen(ltrim(substr($line, 1))) - strlen(trim(substr($line, 1)))); } if (strstr($objStrName, '.')) { $value = array(); $value[0] = trim(substr($line, 1)); $this->setVal($objStrName, $setup, $value); } else { $setup[$objStrName] = trim(substr($line, 1)); if ($this->lastComment && $this->regComments) { // Setting comment.. $setup[$objStrName . '..'] .= $this->lastComment; } if ($this->regLinenumbers) { $setup[$objStrName . '.ln..'][] = $this->lineNumberOffset + $this->rawP - 1; } } break; case '{': $this->inBrace++; if (strstr($objStrName, '.')) { $exitSig = $this->rollParseSub($objStrName, $setup); if ($exitSig) { return $exitSig; } } else { if (!isset($setup[$objStrName . '.'])) { $setup[$objStrName . '.'] = array(); } $exitSig = $this->parseSub($setup[$objStrName . '.']); if ($exitSig) { return $exitSig; } } break; case '(': $this->multiLineObject = $objStrName; $this->multiLineEnabled = 1; $this->multiLineValue = array(); break; case '<': if (substr($line, 0, 3) === "<<<") { $this->multiLineObject = $objStrName; $this->multiLineEnabled = 1; $this->multiLineValue = array(); $this->multiLineHeredoc = trim(substr($line, 3)); } else { if ($this->syntaxHighLight) { $this->regHighLight("value_copy", $lineP, strlen(ltrim(substr($line, 1))) - strlen(trim(substr($line, 1)))); } $theVal = trim(substr($line, 1)); if (substr($theVal, 0, 1) == '.') { $res = $this->getVal(substr($theVal, 1), $setup); } else { $res = $this->getVal($theVal, $this->setup); } $this->setVal($objStrName, $setup, unserialize(serialize($res)), 1); // unserialize(serialize(...)) may look stupid but is needed because of some reference issues. See Kaspers reply to "[TYPO3-core] good question" from December 15 2005. } break; case '>': if ($this->syntaxHighLight) { $this->regHighLight("value_unset", $lineP, strlen(ltrim(substr($line, 1))) - strlen(trim(substr($line, 1)))); } $this->setVal($objStrName, $setup, 'UNSET'); break; default: $this->error('Line ' . ($this->lineNumberOffset + $this->rawP - 1) . ': Object Name String, "' . htmlspecialchars($objStrName) . '" was not preceeded by any operator, =<>({'); break; } } $this->lastComment = ''; } } elseif (substr($line, 0, 1) == '}') { $this->inBrace--; $this->lastComment = ''; if ($this->syntaxHighLight) { $this->regHighLight("operator", $lineP, strlen($line) - 1); } if ($this->inBrace < 0) { $this->error('Line ' . ($this->lineNumberOffset + $this->rawP - 1) . ': An end brace is in excess.', 1); $this->inBrace = 0; } else { break; } } else { if ($this->syntaxHighLight) { $this->regHighLight("comment", $lineP); } // Comment. The comments are concatenated in this temporary string: if ($this->regComments) { $this->lastComment .= trim($line) . chr(10); } } } } // Unset comment if ($this->commentSet) { if ($this->syntaxHighLight) { $this->regHighLight("comment", $lineP); } if (substr($line, 0, 2) == '*/') { $this->commentSet = 0; } } } }
/** * Search for commented INCLUDE_TYPOSCRIPT statements * and save the content between the BEGIN and the END line to the specified file * * @param string template content * @param int Counter for detecting endless loops * @return string template content with uncommented include statements * @author Fabrizio Branca <*****@*****.**> */ function extractIncludes($string, $cycle_counter = 1, $extractedFileNames = array()) { if ($cycle_counter > 10) { t3lib_div::sysLog('It appears like TypoScript code is looping over itself. Check your templates for "<INCLUDE_TYPOSCRIPT: ..." tags', 'Core', 2); return "\n###\n### ERROR: Recursion!\n###\n"; } $fileContent = array(); $restContent = array(); $fileName = NULL; $inIncludePart = FALSE; $lines = explode("\n", $string); $skipNextLineIfEmpty = FALSE; $openingCommentedIncludeStatement = NULL; foreach ($lines as $line) { // t3lib_TSparser::checkIncludeLines inserts an additional empty line, remove this again if ($skipNextLineIfEmpty) { if (trim($line) == '') { continue; } $skipNextLineIfEmpty = FALSE; } if (!$inIncludePart) { // outside commented include statements // search for beginning commented include statements $matches = array(); if (preg_match('/###\\s*<INCLUDE_TYPOSCRIPT:\\s*source\\s*=\\s*"\\s*FILE\\s*:\\s*(.*)\\s*">\\s*BEGIN/i', $line, $matches)) { // save this line in case there is no ending tag $openingCommentedIncludeStatement = trim($line); $openingCommentedIncludeStatement = trim(preg_replace('/### Warning: .*###/', '', $openingCommentedIncludeStatement)); // found a commented include statement $fileName = trim($matches[1]); $inIncludePart = TRUE; $expectedEndTag = '### <INCLUDE_TYPOSCRIPT: source="FILE:' . $fileName . '"> END'; // strip all whitespace characters to make comparision safer $expectedEndTag = strtolower(preg_replace('/\\s/', '', $expectedEndTag)); } else { // if this is not a beginning commented include statement this line goes into the rest content $restContent[] = $line; } } else { // inside commented include statements // search for the matching ending commented include statement $strippedLine = strtolower(preg_replace('/\\s/', '', $line)); if (strpos($strippedLine, $expectedEndTag) !== FALSE) { // found the matching ending include statement $fileContentString = implode("\n", $fileContent); // write the content to the file $realFileName = t3lib_div::getFileAbsFileName($fileName); // some file checks if (empty($realFileName)) { throw new Exception(sprintf('"%s" is not a valid file location.', $fileName)); } if (!is_writable($realFileName)) { throw new Exception(sprintf('"%s" is not writable.', $fileName)); } if (in_array($realFileName, $extractedFileNames)) { throw new Exception(sprintf('Recursive/multiple inclusion of file "%s"', $realFileName)); } $extractedFileNames[] = $realFileName; // recursive call to detected nested commented include statements $fileContentString = self::extractIncludes($fileContentString, ++$cycle_counter, $extractedFileNames); if (!t3lib_div::writeFile($realFileName, $fileContentString)) { throw new Exception(sprintf('Could not write file "%s"', $realFileName)); } // insert reference to the file in the rest content $restContent[] = "<INCLUDE_TYPOSCRIPT: source=\"FILE:{$fileName}\">"; // reset variables (preparing for the next commented include statement) $fileContent = array(); $fileName = NULL; $inIncludePart = FALSE; $openingCommentedIncludeStatement = NULL; // t3lib_TSparser::checkIncludeLines inserts an additional empty line, remove this again $skipNextLineIfEmpty = TRUE; } else { // if this is not a ending commented include statement this line goes into the file content $fileContent[] = $line; } } } // if we're still inside commented include statements copy the lines back to the rest content if ($inIncludePart) { $restContent[] = $openingCommentedIncludeStatement . ' ### Warning: Corresponding end line missing! ###'; $restContent = array_merge($restContent, $fileContent); } $restContentString = implode("\n", $restContent); return $restContentString; }