/** * Migrate tt_news_categorymounts to category_pems in either be_groups or be_users * * @param string $table either be_groups or be_users */ public function migrateTtNewsCategoryMountsToSysCategoryPerms($table) { /** @var \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler */ $dataHandler = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler'); $dataHandler->admin = TRUE; /* assign imported categories to be_groups or be_users */ $whereClause = 'tt_news_categorymounts != \'\'' . BackendUtility::deleteClause($table); $beGroupsOrUsersWithTtNewsCategorymounts = $this->databaseConnection->exec_SELECTgetRows('*', $table, $whereClause); $data = array(); foreach ((array) $beGroupsOrUsersWithTtNewsCategorymounts as $beGroupOrUser) { $ttNewsCategoryPermissions = GeneralUtility::trimExplode(',', $beGroupOrUser['tt_news_categorymounts']); $sysCategoryPermissions = array(); foreach ($ttNewsCategoryPermissions as $ttNewsCategoryPermissionUid) { $whereClause = 'import_source = \'TT_NEWS_CATEGORY_IMPORT\' AND import_id = ' . $ttNewsCategoryPermissionUid; $sysCategory = $this->databaseConnection->exec_SELECTgetSingleRow('uid', 'sys_category', $whereClause); if (!empty($sysCategory)) { $sysCategoryPermissions[] = $sysCategory['uid']; } } if (count($sysCategoryPermissions)) { $data[$table][$beGroupOrUser['uid']] = array('category_perms' => implode(',', $sysCategoryPermissions) . ',' . $beGroupOrUser['category_perms']); } } $dataHandler->start($data, array()); $dataHandler->process_datamap(); }
/** * @param \S3b0\ProjectRegistration\Scheduler\InfoMail\Task $task * * @return bool */ public function run(\S3b0\ProjectRegistration\Scheduler\InfoMail\Task $task) { $settings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$this->extensionName]); $upperLimit = new \DateTime(); $lowerLimit = new \DateTime(); $daysLeft = $settings['warnXDaysBeforeExpireDate']; $sender = [$task->getSenderAddress()]; $receiver = [$task->getReceiverAddress()]; $subject = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('infomail.subject', $this->extensionName); $this->databaseConnection = $GLOBALS['TYPO3_DB']; // Upper limit (expiry) = Current date + Days left $upperLimit->setTimestamp($upperLimit->getTimestamp() + $daysLeft * 86400); // Lower limit (expiry) = Current date + Days left - Scheduler frequency $lowerLimit->setTimestamp($lowerLimit->getTimestamp() + $daysLeft * 86400 - $task->getExecution()->getInterval()); $where = "date_of_expiry > '{$lowerLimit->format('Y-m-d h:i:s')}' AND date_of_expiry < '{$upperLimit->format('Y-m-d h:i:s')}'"; if ($this->databaseConnection->exec_SELECTcountRows('*', 'tx_projectregistration_domain_model_project', $where)) { $expiredProjects = $this->databaseConnection->exec_SELECTgetRows('project.*, registrant.name as registrant_name, registrant.company as registrant_company', 'tx_projectregistration_domain_model_project as project join tx_projectregistration_domain_model_person as registrant on project.registrant=registrant.uid', $where); $list = []; /** @var array $expiredProject */ foreach ($expiredProjects as $expiredProject) { $list[] = "#{$expiredProject['uid']} - '{$expiredProject['title']}' by {$expiredProject['registrant_name']} ({$expiredProject['registrant_company']})"; } $mailContent = \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('infomail.message', $this->extensionName, [$daysLeft, '<li>' . implode('</li><li>', $list) . '</li>']); /** @var \TYPO3\CMS\Core\Mail\MailMessage $mail */ $mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class); $mail->setContentType('text/html'); /** * Email to sender */ $mail->setFrom($sender)->setTo($receiver)->setPriority(1)->setSubject($subject)->setBody($mailContent)->send(); } return true; }
/** * @test */ public function storedGzipCompressedDataReturnsSameData() { $testStringWithBinary = @gzcompress('sdfkljer4587'); $this->fixture->exec_INSERTquery($this->testTable, array('fieldblob' => $testStringWithBinary)); $id = $this->fixture->sql_insert_id(); $entry = $this->fixture->exec_SELECTgetRows('fieldblob', $this->testTable, 'id = ' . $id); $this->assertEquals($testStringWithBinary, $entry[0]['fieldblob']); }
/** * @test */ public function addDataSetsPageLanguageOverlayRows() { $input = ['effectivePid' => '23']; $expected = $input; $expected['pageLanguageOverlayRows'] = [0 => ['uid' => '1', 'pid' => '42', 'sys_language_uid' => '2']]; $this->dbProphecy->exec_SELECTgetRows('*', 'pages_language_overlay', 'pid=23')->shouldBeCalled()->willReturn($expected['pageLanguageOverlayRows']); $this->assertSame($expected, $this->subject->addData($input)); }
private function getImageRecordsOfFeedImport($feedImport) { $imageRows = $this->db->exec_SELECTgetRows('*', 'tx_gorillary_images', "deleted=0 AND feedimport='" . $feedImport['uid'] . "' AND pid='" . $feedImport['pid'] . "'"); $imgArray = array(); foreach ($imageRows as $imgRow) { $imgArray[$imgRow['image']] = $imgRow; } return $imgArray; }
private function getImageRecordsOfCollection($collection) { $imageRows = $this->db->exec_SELECTgetRows('*', 'tx_gorillary_images', "deleted=0 AND collection='" . $collection['uid'] . "' AND pid='" . $collection['pid'] . "'"); $imgArray = array(); foreach ($imageRows as $imgRow) { $imgArray[$imgRow['image']] = $imgRow; } return $imgArray; }
/** * Performs the database update. * * @param array &$dbQueries Queries done in this update * @param mixed &$customMessages Custom messages * @return boolean TRUE on success, FALSE on error */ public function performUpdate(array &$dbQueries, &$customMessages) { $this->flexObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\FlexForm\\FlexFormTools'); $outdatedContentElements = $this->db->exec_SELECTgetRows('*', 'tt_content', $this->flexFormWhere); foreach ($outdatedContentElements as $outdatedContent) { $this->updateOutdatedContentFlexForm($outdatedContent, $dbQueries); } return TRUE; }
/** * The actual update function. Add your update task in here. * * @return void */ protected function processUpdates() { // Do the magic! $transferData = $this->databaseConnection->exec_SELECTgetRows('*', $this->transferTable, '1=1'); if ($transferData && sizeof($transferData)) { $this->truncateTables(); $this->addInitialStaticData(); $this->transferData($transferData); } }
/** * add cities to selectbox. * * @param array $parentArray * @param \TYPO3\CMS\Backend\Form\FormEngine $fObj */ public function addCityItems(array $parentArray, \TYPO3\CMS\Backend\Form\FormEngine $fObj) { $this->init(); $rows = $this->database->exec_SELECTgetRows('city', 'tx_clubdirectory_domain_model_address', '1=1 ' . BackendUtility::BEenableFields('tx_clubdirectory_domain_model_address') . BackendUtility::deleteClause('tx_clubdirectory_domain_model_address'), 'city', 'city', ''); foreach ($rows as $row) { $item = array(); $item[0] = $row['city']; $item[1] = $row['city']; $item[2] = null; $parentArray['items'][] = $item; } }
/** * Get a user from DB by social identifier * * @param string $identifier social identifier * @param string $extraWhere Additional WHERE clause: " AND ... * @param array $dbUserSetup User db table definition: $this->db_user * @return mixed User array or FALSE */ public function fetchUserRecordByIdentifier($identifier, $extraWhere = '', $dbUserSetup = '') { $result = FALSE; $identityClassName = 'Portrino\\PxHybridAuth\\Domain\\Model\\Identity\\' . ucfirst($this->getServiceProvider()) . 'Identity'; if (class_exists($identityClassName) && defined($identityClassName . '::EXTBASE_TYPE')) { $extbaseType = constant($identityClassName . '::EXTBASE_TYPE'); $identityClause = 'deleted=0 AND hidden=0 AND identifier=' . $this->db->fullQuoteStr($identifier, 'tx_pxhybridauth_domain_model_identity') . ' AND ' . 'tx_extbase_type=' . $this->db->fullQuoteStr($extbaseType, 'tx_pxhybridauth_domain_model_identity'); $socialIdentities = $this->db->exec_SELECTgetRows('*', 'tx_pxhybridauth_domain_model_identity', $identityClause); foreach ($socialIdentities as $socialIdentity) { if (isset($socialIdentity['fe_user'])) { $dbUser = is_array($dbUserSetup) ? $dbUserSetup : $this->db_user; // Look up the user by the username and/or extraWhere: $dbres = $this->db->exec_SELECTquery('*', $dbUser['table'], 'uid' . '=' . $this->db->fullQuoteStr($socialIdentity['fe_user'], $dbUser['table']) . $this->db->fullQuoteStr($dbUser['check_pid_clause'], $dbUser['table']) . $dbUser['enable_clause'] . $extraWhere); if ($dbres) { $result = $this->db->sql_fetch_assoc($dbres); $this->db->sql_free_result($dbres); if ($result) { break; } } } } } return $result; }
/** * Fetches the rows directly from the database, not using prepared statement * * @param array $statementParts * @return array the result */ protected function getRowsFromDatabase(array $statementParts) { $queryCommandParameters = $this->createQueryCommandParametersFromStatementParts($statementParts); $rows = $this->databaseHandle->exec_SELECTgetRows($queryCommandParameters['selectFields'], $queryCommandParameters['fromTable'], $queryCommandParameters['whereClause'], '', $queryCommandParameters['orderBy'], $queryCommandParameters['limit']); $this->checkSqlErrors(); return $rows; }
/** * Removes active orphan processes from process list * * @return void */ private function removeActiveOrphanProcesses() { $results = $this->db->exec_SELECTgetRows('process_id, system_process_id', 'tx_crawler_process', 'ttl <= ' . intval(time() - $this->extensionSettings['processMaxRunTime']) . ' AND active = 1'); if (!is_array($results)) { return; } foreach ($results as $result) { $processExists = FALSE; $systemProcessId = (int) $result['system_process_id']; $processId = $result['process_id']; if ($systemProcessId > 1) { $dispatcherProcesses = $this->findDispatcherProcesses(); if (!is_array($dispatcherProcesses) || empty($dispatcherProcesses)) { $this->removeProcessFromProcesslist($processId); return; } foreach ($dispatcherProcesses as $process) { $responseArray = $this->createResponseArray($process); if ($systemProcessId === (int) $responseArray[1]) { $processExists = TRUE; } } if (!$processExists) { $this->removeProcessFromProcesslist($processId); } } } }
/** * Make store control * * @return string */ public function makeStoreControl() { // Load/Save $storeArray = $this->initStoreArray(); $opt = array(); foreach ($storeArray as $k => $v) { $opt[] = '<option value="' . $k . '">' . htmlspecialchars($v) . '</option>'; } // Actions: if (ExtensionManagementUtility::isLoaded('sys_action') && $this->backendUserAuthentication->isAdmin()) { $rows = $this->databaseConnection->exec_SELECTgetRows('*', 'sys_action', 'type=2', '', 'title'); $opt[] = '<option value="0">__Save to Action:__</option>'; foreach ($rows as $row) { $opt[] = '<option value="-' . (int) $row['uid'] . '">' . htmlspecialchars($row['title'] . ' [' . (int) $row['uid'] . ']') . '</option>'; } } $markup = []; $markup[] = '<div class="load-queries">'; $markup[] = ' <div class="form-inline">'; $markup[] = ' <div class="form-group">'; $markup[] = ' <select class="form-control" name="storeControl[STORE]" onChange="document.forms[0]' . '[\'storeControl[title]\'].value= this.options[this.selectedIndex].value!=0 ' . '? this.options[this.selectedIndex].text : \'\';">' . implode(LF, $opt) . '</select>'; $markup[] = ' <input class="form-control" name="storeControl[title]" value="" type="text" max="80">'; $markup[] = ' <input class="btn btn-default" type="submit" name="storeControl[LOAD]" value="Load">'; $markup[] = ' <input class="btn btn-default" type="submit" name="storeControl[SAVE]" value="Save">'; $markup[] = ' <input class="btn btn-default" type="submit" name="storeControl[REMOVE]" value="Remove">'; $markup[] = ' </div>'; $markup[] = ' </div>'; $markup[] = '</div>'; return implode(LF, $markup); }
/** * Creates file identifier hashes for a single storage. * * @param ResourceStorage $storage The storage to update * @return array The executed database queries */ protected function updateIdentifierHashesForStorage(ResourceStorage $storage) { $queries = array(); if (!ExtensionManagementUtility::isLoaded('dbal')) { // if DBAL is not loaded, we're using MySQL and can thus use their // SHA1() function if ($storage->usesCaseSensitiveIdentifiers()) { $updateCall = 'SHA1(identifier)'; } else { $updateCall = 'SHA1(LOWER(identifier))'; } $queries[] = $query = sprintf('UPDATE sys_file SET identifier_hash = %s WHERE storage=%d', $updateCall, $storage->getUid()); $this->db->sql_query($query); // folder hashes cannot be done with one call: so do it manually $files = $this->db->exec_SELECTgetRows('uid, storage, identifier', 'sys_file', sprintf('storage=%d AND folder_hash=""', $storage->getUid())); foreach ($files as $file) { $folderHash = $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file['identifier'])); $queries[] = $query = $this->db->UPDATEquery('sys_file', 'uid=' . $file['uid'], array('folder_hash' => $folderHash)); $this->db->sql_query($query); } } else { // manually hash the identifiers when using DBAL $files = $this->db->exec_SELECTgetRows('uid, storage, identifier', 'sys_file', sprintf('storage=%d AND identifier_hash=""', $storage->getUid())); foreach ($files as $file) { $hash = $storage->hashFileIdentifier($file['identifier']); $folderHash = $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file['identifier'])); $queries[] = $query = $this->db->UPDATEquery('sys_file', 'uid=' . $file['uid'], array('identifier_hash' => $hash, 'folder_hash' => $folderHash)); $this->db->sql_query($query); } } return $queries; }
/** * Migrate news_category.image (CSV) to sys_category.images (sys_file_reference) * * @return void */ protected function migrateCategoryImages() { $oldCategories = $this->databaseConnection->exec_SELECTgetRows('uid, pid, image, migrate_sys_category_uid', 'tx_news_domain_model_category', 'deleted=0 AND image!=""'); // no images to process then skip if (!count($oldCategories)) { return; } $processedImages = 0; foreach ($oldCategories as $oldCategory) { $files = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $oldCategory['image'], true); $i = 0; foreach ($files as $file) { if (file_exists(PATH_site . 'uploads/tx_news/' . $file)) { $fileObject = $this->getCategoryImageFolder()->addFile(PATH_site . 'uploads/tx_news/' . $file); $dataArray = array('uid_local' => $fileObject->getUid(), 'tstamp' => $_SERVER['REQUEST_TIME'], 'crdate' => $_SERVER['REQUEST_TIME'], 'tablenames' => 'sys_category', 'uid_foreign' => $oldCategory['migrate_sys_category_uid'], 'pid' => $oldCategory['pid'], 'fieldname' => 'images', 'table_local' => 'sys_file', 'sorting_foreign' => $i); $this->databaseConnection->exec_INSERTquery('sys_file_reference', $dataArray); $processedImages++; } $i++; } } $message = 'Migrated ' . $processedImages . ' category images'; $status = FlashMessage::INFO; $title = ''; $this->messageArray[] = array($status, $title, $message); }
/** * Relative filemounts are transformed to relate to our fileadmin/ storage * and their path is modified to be a valid resource location * * @return void */ protected function migrateRelativeFilemounts() { $relativeFilemounts = $this->db->exec_SELECTgetRows('*', 'sys_filemounts', 'base = 1' . BackendUtility::deleteClause('sys_filemounts')); foreach ($relativeFilemounts as $filemount) { $this->db->exec_UPDATEquery('sys_filemounts', 'uid=' . (int) $filemount['uid'], array('base' => $this->storage->getUid(), 'path' => '/' . ltrim($filemount['path'], '/'))); $this->sqlQueries[] = $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery; } }
/** * Gets the sequence id for the next search entry. * * @return int The id to be used as the next sequence id for storing the last search keywords. */ protected function getNextSequenceId() { $nextSequenceId = 0; $numberOfLastSearchesToLog = (int) $this->configuration->getSearchLastSearchesLimit(); $row = $this->database->exec_SELECTgetRows('(sequence_id + 1) % ' . $numberOfLastSearchesToLog . ' as next_sequence_id', 'tx_solr_last_searches', '', '', 'tstamp DESC', 1); if (!empty($row)) { $nextSequenceId = $row[0]['next_sequence_id']; } return $nextSequenceId; }
/** * Get records from table where the field to migrate is not empty (NOT NULL and != '') * and also not numeric (which means that it is migrated) * * @param string $table * @param string $fieldToMigrate * @param array $relationFields * @param int $limit Maximum number records to select * @throws \RuntimeException * @return array */ protected function getRecordsFromTable($table, $fieldToMigrate, $relationFields, $limit) { $fields = implode(',', array_merge($relationFields, ['uid', 'pid'])); $deletedCheck = isset($GLOBALS['TCA'][$table]['ctrl']['delete']) ? ' AND ' . $GLOBALS['TCA'][$table]['ctrl']['delete'] . '=0' : ''; $where = $fieldToMigrate . ' IS NOT NULL' . ' AND ' . $fieldToMigrate . ' != \'\'' . ' AND CAST(CAST(' . $fieldToMigrate . ' AS DECIMAL) AS CHAR) <> CAST(' . $fieldToMigrate . ' AS CHAR)' . $deletedCheck; $result = $this->database->exec_SELECTgetRows($fields, $table, $where, '', 'uid', $limit); if ($result === null) { throw new \RuntimeException('Database query failed. Error was: ' . $this->database->sql_error()); } return $result; }
/** * Initializes the Storage * * @return void */ protected function initializeLocalCache() { if (static::$storageRowCache === null) { static::$storageRowCache = $this->db->exec_SELECTgetRows('*', $this->table, '1=1' . $this->getWhereClauseForEnabledFields(), '', 'name', '', 'uid'); // if no storage is created before or the user has not access to a storage // static::$storageRowCache would have the value array() // so check if there is any record. If no record is found, create the fileadmin/ storage // selecting just one row is enoung if (static::$storageRowCache === array()) { $storageObjectsExists = $this->db->exec_SELECTgetSingleRow('uid', $this->table, ''); if ($storageObjectsExists !== null) { if ($this->createLocalStorage('fileadmin/ (auto-created)', $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], 'relative', 'This is the local fileadmin/ directory. This storage mount has been created automatically by TYPO3.', true) > 0) { // reset to null to force reloading of storages static::$storageRowCache = null; // call self for initialize Cache $this->initializeLocalCache(); } } } } }
/** * */ protected function migrateTtContentPlugins() { $contentElements = $this->databaseConnection->exec_SELECTgetRows('*', 'tt_content', '1=1'); foreach ($contentElements as $contentElement) { foreach ($this->legacyTtContentListTypes as $legacyTtContentListType) { $newTtContentListType = str_replace('mmforum_', 'typo3forum_', $legacyTtContentListType); if ($contentElement['list_type'] === $legacyTtContentListType) { $contentElement['list_type'] = $newTtContentListType; $this->databaseConnection->exec_UPDATEquery('tt_content', 'uid = ' . (int) $contentElement['uid'], $contentElement); } } } }
/** * Copies the data from one table to another. * If the source table has more columns than the destination table, * the copy still happens just without that data being transferred. * * @param string $source * @param string $destination * @param array $renameColumns [sourceColName => destColName, ...] Needed if you're copying from one table to another where the column names differ * @return boolean */ protected function copyTable($source, $destination, $renameColumns = array()) { $this->expectTables(array($source, $destination), "Can't copy table"); $sourceCols = $this->fields($source); $destCols = $this->fields($destination); // Only copy columns that exist in both tables $columnsInSourceNotInDest = array_diff($sourceCols, $destCols); foreach ($columnsInSourceNotInDest as $unsetColumn) { if (!isset($renameColumns[$unsetColumn])) { $key = array_search($unsetColumn, $sourceCols); unset($sourceCols[$key]); } } // As long as we select the fields from the $source table that are in the $dest table, // we shouldn't run into any errors. $sourceSelects = array_combine($sourceCols, $sourceCols); // Rename any columns if (count($renameColumns)) { foreach ($renameColumns as $sourceCol => $destCol) { $this->expectColumn($source, $sourceCol, "When copying table {$source} to {$destination}, can't rename column {$sourceCol} to {$destCol} because {$sourceCol} does not exist."); $this->expectColumn($destination, $destCol, "When copying table {$source} to {$destination}, can't rename column {$sourceCol} to {$destCol} because {$destCol} does not exist."); if (!isset($sourceSelects[$sourceCol])) { $this->log("Tried to rename a column that won't be used when copying table {$source} to {$destination}."); continue; } $sourceSelects[$sourceCol] = "{$sourceCol} AS {$destCol}"; } } $select = implode(', ', $sourceSelects); $sourceRows = $this->db->exec_SELECTgetRows($select, $source, ''); if (!count($sourceRows)) { $this->success("Nothing to copy from {$source} to {$destination}"); return TRUE; } $this->db->exec_INSERTmultipleRows($destination, array_keys($sourceRows[0]), $sourceRows); $this->success("Copied table from {$source} to {$destination}."); return TRUE; }
/** * Update the current_version field after update * For performance reason "native" TYPO3_DB is * used here directly. * * @param integer $repositoryUid * @return integer */ public function insertLastVersion($repositoryUid = 1) { $groupedRows = $this->databaseConnection->exec_SELECTgetRows('extension_key, max(integer_version) as maxintversion', 'tx_extensionmanager_domain_model_extension', 'repository=' . intval($repositoryUid), 'extension_key'); $extensions = count($groupedRows); if ($extensions > 0) { // set all to 0 $this->databaseConnection->exec_UPDATEquery('tx_extensionmanager_domain_model_extension', 'current_version=1 AND repository=' . intval($repositoryUid), array('current_version' => 0)); // Find latest version of extensions and set current_version to 1 for these foreach ($groupedRows as $row) { $this->databaseConnection->exec_UPDATEquery('tx_extensionmanager_domain_model_extension', 'extension_key=' . $this->databaseConnection->fullQuoteStr($row['extension_key'], 'tx_extensionmanager_domain_model_extension') . ' AND integer_version=' . intval($row['maxintversion']) . ' AND repository=' . intval($repositoryUid), array('current_version' => 1)); } } return $extensions; }
/** * Adds languages to configuration * * @param array $conf Configuration (passed as reference) * @return void */ protected function addLanguages(&$conf) { if ($this->hasStaticInfoTables) { $languages = $this->databaseConnection->exec_SELECTgetRows('t1.uid AS uid,t2.lg_iso_2 AS lg_iso_2', 'sys_language t1, static_languages t2', 't2.uid=t1.static_lang_isocode AND t1.hidden=0'); } else { $languages = $this->databaseConnection->exec_SELECTgetRows('t1.uid AS uid,t1.uid AS lg_iso_2', 'sys_language t1', 't1.hidden=0'); } if (count($languages) > 0) { $conf['preVars'] = array(0 => array('GETvar' => 'L', 'valueMap' => array(), 'noMatch' => 'bypass')); foreach ($languages as $lang) { $conf['preVars'][0]['valueMap'][strtolower($lang['lg_iso_2'])] = $lang['uid']; } } }
/** * Perform update * * @param array &$dbQueries Queries done in this update * @param mixed &$customMessages Custom messages * @return boolean Whether the updated was made or not */ public function performUpdate(array &$dbQueries, &$customMessages) { $rows = $this->db->exec_SELECTgetRows('uid,pi_flexform', $GLOBALS['TYPO3_CONF_VARS']['SYS']['contentTable'], 'CType = ' . $this->db->fullQuoteStr('media', $GLOBALS['TYPO3_CONF_VARS']['SYS']['contentTable']) . ' AND pi_flexform LIKE ' . $this->db->fullQuoteStr('%<sheet index="sDEF">%', $GLOBALS['TYPO3_CONF_VARS']['SYS']['contentTable'])); /** @var $flexformTools \TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools */ $flexformTools = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\FlexForm\\FlexFormTools'); foreach ($rows as $row) { $flexFormXML = $row['pi_flexform']; $data = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($flexFormXML); $sDEF = $data['data']['sDEF']['lDEF']; unset($data['data']['sDEF']); $type = $sDEF['mmType']['vDEF']; $data['data']['sGeneral'] = array('lDEF' => array('mmType' => array('vDEF' => $type))); $width = $sDEF['mmWidth']['vDEF']; if ($width) { $data['data']['sGeneral']['lDEF']['mmWidth'] = array('vDEF' => (int) $width); } $height = $sDEF['mmHeight']['vDEF']; if ($height) { $data['data']['sGeneral']['lDEF']['mmHeight'] = array('vDEF' => (int) $height); } switch ($type) { case 'video': $data['data']['sVideo'] = array('lDEF' => array('mmFile' => array('vDEF' => $sDEF['mmFile']['vDEF']))); break; case 'audio': $data['data']['sAudio'] = array('lDEF' => array('mmAudioFallback' => array('vDEF' => $sDEF['mmFile']['vDEF']))); break; default: continue; } $newXML = $flexformTools->flexArray2Xml($data, TRUE); $newXML = str_replace('encoding=""', 'encoding="utf-8"', $newXML); $this->db->exec_UPDATEquery($GLOBALS['TYPO3_CONF_VARS']['SYS']['contentTable'], 'uid = ' . $row['uid'], array('pi_flexform' => $newXML)); } return TRUE; }
/** * @param FileInterface $file * @return ProcessedFile[] * @throws \InvalidArgumentException */ public function findAllByOriginalFile(FileInterface $file) { if (!$file instanceof File) { throw new \InvalidArgumentException('Parameter is no File object but got type "' . (is_object($file) ? get_class($file) : gettype($file)) . '"', 1382006142); } $whereClause = 'original=' . (int) $file->getUid(); $rows = $this->databaseConnection->exec_SELECTgetRows('*', $this->table, $whereClause); $itemList = array(); if ($rows !== null) { foreach ($rows as $row) { $itemList[] = $this->createDomainObject($row); } } return $itemList; }
/** * Resolve relations as defined in TCA and add them to the provided $pageRecord array. * * @param int $uid Page id * @param array $pageRecord Array with page data to add relation data to. * @throws \RuntimeException * @return array $pageRecord with additional relations */ protected function enrichWithRelationFields($uid, array $pageRecord) { $pageOverlayFields = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']); foreach ($GLOBALS['TCA']['pages']['columns'] as $column => $configuration) { if ($this->columnHasRelationToResolve($configuration)) { $configuration = $configuration['config']; if ($configuration['MM']) { /** @var $loadDBGroup \TYPO3\CMS\Core\Database\RelationHandler */ $loadDBGroup = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\RelationHandler::class); $loadDBGroup->start($pageRecord[$column], isset($configuration['allowed']) ? $configuration['allowed'] : $configuration['foreign_table'], $configuration['MM'], $uid, 'pages', $configuration); $relatedUids = isset($loadDBGroup->tableArray[$configuration['foreign_table']]) ? $loadDBGroup->tableArray[$configuration['foreign_table']] : array(); } else { $columnIsOverlaid = in_array($column, $pageOverlayFields, true); $table = $configuration['foreign_table']; $field = $configuration['foreign_field']; $whereClauseParts = array($field . ' = ' . (int) ($columnIsOverlaid ? $uid : $pageRecord['uid'])); if (isset($configuration['foreign_match_fields']) && is_array($configuration['foreign_match_fields'])) { foreach ($configuration['foreign_match_fields'] as $field => $value) { $whereClauseParts[] = $field . ' = ' . $this->databaseConnection->fullQuoteStr($value, $table); } } if (isset($configuration['foreign_table_field'])) { if ((int) $this->languageUid > 0 && $columnIsOverlaid) { $whereClauseParts[] = trim($configuration['foreign_table_field']) . ' = \'pages_language_overlay\''; } else { $whereClauseParts[] = trim($configuration['foreign_table_field']) . ' = \'pages\''; } } if (isset($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'])) { $whereClauseParts[] = $table . '.' . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'] . ' = 0'; } $whereClause = implode(' AND ', $whereClauseParts); $whereClause .= $this->pageContext->deleteClause($table); $orderBy = isset($configuration['foreign_sortby']) ? $configuration['foreign_sortby'] : ''; $rows = $this->databaseConnection->exec_SELECTgetRows('uid', $table, $whereClause, '', $orderBy); if (!is_array($rows)) { throw new \RuntimeException('Could to resolve related records for page ' . $uid . ' and foreign_table ' . htmlspecialchars($configuration['foreign_table']), 1343589452); } $relatedUids = array(); foreach ($rows as $row) { $relatedUids[] = $row['uid']; } } $pageRecord[$column] = implode(',', $relatedUids); } } return $pageRecord; }
/** * Gets the entry from cache. Language id is needed here because in some * cases URLs can be the same for different languages (_DOMAINS & use alias, * for example). * * We may not fallback to the default language here! * * @param int $rootPageId * @param string $speakingUrl * @param int|null $languageId * @return UrlCacheEntry|null */ public function getUrlFromCacheBySpeakingUrl($rootPageId, $speakingUrl, $languageId) { $cacheEntry = NULL; $rows = $this->databaseConnection->exec_SELECTgetRows('*', 'tx_realurl_urldata', 'rootpage_id=' . (int) $rootPageId . ' AND ' . 'speaking_url=' . $this->databaseConnection->fullQuoteStr($speakingUrl, 'tx_realurl_urldata'), '', 'expire'); $row = null; foreach ($rows as $rowCandidate) { $variables = (array) @json_decode($rowCandidate['request_variables'], TRUE); if (is_null($languageId)) { // No language known, we retrieve only the URL with lowest expiration value // See https://github.com/dmitryd/typo3-realurl/issues/250 $row = $rowCandidate; if (isset($variables['cHash'])) { break; } } else { // Should check for language match // See https://github.com/dmitryd/typo3-realurl/issues/103 if (isset($variables['L'])) { if ((int) $variables['L'] === (int) $languageId) { // Found language! $row = $rowCandidate; if (isset($variables['cHash'])) { break; } } } elseif ($languageId === 0 && is_null($row)) { // No L in URL parameters of the URL but default language requested. This is a match. $row = $rowCandidate; } } } if (is_array($row)) { $cacheEntry = GeneralUtility::makeInstance('DmitryDulepov\\Realurl\\Cache\\UrlCacheEntry'); /** @var \DmitryDulepov\Realurl\Cache\UrlCacheEntry $cacheEntry */ $cacheEntry->setCacheId($row['uid']); $cacheEntry->setExpiration($row['expire']); $cacheEntry->setPageId($row['page_id']); $cacheEntry->setRootPageId($row['rootpage_id']); $cacheEntry->setOriginalUrl($row['original_url']); $cacheEntry->setSpeakingUrl($speakingUrl); $requestVariables = @json_decode($row['request_variables'], TRUE); // TODO Log a problem here because it must be an array always $cacheEntry->setRequestVariables(is_array($requestVariables) ? $requestVariables : array()); } return $cacheEntry; }
/** * Function to handle record actions for children of translated grid containers * * @param array $containerUpdateArray * * @return void */ public function checkAndUpdateTranslatedChildren($containerUpdateArray = array()) { if (is_array($containerUpdateArray) && count($containerUpdateArray > 0)) { foreach ($containerUpdateArray as $containerUid => $newElement) { $translatedContainers = $this->databaseConnection->exec_SELECTgetRows('uid,sys_language_uid', 'tt_content', 'l18n_parent = ' . (int) $containerUid . \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause('tt_content')); if (count($translatedContainers) > 0) { foreach ($translatedContainers as $languageArray) { $targetContainer = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL('tt_content', $languageArray['uid']); $fieldArray['tx_gridelements_container'] = $targetContainer['uid']; $where = 'tx_gridelements_container = ' . (int) $containerUid . ' AND sys_language_uid = ' . (int) $targetContainer['sys_language_uid']; $this->databaseConnection->exec_UPDATEquery('tt_content', $where, $fieldArray, 'tx_gridelements_container'); $this->getTceMain()->updateRefIndex('tt_content', (int) $targetContainer['uid']); } } } } }
/** * Collects tt_content data from a single page or a page tree starting at a given page * * @param string $shortcutItem : The single page to be used as the tree root * @param array $collectedItems : The collected item data rows ordered by parent position, column position and sorting * @param int $recursive : The number of levels for the recursion * @param string $showHidden : query String containing enable fields * @param string $deleteClause : query String to check for deleted items * @param int $parentUid : uid of the referencing tt_content record * * @return void */ public function collectContentDataFromPages($shortcutItem, &$collectedItems, $recursive = 0, &$showHidden, &$deleteClause, $parentUid) { $itemList = str_replace('pages_', '', $shortcutItem); if ($recursive) { if (!$this->tree instanceof QueryGenerator) { $this->tree = GeneralUtility::makeInstance(QueryGenerator::class); } $itemList = $this->tree->getTreeList($itemList, (int) $recursive, 0, 1); } $itemRows = $this->databaseConnection->exec_SELECTgetRows('*', 'tt_content', 'uid != ' . (int) $parentUid . ' AND pid IN (' . $itemList . ') AND colPos >= 0 ' . $showHidden . $deleteClause, '', 'FIND_IN_SET(pid, \'' . $itemList . '\'),colPos,sorting'); foreach ($itemRows as $itemRow) { if ($this->helper->getBackendUser()->workspace > 0) { BackendUtility::workspaceOL('tt_content', $itemRow, $this->helper->getBackendUser()->workspace); } $itemRow['tx_gridelements_reference_container'] = $itemRow['pid']; $collectedItems[] = $itemRow; } }
/** * Find an extension by title, author name or extension key * This is the function used by the TER search. It is using a * scoring for the matches to sort the extension with an * exact key match on top * * @param string $searchString The string to search for extensions * @return mixed */ public function findByTitleOrAuthorNameOrExtensionKey($searchString) { $quotedSearchString = $this->databaseConnection->escapeStrForLike($this->databaseConnection->quoteStr($searchString, 'tx_extensionmanager_domain_model_extension'), 'tx_extensionmanager_domain_model_extension'); $quotedSearchStringForLike = '\'%' . $quotedSearchString . '%\''; $quotedSearchString = '\'' . $quotedSearchString . '\''; $select = self::TABLE_NAME . '.*, ' . 'CASE ' . 'WHEN extension_key = ' . $quotedSearchString . ' THEN 16 ' . 'WHEN extension_key LIKE ' . $quotedSearchStringForLike . ' THEN 8 ' . 'WHEN title LIKE ' . $quotedSearchStringForLike . ' THEN 4 ' . 'WHEN description LIKE ' . $quotedSearchStringForLike . ' THEN 2 ' . 'WHEN author_name LIKE ' . $quotedSearchStringForLike . ' THEN 1 ' . 'END AS position'; $where = '( extension_key = ' . $quotedSearchString . ' OR extension_key LIKE ' . $quotedSearchStringForLike . ' OR title LIKE ' . $quotedSearchStringForLike . ' OR description LIKE ' . $quotedSearchStringForLike . ' OR author_name LIKE ' . $quotedSearchStringForLike . ' ) AND current_version = 1 AND review_state >= 0'; $order = 'position DESC'; $result = $this->databaseConnection->exec_SELECTgetRows($select, self::TABLE_NAME, $where, '', $order); return $this->dataMapper->map(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension::class, $result); }