TYPO3 ConnectionPool find a file after the uid of

2019-08-18 16:13发布

The concept is that, after a successfull save of my object, it should update a text in the database (With a Hook). Lets call the field 'succText'. The table i would like to access is the sys_file but i only get the sys_file_reference id when i save the object. So i thought i could use the ConnectionPool to select the sys_file row of this file reference and then insert the data on the field 'succText'.

I tried this:

public function processDatamap_preProcessFieldArray(array &$fieldArray, $table, $id, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
    $findItemsId = $queryBuilder
       ->select('*')
       ->from('sys_file_reference')
       ->join(
          'sys_file_reference',
          'sys_file',
          'reference',
          $queryBuilder->expr()->eq('reference.uid', $queryBuilder->quoteIdentifier('uid_local'))
       )
       ->where(
            $queryBuilder->expr()->eq('uid_local', $queryBuilder->createNamedParameter($fieldArray['downloads'], \PDO::PARAM_INT))
       )
      ->execute();
}

But this give me back the sys_file_reference id and not the id and the field values of the sys_file table.

As for the update, i havent tried it yet, cause i haven't figured out yet, how to get the row that needs to be updated. I gues with a subquery after the row is found, i don't really know.

The processDatamap_preProcessFieldArray is going to be renamed to post. I only have it this way in order to get the results on the backend.

Thanks in advance,

2条回答
▲ chillily
2楼-- · 2019-08-18 16:59

You might want to make use of the FileRepository class here.

$fileRepository = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\FileRepository::class);
$fileObjects = $fileRepository->findByRelation('tablename', 'fieldname', $uid);

Where $uid is the ID of the record that the files are connected to via file reference.

You will get back an array of file objects to deal with.

查看更多
成全新的幸福
3楼-- · 2019-08-18 17:03

I resolved my problem by removing the first code and adding a filerepository instance.

 $fileRepository = GeneralUtility::makeInstance(FileRepository::class);
 $fileObjects = $fileRepository->findByRelation('targetTable', 'targetField', $uid);

VERY IMPORTANT!

If you are creating a new element then TYPO3 assigns a temp UID variable with a name that looks like this NEW45643476. In order to get the $uid from the processDatamap_afterDatabaseOperations you need to add this code before you get the instance of the fileRepository.

if (GeneralUtility::isFirstPartOfStr($uid, 'NEW')) {
    $uid = $pObj->substNEWwithIDs[$uid];
 }

Now as far as the text concerns, i extracted from a pdf. First i had to get the basename of the file in order to find its storage location and its name. Since i have only one file i don't really need a foreach loop and i can use the [0] as well. So the code looked like this:

$fileID = $fileObjects[0]->getOriginalFile()->getProperties()['uid'];
$fullPath[] = [PathUtility::basename($fileObjects[0]->getOriginalFile()->getStorage()->getConfiguration()['basePath']), PathUtility::basename($fileObjects[0]->getOriginalFile()->getIdentifier())];

This, gives me back an array looking like this:

array(1 item)
   0 => array(2 items)
      0 => 'fileadmin' (9 chars)
      1 => 'MyPdf.pdf' (9 chars)

Now i need to save the text from every page in a variable. So the code looks like this:

$getPdfText = '';
foreach ($fullPath as $file) {
    $parser = new Parser();
    $pdf    = $parser->parseFile(PATH_site . $file[0] . '/' . $file[1]);
    $pages  = $pdf->getPages();
    foreach ($pages as $page) {
         $getPdfText .= $page->getText();
     }
  }

Now that i have my text i want to add it on the database so i will be able to use it on my search action. I now use the connection pool to get the file from the sys_file.

$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file');
$queryBuilder
      ->update('sys_file')
      ->where(
          $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($fileID))
        )
        ->set('pdf_text', $getPdfText)
        ->execute();

Now everytime i choose a PDF from my extension, i save its text on the database.

EXTRA CONTENT

If you want to include the PDFParser as well and you are on composer mode, then add this on your composer.json:

"smalot/pdfparser" : "*"

and on the autoload:

"Smalot\\PdfParser\\" : "Packages/smalot/pdfparser/src/"

Then under: yourExtension/Classes/Hooks/DataHandler.php add the namespace:

use Smalot\PdfParser\Parser;

Now you are able to use the getPages() and getText() functions.

The Documentation

If i missed something let me know and i will add it.

查看更多
登录 后发表回答