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,
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.
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.