/** * Default action. * * @return array * @throws \RuntimeException */ public function main() { $this->init(); $allowedIps = GeneralUtility::trimExplode(',', $this->config['allowedIps'], true); if ($this->config['debug']) { GeneralUtility::sysLog('Connection from ' . GeneralUtility::getIndpEnv('REMOTE_ADDR'), self::$extKey); } if ($this->config['mode'] !== 'M' || count($allowedIps) && !in_array(GeneralUtility::getIndpEnv('REMOTE_ADDR'), $allowedIps)) { $this->denyAccess(); } // Initialize TCA (method handles if not already initialized) if (version_compare(TYPO3_version, '7.6', '>=')) { \TYPO3\CMS\Frontend\Utility\EidUtility::initTCA(); } $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); } }
/** * 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(); /** @var \TYPO3\CMS\Core\Registry $registry */ $registry = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Registry'); $syncLock = $registry->get(static::$package, 'synchronisationLock'); $content = GeneralUtility::getUrl($this->config['masterUrl']); if ($content && ($syncLock === 0 || $syncLock < time())) { $lockUntil = time() - $this->config['updateInterval'] + self::LOCK_INTERVAL; $registry->set(static::$package, 'synchronisationLock', $lockUntil); $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 { GeneralUtility::sysLog('No users to be synchronized', self::$extKey, 3); } } else { GeneralUtility::sysLog($response['errors'][0], self::$extKey, 3); } $registry->set(static::$package, 'synchronisationLock', 0); } return $success; }
/** * Writes exception to different logs * * @param Exception $exception The exception * @param string $context 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(); if ($context === 'WEB') { $logMessage .= '. Requested URL: ' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'); } $backtrace = $exception->getTrace(); // Write error message to the configured syslogs \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog($logMessage, $logTitle, \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_FATAL); // 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) { \TYPO3\CMS\Core\Utility\GeneralUtility::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) { } }
/** * Writes exception to different logs * * @param \Exception|\Throwable $exception The exception(PHP 5.x) or throwable(PHP >= 7.0) object. * @param string $context The context where the exception was thrown, WEB or CLI * @return void * @see \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(), \TYPO3\CMS\Core\Utility\GeneralUtility::devLog() * @TODO #72293 This will change to \Throwable only if we are >= PHP7.0 only */ protected function writeLogEntries($exception, $context) { // Do not write any logs for this message to avoid filling up tables or files with illegal requests if ($exception->getCode() === 1396795884) { return; } $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(); if ($context === 'WEB') { $logMessage .= '. Requested URL: ' . GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'); } $backtrace = $exception->getTrace(); // Write error message to the configured syslogs GeneralUtility::sysLog($logMessage, $logTitle, GeneralUtility::SYSLOG_SEVERITY_FATAL); // 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 { // Write error message to devlog // see: $TYPO3_CONF_VARS['SYS']['enable_exceptionDLOG'] if (TYPO3_EXCEPTION_DLOG) { GeneralUtility::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) { } }
/** * Lock the process * * @param \EssentialDots\ExtbaseHijax\Lock\Lock $lockObj * @param $key String to identify the lock in the system * @param bool $exclusive Exclusive lock (shared if FALSE) * @return bool Returns TRUE if the lock could be obtained, FALSE otherwise */ public function acquireLock(&$lockObj, $key, $exclusive = TRUE) { try { if (!is_object($lockObj)) { /* @var $lockObj \EssentialDots\ExtbaseHijax\Lock\Lock */ $lockObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('EssentialDots\\ExtbaseHijax\\Lock\\Lock', $key); } if (array_key_exists($key, $this->lockKeyType) && $this->lockKeyType[$key] !== $exclusive) { error_log('The same key cannot be used for shared and exclusive locks atm. Key: ' . $key); return FALSE; } $this->lockKeyType[$key] = $exclusive; $this->lockObjectsKeys[spl_object_hash($lockObj)] = $key; if (array_key_exists($key, $this->existingLocksCount) && $this->existingLocksCount[$key] > 0) { $this->existingLocksCount[$key]++; return true; } else { $this->existingLocksCount[$key] = 1; } $success = FALSE; if (strlen($key)) { $success = $lockObj->acquire($exclusive); if ($success) { $lockObj->sysLog('Acquired lock'); } } } catch (\Exception $e) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Locking: Failed to acquire lock: ' . $e->getMessage(), 'cms', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); $success = FALSE; // If locking fails, return with FALSE and continue without locking } return $success; }
/** * 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) { $lipsum = $this->lipsum; } if (strlen($lipsum) < 255 && !preg_match('/[^a-z0-9_\\.\\:\\/]/i', $lipsum) || 0 === strpos($lipsum, 'EXT:')) { // argument is most likely a file reference. $sourceFile = GeneralUtility::getFileAbsFileName($lipsum); if (file_exists($sourceFile)) { $lipsum = file_get_contents($sourceFile); } else { GeneralUtility::sysLog('Vhs LipsumViewHelper was asked to load Lorem Ipsum from a file which does not exist. ' . 'The file was: ' . $sourceFile, 'vhs', GeneralUtility::SYSLOG_SEVERITY_WARNING); $lipsum = $this->lipsum; } } $lipsum = preg_replace('/[\\r\\n]{1,}/i', "\n", $lipsum); $paragraphs = explode("\n", $lipsum); $paragraphs = array_slice($paragraphs, 0, intval($this->arguments['paragraphs'])); foreach ($paragraphs as $index => $paragraph) { $length = $this->arguments['wordsPerParagraph'] + rand(0 - intval($this->arguments['skew']), intval($this->arguments['skew'])); $words = explode(' ', $paragraph); $paragraphs[$index] = implode(' ', array_slice($words, 0, $length)); } $lipsum = implode("\n", $paragraphs); if ($this->arguments['html']) { $tsParserPath = $this->arguments['parseFuncTSPath'] ? '< ' . $this->arguments['parseFuncTSPath'] : null; $lipsum = $this->contentObject->parseFunc($lipsum, [], $tsParserPath); } return $lipsum; }
/** * Handles an error. * If the error is registered as exceptionalError it will by converted into an exception, to be handled * by the configured exceptionhandler. Additionally 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 int $errorLevel The error level - one of the E_* constants * @param string $errorMessage The error message * @param string $errorFile Name of the file the error occurred in * @param int $errorLine Line number where the error occurred * @return bool * @throws Exception with the data passed to this method if the error is registered as exceptionalError * @throws \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', E_DEPRECATED => 'Runtime Deprecation Notice'); $message = 'PHP ' . $errorLevels[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine; if ($errorLevel & $this->exceptionalErrors) { throw new 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; } $logTitle = 'Core: Error handler (' . TYPO3_MODE . ')'; $message = $logTitle . ': ' . $message; GeneralUtility::sysLog($message, 'core', $severity + 1); return true; } }
/** * the only action the extbase dispatcher knows of * * @return null */ public function dispatchAction() { if (!$this->controllerName) { \TYPO3\CMS\Core\Utility\GeneralUtility::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'])) { \TYPO3\CMS\Core\Utility\GeneralUtility::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 = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->settings[$this->controllerName]['allowedActions'], true); reset($actions); $this->forward(current($actions)); }
/** * Writes exception to different logs * * @param \Exception|\Throwable $exception The exception(PHP 5.x) or throwable(PHP >= 7.0) object. * @param string $context The context where the exception was thrown, WEB or CLI * @return void * @see \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(), \TYPO3\CMS\Core\Utility\GeneralUtility::devLog() */ protected function writeLogEntries($exception, $context) { // Do not write any logs for this message to avoid filling up tables or files with illegal requests if ($exception->getCode() === 1396795884) { return; } $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(); if ($context === self::CONTEXT_WEB) { $logMessage .= '. Requested URL: ' . GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'); } // Write error message to the configured syslogs GeneralUtility::sysLog($logMessage, $logTitle, GeneralUtility::SYSLOG_SEVERITY_FATAL); }
/** * Flushs the memory queue. * * @return void */ protected function flushMemoryQueue() { if ($this->memorySpool !== null) { $mailer = $this->getMailer(); $transport = $mailer->getTransport(); if ($transport instanceof \R3H6\MailSpool\Mail\SpoolTransport) { $failedRecipients = array(); try { $sent = $this->memorySpool->flushQueue($transport->getRealTransport(), $failedRecipients); if (!$sent) { throw new \RuntimeException('No e-mail has been sent', 1476304931); } } catch (\Exception $exception) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog($exception->getMessage(), 'mail_spool', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); } } } }
/** * 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 $to Email address to send to. * @param string $subject Subject line, non-encoded. (see PHP function mail()) * @param string $messageBody Message content, non-encoded. (see PHP function mail()) * @param string $additionalHeaders Additional headers for the mail (see PHP function mail()) * @param string $additionalParameters 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 * @deprecated since 6.1, will be removed two versions later - Use \TYPO3\CMS\Core\Mail\Mailer instead */ public static function mail($to, $subject, $messageBody, $additionalHeaders = NULL, $additionalParameters = NULL) { GeneralUtility::logDeprecatedFunction(); $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) { throw new \RuntimeException($hookSubscriber . ' is an invalid hook implementation. Please consider using an implementation of TYPO3\\CMS\\Core\\Mail\\MailerAdapter.', 1322287600); } else { $mailerAdapter = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($hookSubscriber); if ($mailerAdapter instanceof \TYPO3\CMS\Core\Mail\MailerAdapterInterface) { $success = $success && $mailerAdapter->mail($to, $subject, $messageBody, $additionalHeaders, $additionalParameters, $fakeThis); } else { throw new \RuntimeException($hookSubscriber . ' is not an implementation of TYPO3\\CMS\\Core\\Mail\\MailerAdapter, but must implement that interface to be used in the substituteMailDelivery hook.', 1294062286); } } } } else { if (is_null($additionalParameters)) { $success = @mail($to, $subject, $messageBody, $additionalHeaders); } else { $success = @mail($to, $subject, $messageBody, $additionalHeaders, $additionalParameters); } } if (!$success) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Mail to "' . $to . '" could not be sent (Subject: "' . $subject . '").', 'Core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); } return $success; }
/** * 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 */ public function validateReturnUrl($url) { $url = strval($url); if ($url === '') { return ''; } $decodedUrl = rawurldecode($url); $sanitizedUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::removeXSS($decodedUrl); if ($decodedUrl !== $sanitizedUrl || preg_match('#["<>\\\\]+#', $url)) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(sprintf(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('service-URLValidator-xssAttackDetected', 'cicregister'), $url), 'cicregister', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_WARNING); return ''; } // Validate the URL: if ($this->canRedirectToUrl($url)) { return $url; } // URL is not allowed \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(sprintf(\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('service-URLValidator-noValidRedirectUrl', 'cicregister'), $url), 'felogin', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_WARNING); return ''; }
/** * Lock the process * * @param $lockObj * @param $key String to identify the lock in the system * @param bool $exclusive Exclusive lock (shared if FALSE) * @return bool Returns TRUE if the lock could be obtained, FALSE otherwise */ protected function acquireLock(&$lockObj, $key, $exclusive = TRUE) { try { if (!is_object($lockObj)) { /* @var $lockObj \EssentialDots\ExtbaseHijax\Lock\Lock */ $lockObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('EssentialDots\\ExtbaseHijax\\Lock\\Lock', $key); } $success = FALSE; if (strlen($key)) { $success = $lockObj->acquire($exclusive); if ($success) { $lockObj->sysLog('Acquired lock'); } } } catch (\Exception $e) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Locking: Failed to acquire lock: ' . $e->getMessage(), 'cms', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); $success = FALSE; // If locking fails, return with FALSE and continue without locking } return $success; }
/** * Find a user (eg. look up the user record in database when a login is sent) * * @return mixed User array or FALSE * @todo Define visibility */ public function getUser() { $user = FALSE; if ($this->login['status'] == 'login') { if ($this->login['uident']) { $user = $this->fetchUserRecord($this->login['uname']); if (!is_array($user)) { // Failed login attempt (no username found) $this->writelog(255, 3, 3, 2, 'Login-attempt from %s (%s), username \'%s\' not found!!', array($this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $this->login['uname'])); // Logout written to log \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(sprintf('Login-attempt from %s (%s), username \'%s\' not found!', $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $this->login['uname']), 'Core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_WARNING); } else { if ($this->writeDevLog) { \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('User found: ' . \TYPO3\CMS\Core\Utility\GeneralUtility::arrayToLogString($user, array($this->db_user['userid_column'], $this->db_user['username_column'])), 'TYPO3\\CMS\\Sv\\AuthenticationService'); } } } else { // Failed Login attempt (no password given) $this->writelog(255, 3, 3, 2, 'Login-attempt from %s (%s) for username \'%s\' with an empty password!', array($this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $this->login['uname'])); \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog(sprintf('Login-attempt from %s (%s), for username \'%s\' with an empty password!', $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $this->login['uname']), 'Core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_WARNING); } } return $user; }
/** * Gets the domain to be used on setting cookies. * The information is taken from the value in $GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieDomain']. * * @return string The domain to be used on setting cookies * @see AbstractUserAuthentication::getCookieDomain */ protected static function getCookieDomain() { $result = ''; $cookieDomain = $GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieDomain']; // If a specific cookie domain is defined for a given TYPO3_MODE, // use that domain if (!empty($GLOBALS['TYPO3_CONF_VARS']['FE']['cookieDomain'])) { $cookieDomain = $GLOBALS['TYPO3_CONF_VARS']['FE']['cookieDomain']; } if ($cookieDomain) { if ($cookieDomain[0] == '/') { $match = []; $matchCnt = preg_match($cookieDomain, GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY'), $match); if ($matchCnt === false) { GeneralUtility::sysLog('The regular expression for the cookie domain (' . $cookieDomain . ') contains errors. The session is not shared across sub-domains.', 'Core', GeneralUtility::SYSLOG_SEVERITY_ERROR); } elseif ($matchCnt) { $result = $match[0]; } } else { $result = $cookieDomain; } } return $result; }
/** * Function execute from the Scheduler * * @return boolean TRUE on successful execution, FALSE on error */ public function execute() { list($extensionName, $controllerName, $commandName) = explode(':', $this->commandIdentifier); $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); $this->injectObjectManager($objectManager); $request = $this->objectManager->create('TYPO3\\CMS\\Extbase\\Mvc\\Cli\\Request'); $dispatcher = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\Dispatcher'); $response = $this->objectManager->create('TYPO3\\CMS\\Extbase\\Mvc\\Cli\\Response'); try { $upperCamelCaseExtensionName = \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($extensionName); $upperCamelCaseControllerName = \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($controllerName); // TODO build class name a different way now that we have namespaces // see https://www.pivotaltracker.com/story/show/73980994 $controllerObjectName = sprintf('Tx_%s_Command_%sCommandController', $upperCamelCaseExtensionName, $upperCamelCaseControllerName); $request->setControllerCommandName($commandName); $request->setControllerObjectName($controllerObjectName); $request->setArguments((array) $this->arguments); $dispatcher->dispatch($request, $response); return TRUE; } catch (\Exception $e) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog($e->getMessage(), $extensionName, $e->getCode()); return FALSE; } }
/** * 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 = GeneralUtility::removeXSS($decodedUrl); if ($decodedUrl !== $sanitizedUrl || preg_match('#["<>\\\\]+#', $url)) { GeneralUtility::sysLog(sprintf($this->pi_getLL('xssAttackDetected'), $url), 'felogin', GeneralUtility::SYSLOG_SEVERITY_WARNING); return ''; } // Validate the URL: if ($this->isRelativeUrl($url) || $this->isInCurrentDomain($url) || $this->isInLocalDomain($url)) { return $url; } // URL is not allowed GeneralUtility::sysLog(sprintf($this->pi_getLL('noValidRedirectUrl'), $url), 'felogin', GeneralUtility::SYSLOG_SEVERITY_WARNING); return ''; }
/** * 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 \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog() */ public function writeLogMessage($message) { if (func_num_args() > 1) { $params = func_get_args(); array_shift($params); $message = vsprintf($message, $params); } if (TYPO3_MODE === 'BE') { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog($message, $this->extKey, \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_NOTICE); } else { $GLOBALS['TT']->setTSlogMessage($message); } if (TYPO3_DLOG) { \TYPO3\CMS\Core\Utility\GeneralUtility::devLog($message, $this->extKey, \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_NOTICE); } }
/** * Performs sorting on the data array accordant to the * selected column in the grid view to be used for sorting. * * @return void */ protected function sortDataArray() { if (is_array($this->dataArray)) { switch ($this->sort) { case 'uid': case 'change': case 'workspace_Tstamp': case 't3ver_oid': case 'liveid': case 'livepid': case 'languageValue': uasort($this->dataArray, array($this, 'intSort')); break; case 'label_Workspace': case 'label_Live': case 'label_Stage': case 'workspace_Title': case 'path_Live': // case 'path_Workspace': This is the first sorting attribute uasort($this->dataArray, array($this, 'stringSort')); break; default: // Do nothing } } else { GeneralUtility::sysLog('Try to sort "' . $this->sort . '" in "TYPO3\\CMS\\Workspaces\\Service\\GridDataService::sortDataArray" but $this->dataArray is empty! This might be the Bug #26422 which could not reproduced yet.', 3); } // Suggested slot method: // methodName(\TYPO3\CMS\Workspaces\Service\GridDataService $gridData, array &$dataArray, $sortColumn, $sortDirection) $this->emitSignal(self::SIGNAL_SortDataArray_PostProcesss, $this->dataArray, $this->sort, $this->sortDir); }
/** * Checks if record set is valid and writes debugging information into devLog if not. * * @param bool|\mysqli_result|object MySQLi result object / DBAL object * @return bool TRUE if the record set is valid, FALSE otherwise */ public function debug_check_recordset($res) { if ($res !== false) { return true; } $trace = debug_backtrace(0); array_shift($trace); $msg = 'Invalid database result detected: function TYPO3\\CMS\\Core\\Database\\DatabaseConnection->' . $trace[0]['function'] . ' called from file ' . substr($trace[0]['file'], strlen(PATH_site) + 2) . ' in line ' . $trace[0]['line'] . '.'; GeneralUtility::sysLog($msg . ' Use a devLog extension to get more details.', 'core', GeneralUtility::SYSLOG_SEVERITY_ERROR); // Send to devLog if enabled if (TYPO3_DLOG) { $debugLogData = array('SQL Error' => $this->sql_error(), 'Backtrace' => $trace); if ($this->debug_lastBuiltQuery) { $debugLogData = array('SQL Query' => $this->debug_lastBuiltQuery) + $debugLogData; } GeneralUtility::devLog($msg, 'Core/t3lib_db', 3, $debugLogData); } return false; }
/** * Updating Index (External API) * * @param boolean $testOnly If set, only a test * @param boolean $cli_echo If set, output CLI status * @return array Header and body status content */ public function updateIndex($testOnly, $cli_echo = FALSE) { $errors = array(); $tableNames = array(); $recCount = 0; $tableCount = 0; $headerContent = $testOnly ? 'Reference Index being TESTED (nothing written, use "--refindex update" to update)' : 'Reference Index being Updated'; if ($cli_echo) { echo '*******************************************' . LF . $headerContent . LF . '*******************************************' . LF; } // Traverse all tables: foreach ($GLOBALS['TCA'] as $tableName => $cfg) { if (isset(static::$nonRelationTables[$tableName])) { continue; } // Traverse all records in tables, including deleted records: $fieldNames = BackendUtility::isTableWorkspaceEnabled($tableName) ? 'uid,t3ver_wsid' : 'uid'; $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fieldNames, $tableName, '1=1'); if ($GLOBALS['TYPO3_DB']->sql_error()) { // Table exists in $TCA but does not exist in the database GeneralUtility::sysLog(sprintf('Table "%s" exists in $TCA but does not exist in the database. You should run the Database Analyzer in the Install Tool to fix this.', $tableName), 'core', GeneralUtility::SYSLOG_SEVERITY_ERROR); continue; } $tableNames[] = $tableName; $tableCount++; $uidList = array(0); while ($recdat = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { /** @var $refIndexObj ReferenceIndex */ $refIndexObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\ReferenceIndex'); if (isset($recdat['t3ver_wsid'])) { $refIndexObj->setWorkspaceId($recdat['t3ver_wsid']); } $result = $refIndexObj->updateRefIndexTable($tableName, $recdat['uid'], $testOnly); $uidList[] = $recdat['uid']; $recCount++; if ($result['addedNodes'] || $result['deletedNodes']) { $Err = 'Record ' . $tableName . ':' . $recdat['uid'] . ' had ' . $result['addedNodes'] . ' added indexes and ' . $result['deletedNodes'] . ' deleted indexes'; $errors[] = $Err; if ($cli_echo) { echo $Err . LF; } } } $GLOBALS['TYPO3_DB']->sql_free_result($res); // Searching lost indexes for this table: $where = 'tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($tableName, 'sys_refindex') . ' AND recuid NOT IN (' . implode(',', $uidList) . ')'; $lostIndexes = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('hash', 'sys_refindex', $where); if (count($lostIndexes)) { $Err = 'Table ' . $tableName . ' has ' . count($lostIndexes) . ' lost indexes which are now deleted'; $errors[] = $Err; if ($cli_echo) { echo $Err . LF; } if (!$testOnly) { $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex', $where); } } } // Searching lost indexes for non-existing tables: $where = 'tablename NOT IN (' . implode(',', $GLOBALS['TYPO3_DB']->fullQuoteArray($tableNames, 'sys_refindex')) . ')'; $lostTables = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('hash', 'sys_refindex', $where); if (count($lostTables)) { $Err = 'Index table hosted ' . count($lostTables) . ' indexes for non-existing tables, now removed'; $errors[] = $Err; if ($cli_echo) { echo $Err . LF; } if (!$testOnly) { $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_refindex', $where); } } $testedHowMuch = $recCount . ' records from ' . $tableCount . ' tables were checked/updated.' . LF; $bodyContent = $testedHowMuch . (count($errors) ? implode(LF, $errors) : 'Index Integrity was perfect!'); if ($cli_echo) { echo $testedHowMuch . (count($errors) ? 'Updates: ' . count($errors) : 'Index Integrity was perfect!') . LF; } if (!$testOnly) { $registry = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Registry'); $registry->set('core', 'sys_refindex_lastUpdate', $GLOBALS['EXEC_TIME']); } return array($headerContent, $bodyContent, count($errors)); }
/** * Submit incoming content as translated language to database. Must match what is available in $accum. * * @param array $accum Translation configuration * @param array $inputArray Array with incoming translation. Must match what is found in $accum * @return mixed False if error - else flexFormDiffArray (if $inputArray was an array and processing was performed.) */ function _submitContentAsTranslatedLanguageAndGetFlexFormDiff($accum, $inputArray) { if (is_array($inputArray)) { // Initialize: /** @var $flexToolObj FlexFormTools */ $flexToolObj = GeneralUtility::makeInstance(FlexFormTools::class); $gridElementsInstalled = ExtensionManagementUtility::isLoaded('gridelements'); $TCEmain_data = array(); $TCEmain_cmd = array(); $_flexFormDiffArray = array(); // Traverse: foreach ($accum as $pId => $page) { foreach ($accum[$pId]['items'] as $table => $elements) { foreach ($elements as $elementUid => $data) { if (is_array($data['fields'])) { foreach ($data['fields'] as $key => $tData) { if (is_array($tData) && isset($inputArray[$table][$elementUid][$key])) { list($Ttable, $TuidString, $Tfield, $Tpath) = explode(':', $key); list($Tuid, $Tlang, $TdefRecord) = explode('/', $TuidString); if (!$this->createTranslationAlsoIfEmpty && $inputArray[$table][$elementUid][$key] == '' && $Tuid == 'NEW') { //if data is empty do not save it unset($inputArray[$table][$elementUid][$key]); continue; } // If new element is required, we prepare for localization if ($Tuid === 'NEW') { if ($table === 'tt_content' && $gridElementsInstalled === true) { $element = BackendUtility::getRecordRaw($table, 'uid = ' . $elementUid . ' AND deleted = 0'); if ($element['colPos'] > -1) { $TCEmain_cmd[$table][$elementUid]['localize'] = $Tlang; } else { if ($element['tx_gridelements_container'] > 0) { //TYPO3\CMS\Core\Utility\DebugUtility::debug($element,'$element'); $container = BackendUtility::getRecordRaw($table, 'l18n_parent = ' . $element['tx_gridelements_container'] . ' AND deleted = 0 AND sys_language_uid = ' . $Tlang); if ($container['uid'] > 0) { $TCEmain_cmd[$table][$container['uid']]['inlineLocalizeSynchronize'] = 'tx_gridelements_children,localize'; } } } } else { //print "\nNEW\n"; $TCEmain_cmd[$table][$elementUid]['localize'] = $Tlang; } } // If FlexForm, we set value in special way: if ($Tpath) { if (!is_array($TCEmain_data[$Ttable][$TuidString][$Tfield])) { $TCEmain_data[$Ttable][$TuidString][$Tfield] = array(); } //TCEMAINDATA is passed as reference here: $flexToolObj->setArrayValueByPath($Tpath, $TCEmain_data[$Ttable][$TuidString][$Tfield], $inputArray[$table][$elementUid][$key]); $_flexFormDiffArray[$key] = array('translated' => $inputArray[$table][$elementUid][$key], 'default' => $tData['defaultValue']); } else { $TCEmain_data[$Ttable][$TuidString][$Tfield] = $inputArray[$table][$elementUid][$key]; } unset($inputArray[$table][$elementUid][$key]); // Unsetting so in the end we can see if $inputArray was fully processed. } else { //debug($tData,'fields not set for: '.$elementUid.'-'.$key); //debug($inputArray[$table],'inputarray'); } } if (is_array($inputArray[$table][$elementUid]) && !count($inputArray[$table][$elementUid])) { unset($inputArray[$table][$elementUid]); // Unsetting so in the end we can see if $inputArray was fully processed. } } } if (is_array($inputArray[$table]) && !count($inputArray[$table])) { unset($inputArray[$table]); // Unsetting so in the end we can see if $inputArray was fully processed. } } } //TYPO3\CMS\Core\Utility\DebugUtility::debug($TCEmain_cmd,'$TCEmain_cmd'); //TYPO3\CMS\Core\Utility\DebugUtility::debug($TCEmain_data,'$TCEmain_data'); self::$targetLanguageID = $Tlang; // Execute CMD array: Localizing records: /** @var $tce DataHandler */ $tce = GeneralUtility::makeInstance(DataHandler::class); if ($this->extensionConfiguration['enable_neverHideAtCopy'] == 1) { $tce->neverHideAtCopy = true; } $tce->stripslashes_values = false; $tce->isImporting = true; if (count($TCEmain_cmd)) { $tce->start(array(), $TCEmain_cmd); $tce->process_cmdmap(); if (count($tce->errorLog)) { debug($tce->errorLog, 'TCEmain localization errors:'); } } // Before remapping if (TYPO3_DLOG) { GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': TCEmain_data before remapping: ' . GeneralUtility::arrayToLogString($TCEmain_data), 'l10nmgr'); } // Remapping those elements which are new: $this->lastTCEMAINCommandsCount = 0; foreach ($TCEmain_data as $table => $items) { foreach ($TCEmain_data[$table] as $TuidString => $fields) { list($Tuid, $Tlang, $TdefRecord) = explode('/', $TuidString); $this->lastTCEMAINCommandsCount++; if ($Tuid === 'NEW') { if ($tce->copyMappingArray_merged[$table][$TdefRecord]) { $TCEmain_data[$table][BackendUtility::wsMapId($table, $tce->copyMappingArray_merged[$table][$TdefRecord])] = $fields; } else { GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': Record "' . $table . ':' . $TdefRecord . '" was NOT localized as it should have been!', 'l10nmgr'); } unset($TCEmain_data[$table][$TuidString]); } } } // After remapping if (TYPO3_DLOG) { GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': TCEmain_data after remapping: ' . GeneralUtility::arrayToLogString($TCEmain_data), 'l10nmgr'); } // Now, submitting translation data: /** @var $tce DataHandler */ $tce = GeneralUtility::makeInstance(DataHandler::class); if ($this->extensionConfiguration['enable_neverHideAtCopy'] == 1) { $tce->neverHideAtCopy = true; } $tce->stripslashes_values = false; $tce->dontProcessTransformations = true; $tce->isImporting = true; //print_r($TCEmain_data); $tce->start($TCEmain_data, array()); // check has been done previously that there is a backend user which is Admin and also in live workspace $tce->process_datamap(); self::$targetLanguageID = null; if (count($tce->errorLog)) { GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': TCEmain update errors: ' . GeneralUtility::arrayToLogString($tce->errorLog), 'l10nmgr'); } if (count($tce->autoVersionIdMap) && count($_flexFormDiffArray)) { if (TYPO3_DLOG) { GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': flexFormDiffArry: ' . GeneralUtility::arrayToLogString($this->flexFormDiffArray), 'l10nmgr'); } foreach ($_flexFormDiffArray as $key => $value) { list($Ttable, $Tuid, $Trest) = explode(':', $key, 3); if ($tce->autoVersionIdMap[$Ttable][$Tuid]) { $_flexFormDiffArray[$Ttable . ':' . $tce->autoVersionIdMap[$Ttable][$Tuid] . ':' . $Trest] = $_flexFormDiffArray[$key]; unset($_flexFormDiffArray[$key]); } } if (TYPO3_DLOG) { GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': autoVersionIdMap: ' . $tce->autoVersionIdMap, 'l10nmgr'); GeneralUtility::sysLog(__FILE__ . ': ' . __LINE__ . ': _flexFormDiffArray: ' . GeneralUtility::arrayToLogString($_flexFormDiffArray), 'l10nmgr'); } } // Should be empty now - or there were more information in the incoming array than there should be! if (count($inputArray)) { debug($inputArray, 'These fields were ignored since they were not in the configuration:'); } return $_flexFormDiffArray; } else { return false; } }
<?php if (!defined('TYPO3_MODE')) { die('Access denied.'); } if (FALSE === isset($GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'])) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('FluidcontentCore requires an additional configuration file in typo3conf/AdditionalConfiguration.php - ' . 'you can have FluidcontentCore generate this file for you from the extension manager by running the FluidcontentCore update script. A dummy ' . 'has been created, but you will only be able to render content (not plugins!) until the file is created', 'fluidcontent_core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_WARNING); $GLOBALS['TYPO3_CONF_VARS']['FE']['contentRenderingTemplates'] = array('fluidcontentcore/Configuration/TypoScript/'); } $GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['types'] = array('header', 'text', 'image', 'bullets', 'uploads', 'table', 'media', 'menu', 'shortcut', 'div', 'html', 'default'); \FluidTYPO3\Flux\Core::registerConfigurationProvider('FluidTYPO3\\FluidcontentCore\\Provider\\CoreContentProvider'); $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms']['db_new_content_el']['wizardItemsHook']['fluidcontent_core'] = 'FluidTYPO3\\FluidcontentCore\\Hooks\\WizardItemsHookSubscriber'; // Prepare a global variants registration array indexed by CType value. // To add your own, do fx: $GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['variants']['textpic'][] = 'myextensionkey'; $GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['variants'] = array_combine(array_values($GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['types']), array_fill(0, count($GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['types']), array())); $types = count($GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['types']); for ($i = 0; $i < $types; $i++) { \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin('FluidTYPO3.FluidcontentCore', ucfirst($GLOBALS['TYPO3_CONF_VARS']['FluidTYPO3.FluidcontentCore']['types'][$i]), array('CoreContent' => 'render,error'), array()); } unset($types, $i); // Include new content elements to modWizards if (TRUE === version_compare(TYPO3_version, '7.3', '>')) { \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:fluidcontent_core/Configuration/PageTS/modWizards.ts">'); }
/** * Finds and replaces all URLs by using a given regex * * @param string $contents Data to process * @param string $regex Regex used to find URLs in content * @param string $originalDirectory Original location to CSS file, if file based. * @param string $wrap Wrap around replaced values * @return string Processed data */ protected function copyReferencedFilesAndReplacePaths($contents, $regex, $originalDirectory, $wrap = '|') { $matches = array(); $replacements = array(); $wrap = explode('|', $wrap); preg_match_all($regex, $contents, $matches); foreach ($matches[2] as $matchCount => $match) { $match = trim($match, '\'" '); if (FALSE === strpos($match, ':') && !preg_match('/url\\s*\\(/i', $match)) { $checksum = md5($originalDirectory . $match); if (0 < preg_match('/([^\\?#]+)(.+)?/', $match, $items)) { list(, $path, $suffix) = $items; } else { $path = $match; $suffix = ''; } $newPath = basename($path); $extension = pathinfo($newPath, PATHINFO_EXTENSION); $temporaryFileName = 'vhs-assets-css-' . $checksum . '.' . $extension; $temporaryFile = constant('PATH_site') . 'typo3temp/' . $temporaryFileName; $rawPath = GeneralUtility::getFileAbsFileName($originalDirectory . (TRUE === empty($originalDirectory) ? '' : '/')) . $path; $realPath = realpath($rawPath); if (FALSE === $realPath) { GeneralUtility::sysLog('Asset at path "' . $rawPath . '" not found. Processing skipped.', GeneralUtility::SYSLOG_SEVERITY_WARNING); } else { if (FALSE === file_exists($temporaryFile)) { copy($realPath, $temporaryFile); } $replacements[$matches[1][$matchCount]] = $wrap[0] . $temporaryFileName . $suffix . $wrap[1]; } } } if (FALSE === empty($replacements)) { $contents = str_replace(array_keys($replacements), array_values($replacements), $contents); } return $contents; }
/** * 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; // $this->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) { GeneralUtility::sysLog(__FILE__ . ': Before RTE transformation:' . LF . $xmlstring . LF, 'l10nmgr'); } $xmlstring = str_replace(" ", ' ', $xmlstring); $content = $this->parseHTML->TS_transform_db($xmlstring, 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 = GeneralUtility::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) { GeneralUtility::sysLog(__FILE__ . ': After RTE transformation:' . LF . $content . LF, 'l10nmgr'); } return $content; }
/** * Ensures that the personal dictionary is utf-8 encoded * * @return void */ protected function fixPersonalDictionaryCharacterSet() { if ($this->personalDictionaryPath) { // Fix the options of the personl word list and of the replacement pairs files // Aspell creates such files only for the main dictionary $fileNames = array(); $mainDictionary = preg_split('/[-_]/', $this->dictionary, 2); $fileNames[0] = $this->personalDictionaryPath . '/' . '.aspell.' . $mainDictionary[0] . '.pws'; $fileNames[1] = $this->personalDictionaryPath . '/' . '.aspell.' . $mainDictionary[0] . '.prepl'; foreach ($fileNames as $fileName) { if (file_exists($fileName)) { $fileContent = file_get_contents($fileName); if ($fileContent === FALSE) { GeneralUtility::sysLog('SpellChecker personal word list read error: ' . $fileName, $this->extKey, GeneralUtility::SYSLOG_SEVERITY_ERROR); } else { $fileContent = explode(LF, $fileContent); if (strpos($fileContent[0], 'utf-8') === FALSE) { $fileContent[0] .= ' utf-8'; $fileContent = implode(LF, $fileContent); $result = file_put_contents($fileName, $fileContent); if ($result === FALSE) { GeneralUtility::sysLog('SpellChecker personal word list write error: ' . $fileName, $this->extKey, GeneralUtility::SYSLOG_SEVERITY_ERROR); } } } } } } }
/** * 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 $valueList Contains values for the field names listed above (with slashes removed if from POST input) * @param boolean $base64 Whether to base64 encode the mail content * @return void * @todo Define visibility */ public function start($valueList, $base64 = FALSE) { $this->mailMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\MailMessage'); 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; } else { // Otherwise use renderCharset as default $this->characterSet = $GLOBALS['TSFE']->renderCharset; } 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 ' . \TYPO3\CMS\Core\Utility\GeneralUtility::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 (!\TYPO3\CMS\Core\Utility\GeneralUtility::validEmail($this->fromAddress)) { $this->fromAddress = \TYPO3\CMS\Core\Utility\MailUtility::getSystemFromAddress(); $this->fromName = \TYPO3\CMS\Core\Utility\MailUtility::getSystemFromName(); } $this->replyToAddress = $valueList['replyto_email'] ? $valueList['replyto_email'] : $this->fromAddress; $this->priority = $valueList['priority'] ? \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($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 = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac($this->autoRespondMessage); if ($autoRespondChecksum !== $correctHmacChecksum) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Possible misuse of t3lib_formmail auto respond method. Subject: ' . $valueList['subject'], 'Core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); 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 (!\TYPO3\CMS\Core\Utility\GeneralUtility::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->characterSet); $this->mailMessage->addPart($plainTextContent, 'text/plain', $this->characterSet); } else { $this->mailMessage->setBody($plainTextContent, 'text/plain', $this->characterSet); } for ($a = 0; $a < 10; $a++) { $variableName = 'attachment' . ($a ? $a : ''); if (!isset($_FILES[$variableName])) { continue; } if (!is_uploaded_file($_FILES[$variableName]['tmp_name'])) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Possible abuse of t3lib_formmail: temporary file "' . $_FILES[$variableName]['tmp_name'] . '" ("' . $_FILES[$variableName]['name'] . '") was not an uploaded file.', 'Core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); } if ($_FILES[$variableName]['tmp_name']['error'] !== UPLOAD_ERR_OK) { \TYPO3\CMS\Core\Utility\GeneralUtility::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', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); } $theFile = \TYPO3\CMS\Core\Utility\GeneralUtility::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->setReplyTo($replyTo); $this->mailMessage->getHeaders()->addTextHeader('Organization', $this->organisation); if ($valueList['recipient_copy']) { $this->mailMessage->setCc($this->parseAddresses($valueList['recipient_copy'])); } $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) { \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Possible misuse of t3lib_formmail: see TYPO3 devLog', 'Core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR); if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG']) { \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('t3lib_formmail: ' . \TYPO3\CMS\Core\Utility\GeneralUtility::arrayToLogString($this->dirtyHeaders, '', 200), 'Core', 3); } } } }
/** * Sets the cache-flag to 1. Could be called from user-included php-files in order to ensure that a page is not cached. * * @param string $reason An optional reason to be written to the syslog. * @return void * @todo Define visibility */ public function set_no_cache($reason = '') { if (strlen($reason)) { $warning = '$TSFE->set_no_cache() was triggered. Reason: ' . $reason . '.'; } else { $trace = debug_backtrace(); // This is a hack to work around ___FILE___ resolving symbolic links $PATH_site_real = str_replace('t3lib', '', realpath(PATH_site . 't3lib')); $file = $trace[0]['file']; if (substr($file, 0, strlen($PATH_site_real)) === $PATH_site_real) { $file = str_replace($PATH_site_real, '', $file); } else { $file = str_replace(PATH_site, '', $file); } $line = $trace[0]['line']; $trigger = $file . ' on line ' . $line; $warning = '$TSFE->set_no_cache() was triggered by ' . $trigger . '.'; } if ($this->TYPO3_CONF_VARS['FE']['disableNoCacheParameter']) { $warning .= ' However, $TYPO3_CONF_VARS[\'FE\'][\'disableNoCacheParameter\'] is set, so it will be ignored!'; $GLOBALS['TT']->setTSlogMessage($warning, 2); } else { $warning .= ' Caching is disabled!'; $this->disableCache(); } \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog($warning, 'cms', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_WARNING); }
/** * @param Form $form */ private function logInvalidSubscription($form) { $error = 'Could not synchronize user ' . $form->getField('EMAIL')->getValue() . ":\n"; /** @var Field $field */ foreach ($form->getFields(TRUE) as $field) { foreach ($field->getErrors() as $error) { $error .= $field->getName() . ': ' . $this->translate($error) . "\n"; } } GeneralUtility::sysLog($error, 't3chimp', 2); }
/** * Search for commented INCLUDE_TYPOSCRIPT statements * and save the content between the BEGIN and the END line to the specified file * * @param string $string Template content * @param int $cycle_counter Counter for detecting endless loops * @param array $extractedFileNames * @param string $parentFilenameOrPath * * @throws \RuntimeException * @throws \UnexpectedValueException * @return string Template content with uncommented include statements */ public static function extractIncludes($string, $cycle_counter = 1, array $extractedFileNames = array(), $parentFilenameOrPath = '') { if ($cycle_counter > 10) { GeneralUtility::sysLog('It appears like TypoScript code is looping over itself. Check your templates for "<INCLUDE_TYPOSCRIPT: ..." tags', 'Core', GeneralUtility::SYSLOG_SEVERITY_WARNING); return ' ### ### ERROR: Recursion! ### '; } $expectedEndTag = ''; $fileContent = array(); $restContent = array(); $fileName = NULL; $inIncludePart = FALSE; $lines = preg_split("/\r\n|\n|\r/", $string); $skipNextLineIfEmpty = FALSE; $openingCommentedIncludeStatement = NULL; $optionalProperties = ''; foreach ($lines as $line) { // \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::checkIncludeLines inserts // an additional empty line, remove this again if ($skipNextLineIfEmpty) { if (trim($line) === '') { continue; } $skipNextLineIfEmpty = FALSE; } // Outside commented include statements if (!$inIncludePart) { // Search for beginning commented include statements if (preg_match('/###\\s*<INCLUDE_TYPOSCRIPT:\\s*source\\s*=\\s*"\\s*((?i)file|dir)\\s*:\\s*([^"]*)"(.*)>\\s*BEGIN/i', $line, $matches)) { // Found a commented include statement // Save this line in case there is no ending tag $openingCommentedIncludeStatement = trim($line); $openingCommentedIncludeStatement = preg_replace('/\\s*### Warning: .*###\\s*/', '', $openingCommentedIncludeStatement); // type of match: FILE or DIR $inIncludePart = strtoupper($matches[1]); $fileName = $matches[2]; $optionalProperties = $matches[3]; $expectedEndTag = '### <INCLUDE_TYPOSCRIPT: source="' . $inIncludePart . ':' . $fileName . '"' . $optionalProperties . '> END'; // Strip all whitespace characters to make comparison 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; } //if (is_array($matches)) GeneralUtility::devLog('matches', 'TypoScriptParser', 0, $matches); } else { // Inside commented include statements // Search for the matching ending commented include statement $strippedLine = preg_replace('/\\s/', '', $line); if (stripos($strippedLine, $expectedEndTag) !== FALSE) { // Found the matching ending include statement $fileContentString = implode(PHP_EOL, $fileContent); // Write the content to the file // Resolve a possible relative paths if a parent file is given if ($parentFilenameOrPath !== '' && $fileName[0] === '.') { $realFileName = PathUtility::getAbsolutePathOfRelativeReferencedFileOrPath($parentFilenameOrPath, $fileName); } else { $realFileName = $fileName; } $realFileName = GeneralUtility::getFileAbsFileName($realFileName); if ($inIncludePart === 'FILE') { // Some file checks if (!GeneralUtility::verifyFilenameAgainstDenyPattern($realFileName)) { throw new \UnexpectedValueException(sprintf('File "%s" was not included since it is not allowed due to fileDenyPattern.', $fileName), 1382651858); } if (empty($realFileName)) { throw new \UnexpectedValueException(sprintf('"%s" is not a valid file location.', $fileName), 1294586441); } if (!is_writable($realFileName)) { throw new \RuntimeException(sprintf('"%s" is not writable.', $fileName), 1294586442); } if (in_array($realFileName, $extractedFileNames)) { throw new \RuntimeException(sprintf('Recursive/multiple inclusion of file "%s"', $realFileName), 1294586443); } $extractedFileNames[] = $realFileName; // Recursive call to detected nested commented include statements $fileContentString = self::extractIncludes($fileContentString, $cycle_counter + 1, $extractedFileNames, $realFileName); // Write the content to the file if (!GeneralUtility::writeFile($realFileName, $fileContentString)) { throw new \RuntimeException(sprintf('Could not write file "%s"', $realFileName), 1294586444); } // Insert reference to the file in the rest content $restContent[] = '<INCLUDE_TYPOSCRIPT: source="FILE:' . $fileName . '"' . $optionalProperties . '>'; } else { // must be DIR // Some file checks if (empty($realFileName)) { throw new \UnexpectedValueException(sprintf('"%s" is not a valid location.', $fileName), 1366493602); } if (!is_dir($realFileName)) { throw new \RuntimeException(sprintf('"%s" is not a directory.', $fileName), 1366493603); } if (in_array($realFileName, $extractedFileNames)) { throw new \RuntimeException(sprintf('Recursive/multiple inclusion of directory "%s"', $realFileName), 1366493604); } $extractedFileNames[] = $realFileName; // Recursive call to detected nested commented include statements self::extractIncludes($fileContentString, $cycle_counter + 1, $extractedFileNames, $realFileName); // just drop content between tags since it should usually just contain individual files from that dir // Insert reference to the dir in the rest content $restContent[] = '<INCLUDE_TYPOSCRIPT: source="DIR:' . $fileName . '"' . $optionalProperties . '>'; } // Reset variables (preparing for the next commented include statement) $fileContent = array(); $fileName = NULL; $inIncludePart = FALSE; $openingCommentedIncludeStatement = NULL; // \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::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(PHP_EOL, $restContent); return $restContentString; }