Example #1
0
 /**
  * Gets the cache for the id
  *
  * @param string $id
  * @return mixed
  */
 public function get($id)
 {
     if (!isset($this->level1Cache[$id])) {
         $this->level1Cache[$id] = $this->level2Cache->get($id);
     }
     return $this->level1Cache[$id];
 }
Example #2
0
 /**
  * Builds a data map by adding column maps for all the configured columns in the $TCA.
  * It also resolves the type of values the column is holding and the typo of relation the column
  * represents.
  *
  * @param string $className The class name you want to fetch the Data Map for
  * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap The data map
  */
 public function buildDataMap($className)
 {
     $dataMap = $this->dataMapCache->get(str_replace('\\', '%', $className));
     if ($dataMap === FALSE) {
         $dataMap = $this->buildDataMapInternal($className);
         $this->dataMapCache->set(str_replace('\\', '%', $className), $dataMap);
     }
     return $dataMap;
 }
 /**
  * Clears cache of pages where an object with the given identifier is shown
  * 
  * @param string $classIdentifier
  * @return int|mixed
  */
 public function getAutoId($classIdentifier)
 {
     $exclusiveLock = null;
     $objectIdentifier = 'autoid-' . $classIdentifier;
     $exclusiveLockAcquired = $this->acquireLock($exclusiveLock, $objectIdentifier, TRUE);
     $autoId = 0;
     if ($exclusiveLockAcquired) {
         if ($this->trackingCache->has($objectIdentifier)) {
             $autoId = $this->trackingCache->get($objectIdentifier);
         }
         $autoId++;
         $this->trackingCache->set($objectIdentifier, $autoId);
         $this->releaseLock($exclusiveLock);
     }
     return $autoId;
 }
Example #4
0
 /**
  * Finds and returns a variable value from the query cache.
  *
  * @param string $entryIdentifier Identifier of the cache entry to fetch
  * @return mixed The value
  */
 protected function getQueryCacheEntry($entryIdentifier)
 {
     if (!isset($this->queryRuntimeCache[$entryIdentifier])) {
         $this->queryRuntimeCache[$entryIdentifier] = $this->queryCache->get($entryIdentifier);
     }
     return $this->queryRuntimeCache[$entryIdentifier];
 }
 /**
  * Gets the page title of the given page id
  *
  * @param int $pageId
  * @return string
  */
 protected function getPageTitle($pageId)
 {
     $cacheId = 'recycler-pagetitle-' . $pageId;
     if ($this->runtimeCache->has($cacheId)) {
         $pageTitle = $this->runtimeCache->get($cacheId);
     } else {
         if ($pageId === 0) {
             $pageTitle = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
         } else {
             $recordInfo = $this->tce->recordInfo('pages', $pageId, 'title');
             $pageTitle = $recordInfo['title'];
         }
         $this->runtimeCache->set($cacheId, $pageTitle);
     }
     return $pageTitle;
 }
 /**
  * Called by ajax.php / eID.php
  * Builds an extbase context and returns the response.
  * 
  * @return void
  */
 public function dispatch()
 {
     $src = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('src');
     $hash = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('hash');
     $conf = json_decode(rawurldecode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('conf')), true);
     /* @var $cacheHash \TYPO3\CMS\Frontend\Page\CacheHashCalculator */
     $cacheHash = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\CacheHashCalculator');
     $calculatedHash = $cacheHash->calculateCacheHash(array('encryptionKey' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], 'src' => $src, 'conf' => $conf));
     $allowProcessing = $hash == $calculatedHash;
     /**
      * check hash
      */
     if (!$allowProcessing) {
         header('HTTP/1.1 503 Service Unavailable');
         header('Status: 503 Service Unavailable');
         exit;
     }
     /**
      * check if source file exists
      */
     if (!@file_exists($src)) {
         header("HTTP/1.0 404 Not Found");
         header("Status: 404 Not Found");
         exit;
     }
     /**
      * check if target file exists and is up to date
      */
     if ($this->cache->has($hash)) {
         list($target, $sourceMDate) = $this->cache->get($hash);
         if (@file_exists($target) && @filemtime($src) === $sourceMDate) {
             header("Location:" . $target);
             exit;
         }
     }
     /**
      * generate image
      */
     $this->initialize();
     $target = $this->generateImage($src, $conf['width'], $conf['height'], $conf['minWidth'], $conf['minHeight'], $conf['maxWidth'], $conf['maxHeight']);
     $sourceMDate = @filemtime($src);
     $this->cache->set($hash, array($target, $sourceMDate));
     header("Location:" . $target);
     exit;
 }
Example #7
0
 /**
  * Tries to load the reflection data from this service's cache.
  *
  * @return void
  */
 protected function loadFromCache()
 {
     $data = $this->dataCache->get($this->cacheIdentifier);
     if ($data !== false) {
         foreach ($data as $propertyName => $propertyValue) {
             $this->{$propertyName} = $propertyValue;
         }
     }
 }
 /**
  * @param string $id
  * @return object
  */
 public function findById($id)
 {
     $fullId = 'serialized-' . str_replace('\\', '_', get_class($this)) . '-' . $id;
     $object = null;
     if ($this->objectCache[$fullId]) {
         $object = $this->objectCache[$fullId];
     } elseif ($this->storage->has($fullId)) {
         $object = $this->unserialize($this->storage->get($fullId));
         $this->objectCache[$fullId] = $object;
     }
     return $object;
 }
    /**
     * @param array $parameters
     * @param PageLayoutView|DatabaseRecordList $caller
     * @return string
     */
    public function addSubIcon(array $parameters, $caller = NULL)
    {
        $this->attachAssets();
        list($table, $uid, $record) = $parameters;
        $icon = NULL;
        if (NULL !== $caller) {
            $record = NULL === $record && 0 < $uid ? BackendUtility::getRecord($table, $uid) : $record;
            $cacheIdentity = $table . $uid . sha1(serialize($record));
            // filter 1: icon must not already be cached and both record and caller must be provided.
            if (TRUE === $this->cache->has($cacheIdentity)) {
                $icon = $this->cache->get($cacheIdentity);
            } elseif (NULL !== $record) {
                $field = $this->detectFirstFlexTypeFieldInTableFromPossibilities($table, array_keys($record));
                // filter 2: table must have one field defined as "flex" and record must include it.
                if (NULL !== $field && TRUE === isset($record[$field])) {
                    // we check the cache here because at this point, the cache key is decidedly
                    // unique and we have not yet consulted the (potentially costly) Provider.
                    $provider = $this->fluxService->resolvePrimaryConfigurationProvider($table, $field, $record);
                    // filter 3: a Provider must be resolved for the record.
                    if (NULL !== $provider) {
                        $form = $provider->getForm((array) $record);
                        if (NULL !== $form) {
                            $icon = MiscellaneousUtility::getIconForTemplate($form);
                            if (NULL !== $icon) {
                                $label = trim($form->getLabel());
                                $icon = '<img width="16" height="16" src="' . $icon . '" alt="' . $label . '"
									title="' . $label . '" class="" />';
                                $icon = sprintf($this->templates['iconWrapper'], $icon);
                            }
                        }
                    }
                }
                $this->cache->set($cacheIdentity, $icon);
            }
        }
        return $icon;
    }
Example #10
0
 /**
  * Tracks display of an object on a page
  * 
  * @param \TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object Object to use
  * @param mixed $hash Hash or page id (depending on the type) for which the object display will be associated
  * @param string $type 'hash' (for only one hash) or 'id' (for complete page cache of a page, for all hash combinations)
  * @return void
  */
 public function trackObjectOnPage(\TYPO3\CMS\Extbase\DomainObject\AbstractDomainObject $object = NULL, $type = 'hash', $hash = false)
 {
     if ($object && !$this->ajaxDispatcher->getIsActive()) {
         $this->signalSlotDispatcher->dispatch(__CLASS__, self::SIGNAL_PreTrackObjectOnPage, array('object' => $object, 'type' => $type, 'hash' => $hash));
         if ($type) {
             switch ($type) {
                 case 'id':
                     if (!$hash) {
                         $hash = intval($this->fe->id);
                     }
                     $pageHash = 'id-' . $hash;
                     break;
                 case 'hash':
                 default:
                     if (!$hash) {
                         $hash = $this->fe->getHash();
                     }
                     $pageHash = 'hash-' . $hash;
                     break;
             }
             $objectIdentifier = $this->getObjectIdentifierForObject($object);
             $sharedLock = null;
             $sharedLockAcquired = $this->acquireLock($sharedLock, $objectIdentifier, FALSE);
             if ($sharedLockAcquired) {
                 if ($this->trackingCache->has($objectIdentifier)) {
                     $pageHashs = $this->trackingCache->get($objectIdentifier);
                     if (!in_array($pageHash, $pageHashs)) {
                         $exclusiveLock = null;
                         $exclusiveLockAcquired = $this->acquireLock($exclusiveLock, $objectIdentifier . '-e', TRUE);
                         if ($exclusiveLockAcquired) {
                             $pageHashs = $this->trackingCache->get($objectIdentifier);
                             if (!in_array($pageHash, $pageHashs)) {
                                 $pageHashs[] = $pageHash;
                                 $this->trackingCache->set($objectIdentifier, array_unique($pageHashs));
                             }
                             $this->releaseLock($exclusiveLock);
                         }
                     }
                 } else {
                     $this->trackingCache->set($objectIdentifier, array($pageHash));
                 }
                 $this->releaseLock($sharedLock);
             }
         }
     }
     return;
 }
Example #11
0
 /**
  * Hook for generating dynamic FlexForm source code.
  *
  * NOTE: patches data structure resolving in a way that solves
  * a regression in the TYPO3 core when dealing with IRRE AJAX
  * requests (in which the database record is no longer fetched
  * by the controller). This patches not only data structure
  * resolving for Flux data structures but indeed any data
  * structure built using hooks or involving user functions which
  * require the entire record (but when using hooks, supports
  * only extensions which are loaded AFTER or depend on Flux).
  *
  * @param array $dataStructArray
  * @param array $conf
  * @param array $row
  * @param string $table
  * @param string $fieldName
  * @return void
  */
 public function getFlexFormDS_postProcessDS(&$dataStructArray, $conf, &$row, $table, $fieldName)
 {
     if (empty($fieldName) === TRUE) {
         // Cast NULL if an empty but not-NULL field name was passed. This has significance to the Flux internals in
         // respect to which ConfigurationProvider(s) are returned.
         $fieldName = NULL;
     }
     if (!empty($fieldName) && !isset($row[$fieldName])) {
         // Patch required (possibly temporary). Due to changes in TYPO3 in the new FormEngine we must fetch the
         // database record at this point when the record is incomplete, which happens when attempting to render
         // IRRE records. The reason is that the controller that creates the HTML does not fetch the record any
         // more - and that the AJAX request contains only the UID. So, we fetch the record here to ensure it
         // contains the necessary fields. DOES NOT WORK FOR NEW RECORDS - SEE COMMENTS BELOW.
         $row = $this->recordService->getSingle($table, '*', $row['uid']);
     }
     $defaultDataSourceCacheIdentifier = $table . '_' . $fieldName . '_' . sha1(serialize($conf));
     if (!$row) {
         // In the case that the database record cannot be fetched we are dealing with a new or otherwise deleted
         // or unidentifiable record. This happens primarily when AJAX requests are made to render IRRE records
         // without the parent record having been saved first. To accommodate this case we have to be slightly
         // creative and store a "default" data source definition which is identified based on a checksum of the
         // configuration provided. Whenever we are then unable to fetch a record, we can at least attempt to
         // locate a default data source in previously cached content. NB: we enforce a VERY high cache lifetime
         // and continually refresh it every time it is possible to render a new DS that can serve as default.
         $dataStructArray = (array) $this->cache->get($defaultDataSourceCacheIdentifier);
     } else {
         if (FALSE === is_array($dataStructArray)) {
             $dataStructArray = array();
         }
         $providers = $this->configurationService->resolveConfigurationProviders($table, $fieldName, $row);
         foreach ($providers as $provider) {
             $provider->postProcessDataStructure($row, $dataStructArray, $conf);
         }
         if (empty($dataStructArray)) {
             $dataStructArray = array('ROOT' => array('el' => array()));
         }
         $evaluationParameters = array();
         $this->cache->set($defaultDataSourceCacheIdentifier, $this->recursivelyEvaluateClosures($dataStructArray, $evaluationParameters), array(), time() + 31536000);
     }
     // Trigger TCEforms dimension patching only if required by TYPO3 version according to CompatibilityRegistry.
     if (CompatibilityRegistry::get('FluidTYPO3\\Flux\\Backend\\DynamicFlexForm::NEEDS_TCEFORMS_WRAPPER')) {
         $dataStructArray = $this->patchTceformsWrapper($dataStructArray);
     }
 }
Example #12
0
 /**
  * Builds the page ID checking statement
  *
  * @param string $tableName The database table name
  * @param array &$sql The query parts
  * @param array $storagePageIds list of storage page ids
  * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\InconsistentQuerySettingsException
  * @return void
  */
 protected function addPageIdStatement($tableName, array &$sql, array $storagePageIds)
 {
     $tableColumns = $this->tableColumnCache->get($tableName);
     if ($tableColumns === FALSE) {
         $tableColumns = $this->databaseHandle->admin_get_fields($tableName);
         $this->tableColumnCache->set($tableName, $tableColumns);
     }
     if (is_array($GLOBALS['TCA'][$tableName]['ctrl']) && array_key_exists('pid', $tableColumns)) {
         $rootLevel = (int) $GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'];
         if ($rootLevel) {
             if ($rootLevel === 1) {
                 $sql['additionalWhereClause'][] = $tableName . '.pid = 0';
             }
         } else {
             if (empty($storagePageIds)) {
                 throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\InconsistentQuerySettingsException('Missing storage page ids.', 1365779762);
             }
             $sql['additionalWhereClause'][] = $tableName . '.pid IN (' . implode(', ', $storagePageIds) . ')';
         }
     }
 }
 /**
  * Builds the page ID checking statement
  *
  * @param string $tableName The database table name
  * @param string $tableAlias The table alias used in the query.
  * @param array $storagePageIds list of storage page ids
  * @throws InconsistentQuerySettingsException
  * @return string
  */
 protected function getPageIdStatement($tableName, $tableAlias, array $storagePageIds)
 {
     $pageIdStatement = '';
     $tableColumns = $this->tableColumnCache->get($tableName);
     if ($tableColumns === false) {
         $tableColumns = $this->databaseHandle->admin_get_fields($tableName);
         $this->tableColumnCache->set($tableName, $tableColumns);
     }
     if (is_array($GLOBALS['TCA'][$tableName]['ctrl']) && array_key_exists('pid', $tableColumns)) {
         $rootLevel = (int) $GLOBALS['TCA'][$tableName]['ctrl']['rootLevel'];
         switch ($rootLevel) {
             // Only in pid 0
             case 1:
                 return $tableAlias . '.pid = 0';
                 // Pid 0 and pagetree
             // Pid 0 and pagetree
             case -1:
                 if (empty($storagePageIds)) {
                     return $tableAlias . '.pid = 0';
                 }
                 $storagePageIds[] = 0;
                 break;
                 // Only pagetree or not set
             // Only pagetree or not set
             case 0:
                 if (empty($storagePageIds)) {
                     throw new InconsistentQuerySettingsException('Missing storage page ids.', 1365779762);
                 }
                 break;
                 // Invalid configuration
             // Invalid configuration
             default:
                 return '';
         }
         $pageIdStatement = $tableAlias . '.pid IN (' . implode(',', $this->databaseHandle->cleanIntArray($storagePageIds)) . ')';
     }
     return $pageIdStatement;
 }
Example #14
0
 /**
  * Returns array of arrays with an index of all references found in record from table/uid
  * If the result is used to update the sys_refindex table then ->WSOL must NOT be TRUE (no workspace overlay anywhere!)
  *
  * @param string $tableName Table name from $GLOBALS['TCA']
  * @param int $uid Record UID
  * @return array|NULL Index Rows
  * @todo Define visibility
  */
 public function generateRefIndexData($tableName, $uid)
 {
     if (!isset($GLOBALS['TCA'][$tableName])) {
         return NULL;
     }
     $this->relations = array();
     // Fetch tableRelationFields and save them in cache if not there yet
     $cacheId = static::$cachePrefixTableRelationFields . $tableName;
     if (!$this->runtimeCache->has($cacheId)) {
         $tableRelationFields = $this->fetchTableRelationFields($tableName);
         $this->runtimeCache->set($cacheId, $tableRelationFields);
     } else {
         $tableRelationFields = $this->runtimeCache->get($cacheId);
     }
     // Return if there are no fields which could contain relations
     if ($tableRelationFields === '') {
         return $this->relations;
     }
     $deleteField = $GLOBALS['TCA'][$tableName]['ctrl']['delete'];
     if ($tableRelationFields === '*') {
         // If one field of a record is of type flex, all fields have to be fetched to be passed to BackendUtility::getFlexFormDS
         $selectFields = '*';
     } else {
         // otherwise only fields that might contain relations are fetched
         $selectFields = 'uid,' . $tableRelationFields . ($deleteField ? ',' . $deleteField : '');
     }
     // Get raw record from DB:
     $record = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow($selectFields, $tableName, 'uid=' . (int) $uid);
     if (!is_array($record)) {
         return NULL;
     }
     // Initialize:
     $this->words_strings = array();
     $this->words = array();
     // Deleted:
     $deleted = $deleteField && $record[$deleteField] ? 1 : 0;
     // Get all relations from record:
     $recordRelations = $this->getRelations($tableName, $record);
     // Traverse those relations, compile records to insert in table:
     foreach ($recordRelations as $fieldName => $fieldRelations) {
         // Based on type,
         switch ((string) $fieldRelations['type']) {
             case 'db':
                 $this->createEntryData_dbRels($tableName, $uid, $fieldName, '', $deleted, $fieldRelations['itemArray']);
                 break;
             case 'file_reference':
                 // not used (see getRelations()), but fallback to file
             // not used (see getRelations()), but fallback to file
             case 'file':
                 $this->createEntryData_fileRels($tableName, $uid, $fieldName, '', $deleted, $fieldRelations['newValueFiles']);
                 break;
             case 'flex':
                 // DB references:
                 if (is_array($fieldRelations['flexFormRels']['db'])) {
                     foreach ($fieldRelations['flexFormRels']['db'] as $flexPointer => $subList) {
                         $this->createEntryData_dbRels($tableName, $uid, $fieldName, $flexPointer, $deleted, $subList);
                     }
                 }
                 // File references in flexforms
                 // @todo #65463 Test correct handling of file references in flexforms
                 if (is_array($fieldRelations['flexFormRels']['file'])) {
                     foreach ($fieldRelations['flexFormRels']['file'] as $flexPointer => $subList) {
                         $this->createEntryData_fileRels($tableName, $uid, $fieldName, $flexPointer, $deleted, $subList);
                     }
                 }
                 // Soft references in flexforms
                 // @todo #65464 Test correct handling of soft references in flexforms
                 if (is_array($fieldRelations['flexFormRels']['softrefs'])) {
                     foreach ($fieldRelations['flexFormRels']['softrefs'] as $flexPointer => $subList) {
                         $this->createEntryData_softreferences($tableName, $uid, $fieldName, $flexPointer, $deleted, $subList['keys']);
                     }
                 }
                 break;
         }
         // Soft references in the field:
         if (is_array($fieldRelations['softrefs'])) {
             $this->createEntryData_softreferences($tableName, $uid, $fieldName, '', $deleted, $fieldRelations['softrefs']['keys']);
         }
     }
     return $this->relations;
 }
Example #15
0
 /**
  * @param string $extensionKey
  * @param string $version
  * @param array $segments
  * @return array
  */
 protected function getSchemaData($extensionKey, $version, $segments)
 {
     if (FALSE === ExtensionManagementUtility::isLoaded($extensionKey)) {
         return array();
     }
     $baseCacheKey = $extensionKey . $version;
     $baseCacheKey = preg_replace('/[^a-z0-9]+/i', '-', $baseCacheKey);
     $cacheKey = $baseCacheKey . implode('', $segments);
     if (TRUE === $this->cache->has($cacheKey)) {
         return $this->cache->get($cacheKey);
     }
     $className = implode('/', $segments);
     $url = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
     $schemaFile = $this->getXsdStoragePathSetting() . $extensionKey . '-' . $version . '.xsd';
     $schemaFile = GeneralUtility::getFileAbsFileName($schemaFile);
     $schemaSource = shell_exec('cat ' . $schemaFile . ' | tr -cd \'[:print:]\\r\\n\\t\'');
     $document = new \DOMDocument();
     $document->validateOnParse = TRUE;
     $document->strictErrorChecking = TRUE;
     $document->loadXML($schemaSource);
     if (TRUE === $this->cache->has($baseCacheKey . 'tree')) {
         $tree = $this->cache->get($baseCacheKey . 'tree');
     } else {
         $tree = $this->buildTreeFromSchema($document);
         $this->cache->set($baseCacheKey . 'tree', $tree);
     }
     $node = $this->findCurrentViewHelperNode($document, $segments);
     $targetNamespaceUrl = $document->documentElement->getAttribute('targetNamespace');
     if (0 < count($segments)) {
         $viewHelperArguments = $this->makeArgumentDefinitions($node, $extensionKey, $className);
         $docComment = $node->getElementsByTagName('documentation')->item(0)->nodeValue;
         $additionalDocumentationFile = ExtensionManagementUtility::extPath($extensionKey, 'Documentation/Classes/ViewHelpers/' . $className . '/README.md');
         $nextDiv = FALSE;
         if (TRUE === file_exists($additionalDocumentationFile)) {
             $alerts = array('warning', 'danger', 'success', 'info');
             $additionalDocumentation = file_get_contents($additionalDocumentationFile);
             $parts = explode('```', $additionalDocumentation);
             foreach ($parts as $index => &$part) {
                 $firstText = substr($part, 0, strpos($part, LF));
                 if (TRUE === in_array($firstText, $alerts)) {
                     $part = '<span class="alert alert-' . $firstText . '"><span class="lead">' . ucfirst($firstText) . '</span><br />' . substr($part, strlen($firstText));
                     $nextDiv = TRUE;
                 } else {
                     if (TRUE === $nextDiv) {
                         $part = '</span>' . $part;
                         $nextDiv = FALSE;
                     } elseif (0 < $index) {
                         $part = '```' . $part;
                     }
                 }
             }
             $additionalDocumentation = implode('', $parts);
             $additionalDocumentation = preg_replace('/Arguments\\/([a-z0-9^\\s\\/]+)\\.md/i', $url . '#argument-$1', $additionalDocumentation);
             $additionalDocumentation = preg_replace('/(```)([a-z\\s]+)(.[\\`]{3})(```)/i', $url . '<div class="alert alert-$1">$2</div>', $additionalDocumentation);
             $docComment .= LF . LF . $additionalDocumentation;
         }
     }
     $data = array($tree, $node, $viewHelperArguments, $docComment, $targetNamespaceUrl);
     $this->cache->set($cacheKey, $data);
     return $data;
 }
Example #16
0
 /**
  * Registers elements to be deleted in the registry.
  *
  * @return void
  * @see process_datamap
  */
 protected function registerElementsToBeDeleted()
 {
     $elementsToBeDeleted = (array) $this->runtimeCache->get('core-datahandler-elementsToBeDeleted');
     $this->runtimeCache->set('core-datahandler-elementsToBeDeleted', array_merge($elementsToBeDeleted, $this->getCommandMapElements('delete')));
 }
Example #17
0
 /**
  * Creates a SELECT prepared SQL statement.
  *
  * @param string $select_fields See exec_SELECTquery()
  * @param string $from_table See exec_SELECTquery()
  * @param string $where_clause See exec_SELECTquery()
  * @param string $groupBy See exec_SELECTquery()
  * @param string $orderBy See exec_SELECTquery()
  * @param string $limit See exec_SELECTquery()
  * @param array $input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_AUTOTYPE.
  * @return \TYPO3\CMS\Core\Database\PreparedStatement Prepared statement
  */
 public function prepare_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '', array $input_parameters = array())
 {
     $pt = $this->debug ? GeneralUtility::milliseconds() : 0;
     $precompiledParts = array();
     if ($this->queryCache) {
         $cacheKey = 'prepare_SELECTquery-' . \TYPO3\CMS\Dbal\QueryCache::getCacheKey(array('selectFields' => $select_fields, 'fromTable' => $from_table, 'whereClause' => $where_clause, 'groupBy' => $groupBy, 'orderBy' => $orderBy, 'limit' => $limit));
         if ($this->queryCache->has($cacheKey)) {
             $precompiledParts = $this->queryCache->get($cacheKey);
             if ($this->debug) {
                 $data = array('args' => array($from_table, $select_fields, $where_clause, $groupBy, $orderBy, $limit, $input_parameters), 'precompiledParts' => $precompiledParts);
                 $this->debugHandler('prepare_SELECTquery (cache hit)', GeneralUtility::milliseconds() - $pt, $data);
             }
         }
     }
     $ORIG_tableName = '';
     if (empty($precompiledParts)) {
         // Map table / field names if needed:
         $ORIG_tableName = $from_table;
         // Saving table names in $ORIG_from_table since $from_table is transformed beneath:
         $parsedFromTable = array();
         $queryComponents = array();
         if ($tableArray = $this->map_needMapping($ORIG_tableName, FALSE, $parsedFromTable)) {
             $from = $parsedFromTable ? $parsedFromTable : $from_table;
             $components = $this->map_remapSELECTQueryParts($select_fields, $from, $where_clause, $groupBy, $orderBy);
             $queryComponents['SELECT'] = $components[0];
             $queryComponents['FROM'] = $components[1];
             $queryComponents['WHERE'] = $components[2];
             $queryComponents['GROUPBY'] = $components[3];
             $queryComponents['ORDERBY'] = $components[4];
             $queryComponents['parameters'] = $components[5];
         } else {
             $queryComponents = $this->getQueryComponents($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
         }
         $queryComponents['ORIG_tableName'] = $ORIG_tableName;
         if (!$this->runningNative()) {
             // Quotes all fields
             $queryComponents['SELECT'] = $this->_quoteFieldNames($queryComponents['SELECT']);
             $queryComponents['FROM'] = $this->_quoteFromTables($queryComponents['FROM']);
             $queryComponents['WHERE'] = $this->_quoteWhereClause($queryComponents['WHERE']);
             $queryComponents['GROUPBY'] = $this->_quoteGroupBy($queryComponents['GROUPBY']);
             $queryComponents['ORDERBY'] = $this->_quoteOrderBy($queryComponents['ORDERBY']);
         }
         $precompiledParts = $this->precompileSELECTquery($queryComponents);
         if ($this->queryCache) {
             try {
                 $this->queryCache->set($cacheKey, $precompiledParts);
             } catch (\TYPO3\CMS\Core\Cache\Exception $e) {
                 if ($this->debug) {
                     GeneralUtility::devLog($e->getMessage(), 'dbal', 1);
                 }
             }
         }
     }
     $preparedStatement = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\PreparedStatement::class, '', $from_table, $precompiledParts);
     /* @var $preparedStatement \TYPO3\CMS\Core\Database\PreparedStatement */
     // Bind values to parameters
     foreach ($input_parameters as $key => $value) {
         $preparedStatement->bindValue($key, $value, \TYPO3\CMS\Core\Database\PreparedStatement::PARAM_AUTOTYPE);
     }
     if ($this->debug) {
         $data = array('args' => array($from_table, $select_fields, $where_clause, $groupBy, $orderBy, $limit, $input_parameters), 'ORIG_from_table' => $ORIG_tableName);
         $this->debugHandler('prepare_SELECTquery', GeneralUtility::milliseconds() - $pt, $data);
     }
     // Return prepared statement
     return $preparedStatement;
 }