// ********************* if ($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] !== '') { if ($TYPO3_CONF_VARS['SYS']['errorHandler'] !== '') { // register an error handler for the given errorHandlerErrors $errorHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SYS']['errorHandler'], $TYPO3_CONF_VARS['SYS']['errorHandlerErrors']); // set errors which will be converted in an exception $errorHandler->setExceptionalErrors($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors']); } $exceptionHandler = t3lib_div::makeInstance($TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler']); } /** @var TYPO3_DB t3lib_db */ $TYPO3_DB = t3lib_div::makeInstance('t3lib_DB'); $TYPO3_DB->debugOutput = $TYPO3_CONF_VARS['SYS']['sqlDebug']; $CLIENT = t3lib_div::clientInfo(); // $CLIENT includes information about the browser/user-agent $PARSETIME_START = t3lib_div::milliseconds(); // Is set to the system time in milliseconds. This could be used to output script parsetime in the end of the script // *********************************** // Initializing the Caching System // *********************************** if (TYPO3_UseCachingFramework) { $typo3CacheManager = t3lib_div::makeInstance('t3lib_cache_Manager'); $typo3CacheFactory = t3lib_div::makeInstance('t3lib_cache_Factory'); $typo3CacheFactory->setCacheManager($typo3CacheManager); t3lib_cache::initPageCache(); t3lib_cache::initPageSectionCache(); t3lib_cache::initContentHashCache(); } // ************************* // CLI dispatch processing // *************************
/** * Returns script parsetime IF ->parseTimeFlag is set and user is "admin" * Automatically outputted in page end * * @return string */ function parseTime() { if ($this->parseTimeFlag && $GLOBALS['BE_USER']->isAdmin()) { return '<p>(ParseTime: ' . (t3lib_div::milliseconds() - $GLOBALS['PARSETIME_START']) . ' ms</p> <p>REQUEST_URI-length: ' . strlen(t3lib_div::getIndpEnv('REQUEST_URI')) . ')</p>'; } }
/** * Indexing a regular document given as $file (relative to PATH_site, local file) * * @param string Relative Filename, relative to PATH_site. It can also be an absolute path as long as it is inside the lockRootPath (validated with t3lib_div::isAbsPath()). Finally, if $contentTmpFile is set, this value can be anything, most likely a URL * @param boolean If set, indexing is forced (despite content hashes, mtime etc). * @param string Temporary file with the content to read it from (instead of $file). Used when the $file is a URL. * @param string File extension for temporary file. * @return void */ function indexRegularDocument($file, $force = FALSE, $contentTmpFile = '', $altExtension = '') { // Init $fI = pathinfo($file); $ext = $altExtension ? $altExtension : strtolower($fI['extension']); // Create abs-path: if (!$contentTmpFile) { if (!t3lib_div::isAbsPath($file)) { // Relative, prepend PATH_site: $absFile = t3lib_div::getFileAbsFileName(PATH_site . $file); } else { // Absolute, pass-through: $absFile = $file; } $absFile = t3lib_div::isAllowedAbsPath($absFile) ? $absFile : ''; } else { $absFile = $contentTmpFile; } // Indexing the document: if ($absFile && @is_file($absFile)) { if ($this->external_parsers[$ext]) { $mtime = filemtime($absFile); $cParts = $this->fileContentParts($ext, $absFile); foreach ($cParts as $cPKey) { $this->internal_log = array(); $this->log_push('Index: ' . str_replace('.', '_', basename($file)) . ($cPKey ? '#' . $cPKey : ''), ''); $Pstart = t3lib_div::milliseconds(); $subinfo = array('key' => $cPKey); // Setting page range. This is "0" (zero) when no division is made, otherwise a range like "1-3" $phash_arr = $this->file_phash_arr = $this->setExtHashes($file, $subinfo); $check = $this->checkMtimeTstamp($mtime, $phash_arr['phash']); if ($check > 0 || $force) { if ($check > 0) { $this->log_setTSlogMessage('Indexing needed, reason: ' . $this->reasons[$check], 1); } else { $this->log_setTSlogMessage('Indexing forced by flag', 1); } // Check external file counter: if ($this->externalFileCounter < $this->maxExternalFiles || $force) { // Divide into title,keywords,description and body: $this->log_push('Split content', ''); $contentParts = $this->readFileContent($ext, $absFile, $cPKey); $this->log_pull(); if (is_array($contentParts)) { // Calculating a hash over what is to be the actual content. (see indexTypo3PageContent()) $content_md5h = $this->md5inthash(implode($contentParts, '')); if ($this->checkExternalDocContentHash($phash_arr['phash_grouping'], $content_md5h) || $force) { // Increment counter: $this->externalFileCounter++; // Splitting words $this->log_push('Extract words from content', ''); $splitInWords = $this->processWordsInArrays($contentParts); $this->log_pull(); // Analyse the indexed words. $this->log_push('Analyse the extracted words', ''); $indexArr = $this->indexAnalyze($splitInWords); $this->log_pull(); // Submitting page (phash) record $this->log_push('Submitting page', ''); $size = filesize($absFile); $ctime = filemtime($absFile); // Unfortunately I cannot determine WHEN a file is originally made - so I must return the modification time... $this->submitFilePage($phash_arr, $file, $subinfo, $ext, $mtime, $ctime, $size, $content_md5h, $contentParts); $this->log_pull(); // Check words and submit to word list if not there $this->log_push('Check word list and submit words', ''); $this->checkWordList($indexArr); $this->submitWords($indexArr, $phash_arr['phash']); $this->log_pull(); // Set parsetime $this->updateParsetime($phash_arr['phash'], t3lib_div::milliseconds() - $Pstart); } else { $this->updateTstamp($phash_arr['phash'], $mtime); // Update the timestamp $this->log_setTSlogMessage('Indexing not needed, the contentHash, ' . $content_md5h . ', has not changed. Timestamp updated.'); } } else { $this->log_setTSlogMessage('Could not index file! Unsupported extension.'); } } else { $this->log_setTSlogMessage('The limit of ' . $this->maxExternalFiles . ' has already been exceeded, so no indexing will take place this time.'); } } else { $this->log_setTSlogMessage('Indexing not needed, reason: ' . $this->reasons[$check]); } // Checking and setting sections: # $this->submitFile_grlist($phash_arr['phash']); // Setting a gr_list record if there is none already (set for default fe_group) $this->submitFile_section($phash_arr['phash']); // Setting a section-record for the file. This is done also if the file is not indexed. Notice that section records are deleted when the page is indexed. $this->log_pull(); } } else { $this->log_setTSlogMessage('Indexing not possible; The extension "' . $ext . '" was not supported.'); } } else { $this->log_setTSlogMessage('Indexing not possible; File "' . $absFile . '" not found or valid.'); } }
/** * Performs the search, the display and writing stats * * @param array Search words in array, see ->getSearchWords() for details * @return string HTML for result display. */ function doSearch($sWArr) { // Find free index uid: $freeIndexUid = $this->piVars['freeIndexUid']; if ($freeIndexUid == -2) { $freeIndexUid = $this->conf['search.']['defaultFreeIndexUidList']; } $indexCfgs = t3lib_div::intExplode(',', $freeIndexUid); $accumulatedContent = ''; foreach ($indexCfgs as $freeIndexUid) { // Get result rows: $pt1 = t3lib_div::milliseconds(); if ($hookObj = $this->hookRequest('getResultRows')) { $resData = $hookObj->getResultRows($sWArr, $freeIndexUid); } else { $resData = $this->getResultRows($sWArr, $freeIndexUid); } // Display search results: $pt2 = t3lib_div::milliseconds(); if ($hookObj = $this->hookRequest('getDisplayResults')) { $content = $hookObj->getDisplayResults($sWArr, $resData, $freeIndexUid); } else { $content = $this->getDisplayResults($sWArr, $resData, $freeIndexUid); } $pt3 = t3lib_div::milliseconds(); // Create header if we are searching more than one indexing configuration: if (count($indexCfgs) > 1) { if ($freeIndexUid > 0) { list($indexCfgRec) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('title', 'index_config', 'uid=' . intval($freeIndexUid) . $this->cObj->enableFields('index_config')); $titleString = $indexCfgRec['title']; } else { $titleString = $this->pi_getLL('opt_freeIndexUid_header_' . $freeIndexUid); } $content = '<h1 class="tx-indexedsearch-category">' . htmlspecialchars($titleString) . '</h1>' . $content; } $accumulatedContent .= $content; } // Write search statistics $this->writeSearchStat($sWArr, $resData['count'], array($pt1, $pt2, $pt3)); // Return content: return $accumulatedContent; }
/** * Recursive traversal of page tree: * * @param integer Page root id (must be online, valid page record - or zero for page tree root) * @param integer Depth * @param integer Echo Level * @param string Call back function (from this class or subclass) * @param string DON'T set from outside, internal. (indicates we are inside a version of a page) * @param integer DON'T set from outside, internal. (1: Indicates that rootID is a version of a page, 2: ...that it is even a version of a version (which triggers a warning!) * @param string Internal string that accumulates the path * @return void * @access private */ function genTree_traverse($rootID, $depth, $echoLevel = 0, $callBack = '', $versionSwapmode = '', $rootIsVersion = 0, $accumulatedPath = '') { // Register page: $this->recStats['all']['pages'][$rootID] = $rootID; $pageRecord = t3lib_BEfunc::getRecordRaw('pages', 'uid=' . intval($rootID), 'deleted,title,t3ver_count,t3ver_wsid'); $accumulatedPath .= '/' . $pageRecord['title']; // Register if page is deleted: if ($pageRecord['deleted']) { $this->recStats['deleted']['pages'][$rootID] = $rootID; } // If rootIsVersion is set it means that the input rootID is that of a version of a page. See below where the recursive call is made. if ($rootIsVersion) { $this->recStats['versions']['pages'][$rootID] = $rootID; if ($pageRecord['t3ver_count'] >= 1 && $pageRecord['t3ver_wsid'] == 0) { // If it has been published and is in archive now... $this->recStats['versions_published']['pages'][$rootID] = $rootID; } if ($pageRecord['t3ver_wsid'] == 0) { // If it has been published and is in archive now... $this->recStats['versions_liveWS']['pages'][$rootID] = $rootID; } if (!isset($this->workspaceIndex[$pageRecord['t3ver_wsid']])) { // If it doesn't belong to a workspace... $this->recStats['versions_lost_workspace']['pages'][$rootID] = $rootID; } if ($rootIsVersion == 2) { // In case the rootID is a version inside a versioned page $this->recStats['versions_inside_versioned_page']['pages'][$rootID] = $rootID; } } if ($echoLevel > 0) { echo LF . $accumulatedPath . ' [' . $rootID . ']' . ($pageRecord['deleted'] ? ' (DELETED)' : '') . ($this->recStats['versions_published']['pages'][$rootID] ? ' (PUBLISHED)' : ''); } if ($echoLevel > 1 && $this->recStats['versions_lost_workspace']['pages'][$rootID]) { echo LF . ' ERROR! This version belongs to non-existing workspace (' . $pageRecord['t3ver_wsid'] . ')!'; } if ($echoLevel > 1 && $this->recStats['versions_inside_versioned_page']['pages'][$rootID]) { echo LF . ' WARNING! This version is inside an already versioned page or branch!'; } // Call back: if ($callBack) { $this->{$callBack}('pages', $rootID, $echoLevel, $versionSwapmode, $rootIsVersion); } $pt3 = t3lib_div::milliseconds(); // Traverse tables of records that belongs to page: foreach ($GLOBALS['TCA'] as $tableName => $cfg) { if ($tableName != 'pages') { // Select all records belonging to page: $pt4 = t3lib_div::milliseconds(); $resSub = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), $tableName, 'pid=' . intval($rootID) . ($this->genTree_traverseDeleted ? '' : t3lib_BEfunc::deleteClause($tableName))); $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL']['(ALL)'] += t3lib_div::milliseconds() - $pt4; $this->performanceStatistics['genTree_traverse():TraverseTables:']['MySQL'][$tableName] += t3lib_div::milliseconds() - $pt4; $pt5 = t3lib_div::milliseconds(); $count = $GLOBALS['TYPO3_DB']->sql_num_rows($resSub); if ($count) { if ($echoLevel == 2) { echo LF . ' \\-' . $tableName . ' (' . $count . ')'; } } while ($rowSub = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resSub)) { if ($echoLevel == 3) { echo LF . ' \\-' . $tableName . ':' . $rowSub['uid']; } // If the rootID represents an "element" or "page" version type, we must check if the record from this table is allowed to belong to this: if ($versionSwapmode == 'SWAPMODE:-1' || $versionSwapmode == 'SWAPMODE:0' && !$GLOBALS['TCA'][$tableName]['ctrl']['versioning_followPages']) { // This is illegal records under a versioned page - therefore not registered in $this->recStats['all'] so they should be orphaned: $this->recStats['illegal_record_under_versioned_page'][$tableName][$rowSub['uid']] = $rowSub['uid']; if ($echoLevel > 1) { echo LF . ' ERROR! Illegal record (' . $tableName . ':' . $rowSub['uid'] . ') under versioned page!'; } } else { $this->recStats['all'][$tableName][$rowSub['uid']] = $rowSub['uid']; // Register deleted: if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $rowSub[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) { $this->recStats['deleted'][$tableName][$rowSub['uid']] = $rowSub['uid']; if ($echoLevel == 3) { echo ' (DELETED)'; } } // Check location of records regarding tree root: if (!$GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] && $rootID == 0) { $this->recStats['misplaced_at_rootlevel'][$tableName][$rowSub['uid']] = $rowSub['uid']; if ($echoLevel > 1) { echo LF . ' ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') on rootlevel!'; } } if ($GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'] == 1 && $rootID > 0) { $this->recStats['misplaced_inside_tree'][$tableName][$rowSub['uid']] = $rowSub['uid']; if ($echoLevel > 1) { echo LF . ' ERROR! Misplaced record (' . $tableName . ':' . $rowSub['uid'] . ') inside page tree!'; } } // Traverse plugins: if ($callBack) { $this->{$callBack}($tableName, $rowSub['uid'], $echoLevel, $versionSwapmode, $rootIsVersion); } // Add any versions of those records: if ($this->genTree_traverseVersions) { $versions = t3lib_BEfunc::selectVersionsOfRecord($tableName, $rowSub['uid'], 'uid,t3ver_wsid,t3ver_count' . ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] ? ',' . $GLOBALS['TCA'][$tableName]['ctrl']['delete'] : ''), 0, TRUE); if (is_array($versions)) { foreach ($versions as $verRec) { if (!$verRec['_CURRENT_VERSION']) { if ($echoLevel == 3) { echo LF . ' \\-[#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . '] ' . $tableName . ':' . $verRec['uid'] . ')'; } $this->recStats['all'][$tableName][$verRec['uid']] = $verRec['uid']; // Register deleted: if ($GLOBALS['TCA'][$tableName]['ctrl']['delete'] && $verRec[$GLOBALS['TCA'][$tableName]['ctrl']['delete']]) { $this->recStats['deleted'][$tableName][$verRec['uid']] = $verRec['uid']; if ($echoLevel == 3) { echo ' (DELETED)'; } } // Register version: $this->recStats['versions'][$tableName][$verRec['uid']] = $verRec['uid']; if ($verRec['t3ver_count'] >= 1 && $verRec['t3ver_wsid'] == 0) { // Only register published versions in LIVE workspace (published versions in draft workspaces are allowed) $this->recStats['versions_published'][$tableName][$verRec['uid']] = $verRec['uid']; if ($echoLevel == 3) { echo ' (PUBLISHED)'; } } if ($verRec['t3ver_wsid'] == 0) { $this->recStats['versions_liveWS'][$tableName][$verRec['uid']] = $verRec['uid']; } if (!isset($this->workspaceIndex[$verRec['t3ver_wsid']])) { $this->recStats['versions_lost_workspace'][$tableName][$verRec['uid']] = $verRec['uid']; if ($echoLevel > 1) { echo LF . ' ERROR! Version (' . $tableName . ':' . $verRec['uid'] . ') belongs to non-existing workspace (' . $verRec['t3ver_wsid'] . ')!'; } } if ($versionSwapmode) { // In case we are inside a versioned branch, there should not exists versions inside that "branch". $this->recStats['versions_inside_versioned_page'][$tableName][$verRec['uid']] = $verRec['uid']; if ($echoLevel > 1) { echo LF . ' ERROR! This version (' . $tableName . ':' . $verRec['uid'] . ') is inside an already versioned page or branch!'; } } // Traverse plugins: if ($callBack) { $this->{$callBack}($tableName, $verRec['uid'], $echoLevel, $versionSwapmode, $rootIsVersion); } } } } unset($versions); } } } $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc']['(ALL)'] += t3lib_div::milliseconds() - $pt5; $this->performanceStatistics['genTree_traverse():TraverseTables:']['Proc'][$tableName] += t3lib_div::milliseconds() - $pt5; } } unset($resSub); unset($rowSub); $this->performanceStatistics['genTree_traverse():TraverseTables'] += t3lib_div::milliseconds() - $pt3; // Find subpages to root ID and traverse (only when rootID is not a version or is a branch-version): if (!$versionSwapmode || $versionSwapmode == 'SWAPMODE:1') { if ($depth > 0) { $depth--; $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'pages', 'pid=' . intval($rootID) . ($this->genTree_traverseDeleted ? '' : t3lib_BEfunc::deleteClause('pages')), '', 'sorting'); while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { $this->genTree_traverse($row['uid'], $depth, $echoLevel, $callBack, $versionSwapmode, 0, $accumulatedPath); } } // Add any versions of pages if ($rootID > 0 && $this->genTree_traverseVersions) { $versions = t3lib_BEfunc::selectVersionsOfRecord('pages', $rootID, 'uid,t3ver_oid,t3ver_wsid,t3ver_count,t3ver_swapmode', 0, TRUE); if (is_array($versions)) { foreach ($versions as $verRec) { if (!$verRec['_CURRENT_VERSION']) { $this->genTree_traverse($verRec['uid'], $depth, $echoLevel, $callBack, 'SWAPMODE:' . t3lib_div::intInRange($verRec['t3ver_swapmode'], -1, 1), $versionSwapmode ? 2 : 1, $accumulatedPath . ' [#OFFLINE VERSION: WS#' . $verRec['t3ver_wsid'] . '/Cnt:' . $verRec['t3ver_count'] . ']'); } } } } } }
/** * Find orphan records * VERY CPU and memory intensive since it will look up the whole page tree! * * @return array */ function main() { global $TYPO3_DB; // Initialize result array: $resultArray = array('message' => $this->cli_help['name'] . LF . LF . $this->cli_help['description'], 'headers' => array('orphans' => array('Index of orphaned records', '', 3), 'misplaced_at_rootlevel' => array('Records that should not be at root level but are.', 'Fix manually by moving record into page tree', 2), 'misplaced_inside_tree' => array('Records that should be at root level but are not.', 'Fix manually by moving record to tree root', 2), 'illegal_record_under_versioned_page' => array('Records that cannot be attached to a versioned page', '(Listed under orphaned records so is fixed along with orphans.)', 2)), 'orphans' => array(), 'misplaced_at_rootlevel' => array(), 'misplaced_inside_tree' => array(), 'illegal_record_under_versioned_page' => array()); $startingPoint = 0; // zero = tree root, must use tree root if you wish to reverse selection to find orphans! $pt = t3lib_div::milliseconds(); $this->genTree($startingPoint, 1000, (int) $this->cli_argValue('--echotree')); $resultArray['misplaced_at_rootlevel'] = $this->recStats['misplaced_at_rootlevel']; $resultArray['misplaced_inside_tree'] = $this->recStats['misplaced_inside_tree']; $resultArray['illegal_record_under_versioned_page'] = $this->recStats['illegal_record_under_versioned_page']; // Find orphans: foreach ($GLOBALS['TCA'] as $tableName => $cfg) { $idList = is_array($this->recStats['all'][$tableName]) && count($this->recStats['all'][$tableName]) ? implode(',', $this->recStats['all'][$tableName]) : 0; // Select all records belonging to page: $orphanRecords = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $tableName, 'uid NOT IN (' . $idList . ')', '', 'uid', '', 'uid'); if (count($orphanRecords)) { $resultArray['orphans'][$tableName] = array(); foreach ($orphanRecords as $oR) { $resultArray['orphans'][$tableName][$oR['uid']] = $oR['uid']; } } } return $resultArray; }
/** * Function executed from the Scheduler. * * @return boolean Returns true on successful execution, false on error */ public function execute() { /* beispiel für das logging array. $devLog = array('message' => '', 'extKey' => 'mklib', 'dataVar' => FALSE); $devLog = array( tx_rnbase_util_Logger::LOGLEVEL_DEBUG => $devLog, tx_rnbase_util_Logger::LOGLEVEL_INFO => $devLog, tx_rnbase_util_Logger::LOGLEVEL_NOTICE => $devLog, tx_rnbase_util_Logger::LOGLEVEL_WARN => $devLog, tx_rnbase_util_Logger::LOGLEVEL_FATAL => $devLog ); */ $devLog = array(); $options = $this->getOptions(); $startTimeInMilliseconds = t3lib_div::milliseconds(); $memoryUsageAtStart = memory_get_usage(); tx_rnbase_util_Logger::info('[' . get_class($this) . ']: Scheduler starts', $this->getExtKey()); try { $message = $this->executeTask($options, $devLog); $this->setLastRunTime(); // devlog if (t3lib_extMgm::isLoaded('devlog')) { if (empty($devLog) || isset($devLog[tx_rnbase_util_Logger::LOGLEVEL_INFO]) && empty($devLog[tx_rnbase_util_Logger::LOGLEVEL_INFO]['message'])) { $devLog[tx_rnbase_util_Logger::LOGLEVEL_INFO]['message'] = $message; } foreach ($devLog as $logLevel => $logData) { if (empty($logData['message'])) { continue; } t3lib_div::devLog('[' . get_class($this) . ']: ' . $logData['message'], isset($logData['extKey']) ? $logData['extKey'] : $this->getExtKey(), $logLevel, isset($logData['dataVar']) ? $logData['dataVar'] : FALSE); } } } catch (Exception $exception) { $dataVar = array('errorcode' => $exception->getCode(), 'errormsg' => $exception->getMessage(), 'trace' => $exception->getTraceAsString(), 'options' => $options, 'devlog' => $devLog); if ($exception instanceof tx_rnbase_util_Exception) { $dataVar['exception_data'] = $exception->getAdditional(FALSE); } if (tx_rnbase_util_Logger::isFatalEnabled()) { tx_rnbase_util_Logger::fatal('Task [' . get_class($this) . '] failed.' . ' Error(' . $exception->getCode() . '):' . $exception->getMessage(), $this->getExtKey(), $dataVar); } // Exception Mail an die Entwicker senden $mail = tx_rnbase_configurations::getExtensionCfgValue('rn_base', 'sendEmailOnException'); if (!empty($mail)) { $this->sendErrorMail($mail, tx_rnbase::makeInstance('tx_rnbase_util_Exception', get_class($exception) . ': ' . $exception->getMessage(), $exception->getCode(), $dataVar, $exception)); } // Wir geben die Exception weiter, // damit der Scheduler eine entsprechende Meldung ausgeben kann. throw $exception; } $memoryUsageAtEnd = memory_get_usage(); tx_rnbase_util_Logger::info('[' . get_class($this) . ']: Scheduler ends successful ', $this->getExtKey(), array('Execution Time' => t3lib_div::milliseconds() - $startTimeInMilliseconds . ' ms', 'Memory Start' => $memoryUsageAtStart . ' Bytes', 'Memory End' => $memoryUsageAtEnd . ' Bytes', 'Memory Consumed' => $memoryUsageAtEnd - $memoryUsageAtStart . ' Bytes')); return true; }
/** * Executes a prepared query. * * @param string $query The query to execute * @param array $queryComponents The components of the query to execute * @return pointer MySQL result pointer / DBAL object * @access protected This method may only be called by t3lib_db_PreparedStatement */ public function exec_PREPAREDquery($query, array $precompiledParts) { if ($this->debug) { $pt = t3lib_div::milliseconds(); } // Get handler key and select API: switch ($precompiledParts['handler']) { case 'native': $this->lastQuery = $query; $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']); $this->resourceIdToTableNameMap[(string) $sqlResult] = $precompiledParts['ORIG_tableName']; break; case 'adodb': $limit = $precompiledParts['LIMIT']; if ($this->runningADOdbDriver('postgres')) { // Possibly rewrite the LIMIT to be PostgreSQL-compatible $splitLimit = t3lib_div::intExplode(',', $limit); // Splitting the limit values: if ($splitLimit[1]) { // If there are two parameters, do mapping differently than otherwise: $numrows = $splitLimit[1]; $offset = $splitLimit[0]; $limit = $numrows . ' OFFSET ' . $offset; } } if ($limit != '') { $splitLimit = t3lib_div::intExplode(',', $limit); // Splitting the limit values: if ($splitLimit[1]) { // If there are two parameters, do mapping differently than otherwise: $numrows = $splitLimit[1]; $offset = $splitLimit[0]; } else { $numrows = $splitLimit[0]; $offset = 0; } $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($query, $numrows, $offset); $this->lastQuery = $sqlResult->sql; } else { $this->lastQuery = $query; $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_Execute($this->lastQuery); } $sqlResult->TYPO3_DBAL_handlerType = 'adodb'; // Setting handler type in result object (for later recognition!) $sqlResult->TYPO3_DBAL_tableList = $precompiledParts['ORIG_tableName']; break; case 'userdefined': $queryParts = $precompiledParts['queryParts']; $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery($queryParts['SELECT'], $queryParts['FROM'], $queryParts['WHERE'], $queryParts['GROUPBY'], $queryParts['ORDERBY'], $queryParts['LIMIT']); if (is_object($sqlResult)) { $sqlResult->TYPO3_DBAL_handlerType = 'userdefined'; // Setting handler type in result object (for later recognition!) $sqlResult->TYPO3_DBAL_tableList = $precompiledParts['ORIG_tableName']; } break; } if ($this->printErrors && $this->sql_error()) { debug(array($this->lastQuery, $this->sql_error())); } if ($this->debug) { $data = array('handlerType' => $precompiledParts['handler'], 'args' => $precompiledParts, 'ORIG_from_table' => $precompiledParts['ORIG_tableName']); if ($this->conf['debugOptions']['numberRows']) { $data['numberRows'] = $this->sql_num_rows($sqlResult); } $this->debugHandler('exec_PREPAREDquery', t3lib_div::milliseconds() - $pt, $data); } // Return result handler. return $sqlResult; }
/** * The main method of the PlugIn * * @param string $content: The PlugIn content * @param array $conf: The PlugIn configuration * @return The content that is displayed on the website */ function main($content, $conf) { if (TYPO3_VERSION_INTEGER >= 7000000) { $this->ms = TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds(); } else { $this->ms = t3lib_div::milliseconds(); } $this->conf = $conf; $this->pi_setPiVarDefaults(); $this->pi_loadLL(); $this->pi_USER_INT_obj = 1; // Configuring so caching is not expected. This value means that no cHash params are ever set. We do this, because it's a USER_INT object! // initializes plugin configuration $this->init(); // init domReady action $this->initDomReadyAction(); // add header parts when in searchbox mode $this->addHeaderParts(); // init XAJAX? if ($this->conf['renderMethod'] != 'static') { if (TYPO3_VERSION_INTEGER < 6002000) { $xajaxIsLoaded = t3lib_extMgm::isLoaded('xajax'); } else { $xajaxIsLoaded = TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('xajax'); } if (!$xajaxIsLoaded) { return '<span style="color: red;"><b>ke_search error:</b>"XAJAX" must be installed for this mode.</span>'; } else { $this->initXajax(); } } // Spinner Image if ($this->conf['spinnerImageFile']) { $spinnerSrc = $this->conf['spinnerImageFile']; } else { if (TYPO3_VERSION_INTEGER < 6002000) { $spinnerSrc = t3lib_extMgm::siteRelPath($this->extKey) . 'res/img/spinner.gif'; } else { $spinnerSrc = TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey) . 'res/img/spinner.gif'; } } $this->spinnerImageFilters = '<img id="kesearch_spinner_filters" src="' . $spinnerSrc . '" alt="' . $this->pi_getLL('loading') . '" />'; $this->spinnerImageResults = '<img id="kesearch_spinner_results" src="' . $spinnerSrc . '" alt="' . $this->pi_getLL('loading') . '" />'; // get javascript onclick actions $this->initOnclickActions(); // hook for initials if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'] as $_classRef) { if (TYPO3_VERSION_INTEGER >= 7000000) { $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef); } else { $_procObj =& t3lib_div::getUserObj($_classRef); } $_procObj->addInitials($this); } } // get content $content = $this->getSearchboxContent(); $subpart = $this->cObj->getSubpart($content, '###SHOW_SPINNER###'); if ($this->conf['renderMethod'] == 'static') { $content = $this->cObj->substituteSubpart($content, '###SHOW_SPINNER###', ''); } else { $subpart = $this->cObj->substituteMarker($subpart, '###SPINNER###', $this->spinnerImageFilters); $content = $this->cObj->substituteSubpart($content, '###SHOW_SPINNER###', $subpart); } $content = $this->cObj->substituteMarker($content, '###LOADING###', $this->pi_getLL('loading')); // hook for additional searchbox markers if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalSearchboxContent'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['additionalSearchboxContent'] as $_classRef) { if (TYPO3_VERSION_INTEGER >= 7000000) { $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef); } else { $_procObj =& t3lib_div::getUserObj($_classRef); } $_procObj->additionalSearchboxContent($content, $this); } } return $this->pi_wrapInBaseClass($content); }
/** * The main method of the PlugIn * * @param string $content: The PlugIn content * @param array $conf: The PlugIn configuration * @return The content that is displayed on the website */ function main($content, $conf) { if (TYPO3_VERSION_INTEGER >= 7000000) { $this->ms = TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds(); } else { $this->ms = t3lib_div::milliseconds(); } $this->conf = $conf; $this->pi_setPiVarDefaults(); $this->pi_loadLL(); $this->pi_USER_INT_obj = 1; // Configuring so caching is not expected. This value means that no cHash params are ever set. We do this, because it's a USER_INT object! // initializes plugin configuration $this->init(); // init XAJAX? if ($this->conf['renderMethod'] != 'static') { if (TYPO3_VERSION_INTEGER < 6002000) { $xajaxIsLoaded = t3lib_extMgm::isLoaded('xajax'); } else { $xajaxIsLoaded = TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('xajax'); } if (!$xajaxIsLoaded) { return '<span style="color: red;"><b>ke_search error:</b>"XAJAX" must be installed for this mode.</span>'; } else { $this->initXajax(); } } // hook for initials if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'] as $_classRef) { if (TYPO3_VERSION_INTEGER >= 7000000) { $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef); } else { $_procObj =& t3lib_div::getUserObj($_classRef); } $_procObj->addInitials($this); } } // get templates $template['multiselect'] = $this->cObj->getSubpart($this->templateCode, '###SUB_FILTER_MULTISELECT###'); $template['multihidden'] = $this->cObj->getSubpart($template['multiselect'], '###SUB_FILTER_MULTISELECT_HIDDEN###'); $template['multifilter'] = $this->cObj->getSubpart($template['multiselect'], '###SUB_FILTER_MULTISELECT_FILTER###'); $template['multioption'] = $this->cObj->getSubpart($template['multifilter'], '###SUB_FILTER_MULTISELECT_OPTION###'); // get current filter $filters = $this->filters->getFilters(); foreach ($filters as $filter) { if ($filter['target_pid'] == intval($GLOBALS['TSFE']->id)) { break; } } // hook for modifying content if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyMultiselectContent'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyMultiselectContent'] as $_classRef) { if (TYPO3_VERSION_INTEGER >= 7000000) { $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef); } else { $_procObj =& t3lib_div::getUserObj($_classRef); } $content = $_procObj->modifyMultiselectContent($template['multiselect'], $filter, $this); } } if (is_array($filter) && count($filter)) { $contentOptions = ''; $optionsAmountArray = $GLOBALS['TSFE']->fe_user->getKey('ses', 'ke_search.tagsInSearchResults'); $countLoops = 1; if (is_array($this->piVars['filter'][$filter['uid']]) && count($this->piVars['filter'][$filter['uid']])) { $this->piVars['filter'][$filter['uid']] = array_unique($this->piVars['filter'][$filter['uid']]); } foreach ($filter['options'] as $optionKey => $option) { $option['title'] = htmlspecialchars($option['title']); $option['tag'] = htmlspecialchars($option['tag']); if ($optionsAmountArray[$option['tag']]) { $optionCounter = $optionsAmountArray[$option['tag']]; } else { $optionCounter = 0; } $selected = $this->piVars['filter'][$filter['uid']][$optionKey] ? 'checked="checked"' : ''; $markerArray['###ADDCLASS###'] = $countLoops % 3 ? '' : ' last'; $markerArray['###FILTERNAME###'] = 'tx_kesearch_pi1[filter][' . $filter['uid'] . ']'; $markerArray['###OPTIONID###'] = $option['uid']; $markerArray['###OPTIONKEY###'] = $optionKey; $markerArray['###OPTIONTITLE###'] = $option['title'] . ' (' . $optionCounter . ')'; $markerArray['###OPTIONTAG###'] = $option['tag']; $markerArray['###SELECTED###'] = $selected; $countLoops++; $contentOptions .= $this->cObj->substituteMarkerArray($template['multioption'], $markerArray); } $content .= $this->cObj->substituteSubpart($template['multifilter'], '###SUB_FILTER_MULTISELECT_OPTION###', $contentOptions); $content = $this->cObj->substituteMarker($content, '###TITLE###', $filter['title']); } $content = $this->cObj->substituteSubpart($template['multiselect'], '###SUB_FILTER_MULTISELECT_FILTER###', $content); $content = $this->cObj->substituteMarker($content, '###FORM_ACTION###', $this->pi_getPageLink($this->conf['resultPage'])); $content = $this->cObj->substituteMarker($content, '###SHOW_RESULTS###', $this->pi_getLL('show_results')); $content = $this->cObj->substituteMarker($content, '###LINK_BACK###', $this->cObj->typoLink($this->pi_getLL('back'), array('parameter' => $this->conf['resultPage'], 'addQueryString' => 1, 'addQueryString.' => array('exclude' => 'id')))); if (is_array($this->piVars['filter']) && count($this->piVars['filter'])) { foreach ($this->piVars['filter'] as $filterKey => $filterValue) { if ($filterKey == $filter['uid']) { continue; } foreach ($this->piVars['filter'][$filterKey] as $optionKey => $option) { $hidden .= $this->cObj->substituteMarker($template['multihidden'], '###NAME###', 'tx_kesearch_pi1[filter][' . $filterKey . '][' . $optionKey . ']'); $hidden = $this->cObj->substituteMarker($hidden, '###VALUE###', $option); } } } $content = $this->cObj->substituteSubpart($content, '###SUB_FILTER_MULTISELECT_HIDDEN###', $hidden); $content = $this->cObj->substituteMarker($content, '###PAGEID###', $this->conf['resultPage']); $content = $this->cObj->substituteMarker($content, '###SWORD###', htmlspecialchars($this->piVars['sword'])); return $this->pi_wrapInBaseClass($content); }
/** * Counts the usage of a function/class in all files related to the extension! * * @param string Function or class header, eg. "function blablabla() {" * @param array Array of files in the extension to search * @param string Absolute directory prefix for files in $extPhpFiles * @return array Count statistics in an array. */ function countFunctionUsage($functionHeader, $extPhpFiles, $extDir) { $reg = array(); $counter = array(); // Search for class/function . if (preg_match('/(class|function)[[:space:]]+([[:alnum:]_]+)[[:space:]]*/i', $functionHeader, $reg)) { $pt = t3lib_div::milliseconds(); // Reset counter array: $counter = array(); // For each file found in the extension, search for the function/class usage: foreach ($extPhpFiles as $fileName) { // File MD5 for array keys: $lFile_MD5 = 'MD5_' . t3lib_div::shortMD5($fileName); // Detect function/class: switch (strtolower($reg[1])) { case 'class': // If it's a class: $res = $this->searchFile('t3lib_div::makeinstance[[:space:]]*\\(["\']' . strtolower($reg[2]) . '["\']\\)', $fileName, $extDir); if ($res[0]) { $counter['ALL']['makeinstance'] += $res[0]; $counter['ALL']['TOTAL'] += $res[0]; $counter[$lFile_MD5]['fileName'] = $fileName; $counter[$lFile_MD5]['makeinstance'] += $res[0]; $counter[$lFile_MD5]['TOTAL'] += $res[0]; } break; case 'function': // If it's a function: // Instantiated usage: $res = $this->searchFile('->' . strtolower($reg[2]) . '[[:space:]]*\\(', $fileName, $extDir); if ($res[0]) { $counter['ALL']['objectUsage'] += $res[0]; $counter['ALL']['TOTAL'] += $res[0]; $counter[$lFile_MD5]['fileName'] = $fileName; $counter[$lFile_MD5]['objectUsage'] += $res[0]; $counter[$lFile_MD5]['TOTAL'] += $res[0]; } // Non-instantiated usage: $res = $this->searchFile('::' . strtolower($reg[2]) . '[[:space:]]*\\(', $fileName, $extDir); if ($res[0]) { $counter['ALL']['nonObjectUsage'] += $res[0]; $counter['ALL']['TOTAL'] += $res[0]; $counter[$lFile_MD5]['fileName'] = $fileName; $counter[$lFile_MD5]['nonObjectUsage'] += $res[0]; $counter[$lFile_MD5]['TOTAL'] += $res[0]; } break; } } $counter['_searchtime_milliseconds'] = t3lib_div::milliseconds() - $pt; $counter['_functionHeader'] = $functionHeader; } return $counter; }
/** * Stops Formidable and PHP execution : die() if some critical error appeared * * @param string $msg: the error message * @return void */ function mayday($msg) { if ($this->__getEnvExecMode() === "EID") { die("Formidable::Mayday\n\n" . trim(strip_tags($msg))); } $aTrace = debug_backtrace(); $aLocation = array_shift($aTrace); $aTrace1 = array_shift($aTrace); $aTrace2 = array_shift($aTrace); $aTrace3 = array_shift($aTrace); $aTrace4 = array_shift($aTrace); $aDebug = array(); $aDebug[] = "<span class='notice'><b>XML: </b> " . $this->_xmlPath . "</span>"; $aDebug[] = "<br/>"; $aDebug[] = "<span class='notice'><b>Formidable: </b>v" . $this->sApiVersion . "</span>"; $aDebug[] = "<br/>"; $aDebug[] = "<span class='notice'><b>Total exec. time: </b>" . round(t3lib_div::milliseconds() - $this->start_tstamp, 4) / 1000 . " sec</span>"; $aDebug[] = "<br/>"; $aDebug[] = "<h2 id='backtracetitle'>Call stack</h2>"; $aDebug[] = "<div class='backtrace'>"; $aDebug[] = "<span class='notice'><b>Call 0: </b>" . str_replace(PATH_site, "/", $aLocation["file"]) . ":" . $aLocation["line"] . " | <b>" . $aTrace1["class"] . $aTrace1["type"] . $aTrace1["function"] . "</b></span><br/>With parameters: " . (!empty($aTrace1["args"]) ? $this->_viewMixed($aTrace1["args"]) : " no parameters"); $aDebug[] = "<hr/>"; $aDebug[] = "<span class='notice'><b>Call -1: </b>" . str_replace(PATH_site, "/", $aTrace1["file"]) . ":" . $aTrace1["line"] . " | <b>" . $aTrace2["class"] . $aTrace2["type"] . $aTrace2["function"] . "</b></span><br />With parameters: " . (!empty($aTrace2["args"]) ? $this->_viewMixed($aTrace2["args"]) : " no parameters"); $aDebug[] = "<hr/>"; $aDebug[] = "<span class='notice'><b>Call -2: </b>" . str_replace(PATH_site, "/", $aTrace2["file"]) . ":" . $aTrace2["line"] . " | <b>" . $aTrace3["class"] . $aTrace3["type"] . $aTrace3["function"] . "</b></span><br />With parameters: " . (!empty($aTrace3["args"]) ? $this->_viewMixed($aTrace3["args"]) : " no parameters"); $aDebug[] = "<hr/>"; $aDebug[] = "<span class='notice'><b>Call -3: </b>" . str_replace(PATH_site, "/", $aTrace3["file"]) . ":" . $aTrace3["line"] . " | <b>" . $aTrace4["class"] . $aTrace4["type"] . $aTrace4["function"] . "</b></span><br />With parameters: " . (!empty($aTrace4["args"]) ? $this->_viewMixed($aTrace4["args"]) : " no parameters"); $aDebug[] = "<hr/>"; if (is_callable(array("t3lib_div", "debug_trail"))) { $aDebug[] = "<span class='notice'>" . t3lib_div::debug_trail() . "</span>"; $aDebug[] = "<hr/>"; } $aDebug[] = "</div>"; $aDebug[] = "<br/>"; $sContent = "<h1 id='title'>Formidable::Mayday</h1>"; $sContent .= "<div id='errormessage'>" . $msg . "</div>"; $sContent .= "<hr />"; $sContent .= implode("", $aDebug); //$sContent .= $this->debug(TRUE); $sPage = <<<MAYDAYPAGE <!DOCTYPE html \tPUBLIC "-//W3C//DTD XHTML 1.1//EN" \t"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> \t<head> \t\t<title>Formidable::Mayday</title> \t\t<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> \t\t<meta name="robots" content="noindex, nofollow" /> \t\t<style type="text/css"> \t\t\t#title { \t\t\t\tcolor: red; \t\t\t\tfont-family: Verdana; \t\t\t} \t\t\t#errormessage { \t\t\t\tborder: 2px solid red; \t\t\t\tpadding: 10px; \t\t\t\tcolor: white; \t\t\t\tbackground-color: red; \t\t\t\tfont-family: Verdana; \t\t\t\tfont-size: 12px; \t\t\t} \t\t\t.notice { \t\t\t\tfont-family: Verdana; \t\t\t\tfont-size: 9px; \t\t\t\tfont-style: italic; \t\t\t} \t\t\t#backtracetitle { \t\t\t} \t\t\t.backtrace { \t\t\t\tbackground-color: #FFFFCC; \t\t\t} \t\t\tHR { \t\t\t\tborder: 1px solid silver; \t\t\t} \t\t</style> \t</head> \t<body> \t\t{$sContent} \t</body> </html> MAYDAYPAGE; /* if($this->bDebug) { die($sPage); } elseif($this->bDebugIP) { $sPage = "<h4 style='color: red'>This full detail error-message is displayed because your IP(" . t3lib_div::getIndpEnv('REMOTE_ADDR') . ") matches the TYPO3 devIPMask</h4>" . $sPage; die($sPage); } elseif($GLOBALS["TSFE"]->TYPO3_CONF_VARS['FE']['pageNotFound_handling']) { $GLOBALS["TSFE"]->pageNotFoundAndExit('FORMIDABLE Mayday: ' . $msg); }*/ die($sPage); }
/** * End statistics * * @return void */ function statEnd() { $this->stat['totalTime'] = t3lib_div::milliseconds() - $this->stat['totalStartTime']; if ($this->writeDevLog) { t3lib_div::devLog('statMeta(): ' . $this->stat['totalTime'], 'tx_dam_indexing', 0, $this->stat); } }
/** * Truncates a table. * * @param string Database tablename * @return mixed Result from handler */ public function exec_TRUNCATEquery($table) { if ($this->debug) { $pt = t3lib_div::milliseconds(); } // Do table/field mapping: $ORIG_tableName = $table; if ($tableArray = $this->map_needMapping($table)) { // Table name: if ($this->mapping[$table]['mapTableName']) { $table = $this->mapping[$table]['mapTableName']; } } // Select API $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName); switch ((string) $this->handlerCfg[$this->lastHandlerKey]['type']) { case 'native': $this->lastQuery = $this->TRUNCATEquery($table); $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']); break; case 'adodb': $this->lastQuery = $this->TRUNCATEquery($table); $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery, FALSE); break; case 'userdefined': $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_TRUNCATEquery($table, $where); break; } if ($this->printErrors && $this->sql_error()) { debug(array($this->lastQuery, $this->sql_error())); } if ($this->debug) { $this->debugHandler('exec_TRUNCATEquery', t3lib_div::milliseconds() - $pt, array('handlerType' => $hType, 'args' => array($table), 'ORIG_from_table' => $ORIG_tableName)); } // Return result: return $sqlResult; }
/** * The main method of the PlugIn * * @param string $content: The PlugIn content * @param array $conf: The PlugIn configuration * @return The content that is displayed on the website */ function main($content, $conf) { if (TYPO3_VERSION_INTEGER >= 7000000) { $this->ms = TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds(); } else { $this->ms = t3lib_div::milliseconds(); } $this->conf = $conf; $this->pi_setPiVarDefaults(); $this->pi_loadLL(); $this->pi_USER_INT_obj = 1; // Configuring so caching is not expected. This value means that no cHash params are ever set. We do this, because it's a USER_INT object! // initializes plugin configuration $this->init(); if ($this->conf['resultPage'] != $GLOBALS['TSFE']->id) { $content = '<div id="textmessage">' . $this->pi_getLL('error_resultPage') . '</div>'; return $this->pi_wrapInBaseClass($content); } // init XAJAX? if ($this->conf['renderMethod'] != 'static') { if (TYPO3_VERSION_INTEGER < 6002000) { $xajaxIsLoaded = t3lib_extMgm::isLoaded('xajax'); } else { $xajaxIsLoaded = TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('xajax'); } if (!$xajaxIsLoaded) { return; } else { $this->initXajax(); } } // Spinner Image if ($this->conf['spinnerImageFile']) { $spinnerSrc = $this->conf['spinnerImageFile']; } else { if (TYPO3_VERSION_INTEGER < 6002000) { $spinnerSrc = t3lib_extMgm::siteRelPath($this->extKey) . 'res/img/spinner.gif'; } else { $spinnerSrc = TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($this->extKey) . 'res/img/spinner.gif'; } } $this->spinnerImageFilters = '<img id="kesearch_spinner_filters" src="' . $spinnerSrc . '" alt="' . $this->pi_getLL('loading') . '" />'; $this->spinnerImageResults = '<img id="kesearch_spinner_results" src="' . $spinnerSrc . '" alt="' . $this->pi_getLL('loading') . '" />'; // get javascript onclick actions $this->initOnclickActions(); // hook for initials if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'] as $_classRef) { if (TYPO3_VERSION_INTEGER >= 7000000) { $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef); } else { $_procObj =& t3lib_div::getUserObj($_classRef); } $_procObj->addInitials($this); } } $content = $this->cObj->getSubpart($this->templateCode, '###RESULT_LIST###'); // hook: modifyResultList if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyResultList'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyResultList'] as $_classRef) { if (TYPO3_VERSION_INTEGER >= 7000000) { $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef); } else { $_procObj =& t3lib_div::getUserObj($_classRef); } $_procObj->modifyResultList($content, $this); } } // show text instead of results if no searchparams set and activated in ff if ($this->isEmptySearch && $this->conf['showTextInsteadOfResults']) { // Don't replace the following with substituteMarker // this is used to be valid against JavaScript calls $content = '<div id="textmessage">' . $this->pi_RTEcssText($this->conf['textForResults']) . '</div>'; $content .= '<div id="kesearch_results"></div>'; $content .= '<div id="kesearch_updating_results"></div>'; $content .= '<div id="kesearch_pagebrowser_top"></div>'; $content .= '<div id="kesearch_pagebrowser_bottom"></div>'; $content .= '<div id="kesearch_query_time"></div>'; return $content; } if ($this->conf['renderMethod'] == 'ajax_after_reload') { $content = $this->cObj->substituteMarker($content, '###MESSAGE###', ''); $content = $this->cObj->substituteMarker($content, '###QUERY_TIME###', ''); $content = $this->cObj->substituteMarker($content, '###PAGEBROWSER_TOP###', ''); $content = $this->cObj->substituteMarker($content, '###PAGEBROWSER_BOTTOM###', ''); $content = $this->cObj->substituteMarker($content, '###NUMBER_OF_RESULTS###', ''); $content = $this->cObj->substituteMarker($content, '###ORDERING###', ''); $content = $this->cObj->substituteMarker($content, '###SPINNER###', ''); $content = $this->cObj->substituteMarker($content, '###LOADING###', ''); return $this->pi_wrapInBaseClass($content); } $content = $this->cObj->substituteMarker($content, '###MESSAGE###', $this->getSearchResults()); $content = $this->cObj->substituteMarker($content, '###NUMBER_OF_RESULTS###', sprintf($this->pi_getLL('num_results'), $this->numberOfResults)); $content = $this->cObj->substituteMarker($content, '###ORDERING###', $this->renderOrdering()); $subpart = $this->cObj->getSubpart($content, '###SHOW_SPINNER###'); if ($this->conf['renderMethod'] == 'static') { $content = $this->cObj->substituteSubpart($content, '###SHOW_SPINNER###', ''); } else { $subpart = $this->cObj->substituteMarker($subpart, '###SPINNER###', $this->spinnerImageResults); $content = $this->cObj->substituteSubpart($content, '###SHOW_SPINNER###', $subpart); } $content = $this->cObj->substituteMarker($content, '###LOADING###', $this->pi_getLL('loading')); // process query time if ($this->conf['showQueryTime']) { if (TYPO3_VERSION_INTEGER >= 7000000) { $queryTime = TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds() - $GLOBALS['TSFE']->register['ke_search_queryStartTime']; } else { $queryTime = t3lib_div::milliseconds() - $GLOBALS['TSFE']->register['ke_search_queryStartTime']; } $content = $this->cObj->substituteMarker($content, '###QUERY_TIME###', sprintf($this->pi_getLL('query_time'), $queryTime)); } else { $content = $this->cObj->substituteMarker($content, '###QUERY_TIME###', ''); } // render pagebrowser if ($GLOBALS['TSFE']->id == $this->conf['resultPage']) { if ($this->conf['pagebrowserOnTop'] || $this->conf['pagebrowserAtBottom']) { $pagebrowserContent = $this->renderPagebrowser(); } if ($this->conf['pagebrowserOnTop']) { $content = $this->cObj->substituteMarker($content, '###PAGEBROWSER_TOP###', $pagebrowserContent); } else { $content = $this->cObj->substituteMarker($content, '###PAGEBROWSER_TOP###', ''); } if ($this->conf['pagebrowserAtBottom']) { $content = $this->cObj->substituteMarker($content, '###PAGEBROWSER_BOTTOM###', $pagebrowserContent); } else { $content = $this->cObj->substituteMarker($content, '###PAGEBROWSER_BOTTOM###', ''); } } return $this->pi_wrapInBaseClass($content); }
/** * jesus.TIF: IBM/LZW * jesus.GIF: Save for web, 32 colors * jesus.JPG: Save for web, 30 quality * jesus.PNG: Save for web, PNG-24 * jesus.tga 24 bit TGA file * jesus.pcx * jesus.bmp 24 bit BMP file * jesus_ps6.PDF: PDF w/layers and vector data * typo3logo.ai: Illustrator 8 file * pdf_from_imagemagick.PDF PDF-file made by Acrobat Distiller from InDesign PS-file * * * Imagemagick * - Read formats * - Write png, gif, jpg * * Problems may arise from the use of safe_mode (eg. png) * In safemode you will automatically execute the program convert in the safe_mode_exec_path no matter what other path you specify * check fileexist before anything... * * - compare gif size * - scaling (by stdgraphic) * - combining (by stdgraphic) * * GDlib: * - create from:.... * - ttf text * * From TypoScript: (GD only, GD+IM, IM) * * @return void */ function checkTheImageProcessing() { $this->message('Image Processing', 'What is it?', ' <p> TYPO3 is known for its ability to process images on the server. <br /> In the backend interface (TBE) thumbnails are automatically generated (by ImageMagick in thumbs.php) as well as icons, menu items and pane tabs (by GDLib). <br /> In the TypoScript enabled frontend all kinds of graphical elements are processed. Typically images are scaled down to fit the pages (by ImageMagick) and menu items, graphical headers and such are generated automatically (by GDLib + ImageMagick). <br /> In addition TYPO3 is able to handle many file formats (thanks to ImageMagick), for example TIF, BMP, PCX, TGA, AI and PDF in addition to the standard web formats; JPG, GIF, PNG. </p> <p> In order to do this, TYPO3 uses two sets of tools: </p> <p> <strong>ImageMagick:</strong> <br /> For conversion of non-web formats to webformats, combining images with alpha-masks, performing image-effects like blurring and sharpening. <br /> ImageMagick is a collection of external programs on the server called by the exec() function in PHP. TYPO3 uses three of these, namely \'convert\' (converting fileformats, scaling, effects), \'combine\'/\'composite\' (combining images with masks) and \'identify\' (returns image information). <br /> Because ImageMagick are external programs, two requirements must be met: 1) The programs must be installed on the server and working and 2) if safe_mode is enabled, the programs must be located in the folder defined by the php.ini setting, <em>safe_mode_exec_dir</em> (else they are not executed). <br /> ImageMagick is available for both Windows and Unix. The current version is 5+, but TYPO3 enthusiasts prefer an old version 4.2.9 because that version has three main advantages: It\'s faster in some operations, the blur-function works, the sharpen-function works. Anyway you do it, you must tell TYPO3 by configuration whether you\'re using version 5+ or 4.2.9. (flag: [GFX][im_version_5]) <br /> ImageMagick homepage is at <a href="http://www.imagemagick.org/">http://www.imagemagick.org/</a> </p> <p> <strong>GDLib:</strong> <br /> For drawing boxes and rendering text on images with truetype fonts. Also used for icons, menuitems and generally the TypoScript GIFBUILDER object is based on GDlib, but extensively utilizing ImageMagick to process intermediate results. <br /> GDLib is accessed through internal functions in PHP, so in this case, you have no safe_mode problems, but you\'ll need a version of PHP with GDLib compiled in. Also in order to use TrueType fonts with GDLib you\'ll need FreeType compiled in as well. <br /> </p> ' . $this->getGDSoftwareInfo() . ' <p> You can disable all image processing options in TYPO3 ([GFX][image_processing]=0), but that would seriously disable TYPO3. </p> '); $this->message('Image Processing', 'Verifying the image processing capabilities of your server', ' <p> This page performs image processing and displays the result. It\'s a thorough check that everything you\'ve configured is working correctly. <br /> It\'s quite simple to verify your installation; Just look down the page, the images in pairs should look like each other. If some images are not alike, something is wrong. You may also notice warnings and errors if this tool found signs of any problems. </p> <p> The image to the right is the reference image (how it should be) and to the left the image made by your server. <br /> The reference images are made with the classic ImageMagick install based on the 4.2.9 RPM and 5.2.3 RPM. If the version 5 flag is set, the reference images are made by the 5.2.3 RPM. </p> <p> This test will work only if your ImageMagick/GDLib configuration allows it to. The typo3temp/ folder must be writable for all the temporary image files. They are all prefixed \'install_\' so they are easy to recognize and delete afterwards. </p> '); $im_path = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']; if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] == 'gm') { $im_path_version = $this->config_array['im_versions'][$im_path]['gm']; } else { $im_path_version = $this->config_array['im_versions'][$im_path]['convert']; } $im_path_lzw = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']; $im_path_lzw_version = $this->config_array['im_versions'][$im_path_lzw]['convert']; $msg = ' <dl id="t3-install-imageprocessingim"> <dt> ImageMagick enabled: </dt> <dd> ' . $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] . ' </dd> <dt> ImageMagick path: </dt> <dd> ' . $im_path . ' <span>(' . $im_path_version . ')</span> </dd> <dt> ImageMagick path/LZW: </dt> <dd> ' . $im_path_lzw . ' <span>(' . $im_path_lzw_version . ')</span> </dd> <dt> Version 5/GraphicsMagick flag: </dt> <dd> ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] : ' ') . ' </dd> </dl> <dl id="t3-install-imageprocessingother"> <dt> GDLib enabled: </dt> <dd> ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] : ' ') . ' </dd> <dt> GDLib using PNG: </dt> <dd> ' . ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] : ' ') . ' </dd> <dt> IM5 effects enabled: </dt> <dd> ' . $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_v5effects'] . ' <span>(Blurring/Sharpening with IM 5+)</span> </dd> <dt> Freetype DPI: </dt> <dd> ' . $GLOBALS['TYPO3_CONF_VARS']['GFX']['TTFdpi'] . ' <span>(Should be 96 for Freetype 2)</span> </dd> <dt> Mask invert: </dt> <dd> ' . $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_imvMaskState'] . ' <span>(Should be set for some IM versions approx. 5.4+)</span> </dd> </dl> <dl id="t3-install-imageprocessingfileformats"> <dt> File Formats: </dt> <dd> ' . $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] . ' </dd> </dl> '; // Various checks to detect IM/GM version mismatches $mismatch = false; switch (strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'])) { case 'gm': if (doubleval($im_path_version) >= 2) { $mismatch = true; } break; case 'im4': if (doubleval($im_path_version) >= 5) { $mismatch = true; } break; default: if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] ? true : false) != doubleval($im_path_version) >= 5) { $mismatch = true; } break; } if ($mismatch) { $msg .= ' <p> Warning: Mismatch between the version of ImageMagick' . ' (' . $im_path_version . ') and the configuration of ' . '[GFX][im_version_5] (' . $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] . ') </p> '; $etype = 2; } else { $etype = 1; } if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5'] == 'gm') { $msg = str_replace('ImageMagick', 'GraphicsMagick', $msg); } $this->message('Image Processing', 'Current configuration', $msg, $etype); if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['image_processing']) { $this->message('Image Processing', 'Image Processing disabled!', ' <p> Image Processing is disabled by the config flag [GFX][image_processing] set to false (zero) </p> ', 2); $this->output($this->outputWrapper($this->printAll())); return; } if (!$this->config_array['dir_typo3temp']) { $this->message('Image Processing', 'typo3temp/ not writable!', ' <p> You must make typo3temp/ write enabled before you can proceed with this test. </p> ', 2); $this->output($this->outputWrapper($this->printAll())); return; } $msg = ' <p> <a id="testmenu"></a> Click each of these links in turn to test a topic. <strong> Please be aware that each test may take several seconds! </strong>: </p> ' . $this->imagemenu(); $this->message('Image Processing', 'Testmenu', $msg, ''); $parseStart = t3lib_div::milliseconds(); $imageProc = t3lib_div::makeInstance('t3lib_stdGraphic'); $imageProc->init(); $imageProc->tempPath = $this->typo3temp_path; $imageProc->dontCheckForExistingTempFile = 1; // $imageProc->filenamePrefix='install_'.($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_version_5']?"v5":""); $imageProc->filenamePrefix = 'install_'; $imageProc->dontCompress = 1; $imageProc->alternativeOutputKey = 'TYPO3_INSTALL_SCRIPT'; $imageProc->noFramePrepended = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noFramePrepended']; // Very temporary!!! $imageProc->dontUnlinkTempFiles = 0; $imActive = $this->config_array['im'] && $im_path; $gdActive = $this->config_array['gd'] && $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib']; switch ($this->INSTALL['images_type']) { case 'read': $refParseTime = '5600'; // 4.2.9 $refParseTime = '3300'; // 5.2.3 $headCode = 'Reading and converting images'; $this->message($headCode, 'Supported file formats', ' <p> This verifies that your ImageMagick installation is able to read the nine default file formats; JPG, GIF, PNG, TIF, BMP, PCX, TGA, PDF, AI. The tool \'identify\' will be used to read the pixeldimensions of non-web formats. The tool \'convert\' is used to read the image and write a temporary JPG-file </p> '); if ($imActive) { // Reading formats - writing JPG $extArr = explode(',', 'jpg,gif,png,tif,bmp,pcx,tga'); foreach ($extArr as $ext) { if ($this->isExtensionEnabled($ext, $headCode, "Read " . strtoupper($ext))) { $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/jesus.' . $ext; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'read_' . $ext; $fileInfo = $imageProc->imageMagickConvert($theFile, 'jpg', "", '', "", '', "", 1); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, "Read " . strtoupper($ext), $result[0], $result[1]); } } if ($this->isExtensionEnabled('pdf', $headCode, 'Read PDF')) { $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/pdf_from_imagemagick.pdf'; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'read_pdf'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'jpg', "170", '', "", '', "", 1); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Read PDF', $result[0], $result[1]); } if ($this->isExtensionEnabled('ai', $headCode, 'Read AI')) { $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/typo3logotype.ai'; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'read_ai'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'jpg', "170", '', "", '', "", 1); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Read AI', $result[0], $result[1]); } } else { $this->message($headCode, 'Test skipped', ' <p> Use of ImageMagick has been disabled in the configuration. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } break; case 'write': $refParseTime = '300'; // Writingformats - writing JPG $headCode = 'Writing images'; $this->message($headCode, 'Writing GIF and PNG', ' <p> This verifies that ImageMagick is able to write GIF and PNG files. <br /> The GIF-file is attempted compressed with LZW by the t3lib_div::gif_compress() function. </p> '); if ($imActive) { // Writing GIF $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/jesus.gif'; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'write_gif'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'gif', "", '', "", '', "", 1); if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) { clearstatcache(); $prevSize = t3lib_div::formatSize(@filesize($fileInfo[3])); $returnCode = t3lib_div::gif_compress($fileInfo[3], ''); clearstatcache(); $curSize = t3lib_div::formatSize(@filesize($fileInfo[3])); $note = array('Note on gif_compress() function:', "The 'gif_compress' method used was '" . $returnCode . "'.<br />Previous filesize: " . $prevSize . '. Current filesize:' . $curSize); } else { $note = array('Note on gif_compress() function:', '<em>Not used! Disabled by [GFX][gif_compress]</em>'); } $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands, $note); $this->message($headCode, 'Write GIF', $result[0], $result[1]); // Writing PNG $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/jesus.gif'; $imageProc->imageMagickConvert_forceFileNameBody = 'write_png'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'png', "", '', "", '', "", 1); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Write PNG', $result[0], $result[1]); } else { $this->message($headCode, 'Test skipped', ' <p> Use of ImageMagick has been disabled in the configuration. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } break; case 'scaling': $refParseTime = '650'; // Scaling $headCode = 'Scaling images'; $this->message($headCode, 'Scaling transparent images', ' <p> This shows how ImageMagick reacts when scaling transparent GIF and PNG files. </p> '); if ($imActive) { // Scaling transparent image $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/jesus2_transp.gif'; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'scale_gif'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'gif', "150", '', "", '', "", 1); if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) { clearstatcache(); $prevSize = t3lib_div::formatSize(@filesize($fileInfo[3])); $returnCode = t3lib_div::gif_compress($fileInfo[3], ''); clearstatcache(); $curSize = t3lib_div::formatSize(@filesize($fileInfo[3])); $note = array('Note on gif_compress() function:', "The 'gif_compress' method used was '" . $returnCode . "'.<br />Previous filesize: " . $prevSize . '. Current filesize:' . $curSize); } else { $note = array('Note on gif_compress() function:', '<em>Not used! Disabled by [GFX][gif_compress]</em>'); } $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands, $note); $this->message($headCode, 'GIF to GIF, 150 pixels wide', $result[0], $result[1]); $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/jesus2_transp.png'; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'scale_png'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'png', "150", '', "", '', "", 1); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'PNG to PNG, 150 pixels wide', $result[0], $result[1]); $imageProc->IM_commands = array(); $theFile = t3lib_extMgm::extPath('install') . 'imgs/jesus2_transp.gif'; if (!@is_file($theFile)) { die('Error: ' . $theFile . ' was not a file'); } $imageProc->imageMagickConvert_forceFileNameBody = 'scale_jpg'; $fileInfo = $imageProc->imageMagickConvert($theFile, 'jpg', "150", '', "", '', "", 1); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'GIF to JPG, 150 pixels wide', $result[0], $result[1]); } else { $this->message($headCode, 'Test skipped', ' <p> Use of ImageMagick has been disabled in the configuration. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } break; case 'combining': $refParseTime = '150'; // 4.2.9 $refParseTime = '250'; // 5.2.3 // Combine $headCode = 'Combining images'; $this->message($headCode, 'Combining images', ' <p> This verifies that the ImageMagick tool, \'combine\'/\'composite\', is able to combine two images through a grayscale mask. <br /> If the masking seems to work but inverted, that just means you\'ll have to make sure the invert flag is set (some combination of im_negate_mask/im_imvMaskState) </p> '); if ($imActive) { $imageProc->IM_commands = array(); $input = t3lib_extMgm::extPath('install') . 'imgs/greenback.gif'; $overlay = t3lib_extMgm::extPath('install') . 'imgs/jesus.jpg'; $mask = t3lib_extMgm::extPath('install') . 'imgs/blackwhite_mask.gif'; if (!@is_file($input)) { die('Error: ' . $input . ' was not a file'); } if (!@is_file($overlay)) { die('Error: ' . $overlay . ' was not a file'); } if (!@is_file($mask)) { die('Error: ' . $mask . ' was not a file'); } $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5($imageProc->alternativeOutputKey . 'combine1') . '.jpg'; $imageProc->combineExec($input, $overlay, $mask, $output, true); $fileInfo = $imageProc->getImageDimensions($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Combine using a GIF mask with only black and white', $result[0], $result[1]); // Combine $imageProc->IM_commands = array(); $input = t3lib_extMgm::extPath('install') . 'imgs/combine_back.jpg'; $overlay = t3lib_extMgm::extPath('install') . 'imgs/jesus.jpg'; $mask = t3lib_extMgm::extPath('install') . 'imgs/combine_mask.jpg'; if (!@is_file($input)) { die('Error: ' . $input . ' was not a file'); } if (!@is_file($overlay)) { die('Error: ' . $overlay . ' was not a file'); } if (!@is_file($mask)) { die('Error: ' . $mask . ' was not a file'); } $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5($imageProc->alternativeOutputKey . 'combine2') . '.jpg'; $imageProc->combineExec($input, $overlay, $mask, $output, true); $fileInfo = $imageProc->getImageDimensions($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Combine using a JPG mask with graylevels', $result[0], $result[1]); } else { $this->message($headCode, 'Test skipped', ' <p> Use of ImageMagick has been disabled in the configuration. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } break; case 'gdlib': // GIF / 4.2.9 / LZW (5.2.3) $refParseTime = '1800'; // PNG / 4.2.9 / LZW (5.2.3) $refParseTime = '2700'; // GIF / 5.2.3 / LZW (5.2.3) $refParseTime = '1600'; // GDLibrary $headCode = 'GDLib'; $this->message($headCode, 'Testing GDLib', ' <p> This verifies that the GDLib installation works properly. </p> '); if ($gdActive) { // GD with box $imageProc->IM_commands = array(); $im = imagecreatetruecolor(170, 136); $Bcolor = ImageColorAllocate($im, 0, 0, 0); ImageFilledRectangle($im, 0, 0, 170, 136, $Bcolor); $workArea = array(0, 0, 170, 136); $conf = array('dimensions' => '10,50,150,36', 'color' => 'olive'); $imageProc->makeBox($im, $conf, $workArea); $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5('GDbox') . '.' . $imageProc->gifExtension; $imageProc->ImageWrite($im, $output); $fileInfo = $imageProc->getImageDimensions($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Create simple image', $result[0], $result[1]); // GD from image with box $imageProc->IM_commands = array(); $input = t3lib_extMgm::extPath('install') . 'imgs/jesus.' . $imageProc->gifExtension; if (!@is_file($input)) { die('Error: ' . $input . ' was not a file'); } $im = $imageProc->imageCreateFromFile($input); $workArea = array(0, 0, 170, 136); $conf = array(); $conf['dimensions'] = '10,50,150,36'; $conf['color'] = 'olive'; $imageProc->makeBox($im, $conf, $workArea); $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5('GDfromImage+box') . '.' . $imageProc->gifExtension; $imageProc->ImageWrite($im, $output); $fileInfo = $imageProc->getImageDimensions($output); $GDWithBox_filesize = @filesize($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Create image from file', $result[0], $result[1]); // GD with text $imageProc->IM_commands = array(); $im = imagecreatetruecolor(170, 136); $Bcolor = ImageColorAllocate($im, 128, 128, 150); ImageFilledRectangle($im, 0, 0, 170, 136, $Bcolor); $workArea = array(0, 0, 170, 136); $conf = array('iterations' => 1, 'angle' => 0, 'antiAlias' => 1, 'text' => 'HELLO WORLD', 'fontColor' => '#003366', 'fontSize' => 18, 'fontFile' => $this->backPath . '../t3lib/fonts/vera.ttf', 'offset' => '17,40'); $conf['BBOX'] = $imageProc->calcBBox($conf); $imageProc->makeText($im, $conf, $workArea); $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5('GDwithText') . '.' . $imageProc->gifExtension; $imageProc->ImageWrite($im, $output); $fileInfo = $imageProc->getImageDimensions($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands); $this->message($headCode, 'Render text with TrueType font', $result[0], $result[1]); if ($imActive) { // extension: GD with text, niceText $conf['offset'] = '17,65'; $conf['niceText'] = 1; $imageProc->makeText($im, $conf, $workArea); $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5('GDwithText-niceText') . '.' . $imageProc->gifExtension; $imageProc->ImageWrite($im, $output); $fileInfo = $imageProc->getImageDimensions($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands, array("Note on 'niceText':", "'niceText' is a concept that tries to improve the antialiasing of the rendered type by actually rendering the textstring in double size on a black/white mask, downscaling the mask and masking the text onto the image through this mask. This involves ImageMagick 'combine'/'composite' and 'convert'.")); $this->message($headCode, 'Render text with TrueType font using \'niceText\' option', ' <p> (If the image has another background color than the image above (eg. dark background color with light text) then you will have to set TYPO3_CONF_VARS[GFX][im_imvMaskState]=1) </p> ' . $result[0], $result[1]); } else { $this->message($headCode, 'Render text with TrueType font using \'niceText\' option', ' <p> <strong>Test is skipped!</strong> </p> <p> Use of ImageMagick has been disabled in the configuration. ImageMagick is needed to generate text with the niceText option. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } if ($imActive) { // extension: GD with text, niceText AND shadow $conf['offset'] = '17,90'; $conf['niceText'] = 1; $conf['shadow.'] = array('offset' => '2,2', 'blur' => $imageProc->V5_EFFECTS ? "20" : "90", 'opacity' => '50', 'color' => 'black'); $imageProc->makeShadow($im, $conf['shadow.'], $workArea, $conf); $imageProc->makeText($im, $conf, $workArea); $output = $imageProc->tempPath . $imageProc->filenamePrefix . t3lib_div::shortMD5('GDwithText-niceText-shadow') . '.' . $imageProc->gifExtension; $imageProc->ImageWrite($im, $output); $fileInfo = $imageProc->getImageDimensions($output); $result = $this->displayTwinImage($fileInfo[3], $imageProc->IM_commands, array('Note on drop shadows:', 'Drop shadows are done by using ImageMagick to blur a mask through which the drop shadow is generated. The blurring of the mask only works in ImageMagick 4.2.9 and <em>not</em> ImageMagick 5 - which is why you may see a hard and not soft shadow.')); $this->message($headCode, 'Render \'niceText\' with a shadow under', ' <p> (This test makes sense only if the above test had a correct output. But if so, you may not see a soft dropshadow from the third text string as you should. In that case you are most likely using ImageMagick 5 and should set the flag TYPO3_CONF_VARS[GFX][im_v5effects]. However this may cost server performance! </p> ' . $result[0], $result[1]); } else { $this->message($headCode, 'Render \'niceText\' with a shadow under', ' <p> <strong>Test is skipped!</strong> </p> <p> Use of ImageMagick has been disabled in the configuration. ImageMagick is needed to generate shadows. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } if ($imageProc->gifExtension == 'gif') { $buffer = 20; $assess = "This assessment is based on the filesize from 'Create image from file' test, which were " . $GDWithBox_filesize . ' bytes'; $goodNews = "If the image was LZW compressed you would expect to have a size of less than 9000 bytes. If you open the image with Photoshop and saves it from Photoshop, you'll a filesize like that.<br />The good news is (hopefully) that your [GFX][im_path_lzw] path is correctly set so the gif_compress() function will take care of the compression for you!"; if ($GDWithBox_filesize < 8784 + $buffer) { $msg = ' <p> <strong> Your GDLib appears to have LZW compression! </strong> <br /> This assessment is based on the filesize from \'Create image from file\' test, which were ' . $GDWithBox_filesize . ' bytes. <br /> This is a real advantage for you because you don\'t need to use ImageMagick for LZW compressing. In order to make sure that GDLib is used, <strong> please set the config option [GFX][im_path_lzw] to an empty string! </strong> <br /> When you disable the use of ImageMagick for LZW compressing, you\'ll see that the gif_compress() function has a return code of \'GD\' (for GDLib) instead of \'IM\' (for ImageMagick) </p> '; } elseif ($GDWithBox_filesize > 19000) { $msg = ' <p> <strong> Your GDLib appears to have no compression at all! </strong> <br /> ' . $assess . ' <br /> ' . $goodNews . ' </p> '; } else { $msg = ' <p> Your GDLib appears to have RLE compression <br /> ' . $assess . ' <br /> ' . $goodNews . ' </p> '; } $this->message($headCode, 'GIF compressing in GDLib', "\n\t\t\t\t\t\t" . $msg . "\n\t\t\t\t\t\t", 1); } } else { $this->message($headCode, 'Test skipped', ' <p> Use of GDLib has been disabled in the configuration. <br /> Refer to section \'Basic Configuration\' to change or review you configuration settings </p> ', 2); } break; } if ($this->INSTALL['images_type']) { // End info if ($this->fatalError) { $this->message('Info', 'Errors', ' <p> It seems that you had some fatal errors in this test. Please make sure that your ImageMagick and GDLib settings are correct. Refer to the \'Basic Configuration\' section for more information and debugging of your settings. </p> '); } $parseMS = t3lib_div::milliseconds() - $parseStart; $this->message('Info', 'Parsetime', ' <p> ' . $parseMS . ' ms </p> '); } $this->output($this->outputWrapper($this->printAll())); }