#typo3 #hook #typo3-8.x #filereference #connection-pool
#typo3 #перехват #typo3-8.x #ссылка на файл #соединение-пул
Вопрос:
Концепция заключается в том, что после успешного сохранения моего объекта он должен обновить текст в базе данных (с помощью Hook). Давайте назовем поле ‘SUCCECTEXT‘. Таблица, к которой я хотел бы получить доступ, — это sys_file, но я получаю идентификатор sys_file_reference только при сохранении объекта. Поэтому я подумал, что могу использовать ConnectionPool, чтобы выбрать строку sys_file этой ссылки на файл, а затем вставить данные в поле ‘SUCCECTEXT‘.
Я попробовал это:
public function processDatamap_preProcessFieldArray(array amp;$fieldArray, $table, $id, TYPO3CMSCoreDataHandlingDataHandler amp;$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();
}
Но это возвращает мне идентификатор sys_file_reference, а не идентификатор и значения полей таблицы sys_file.
Что касается обновления, я еще не пробовал, потому что я еще не понял, как получить строку, которую необходимо обновить. Я догадываюсь с помощью подзапроса после того, как строка найдена, я действительно не знаю.
processDatamap_preProcessFieldArray будет переименован в post . У меня это только для того, чтобы получить результаты на серверной части.
Заранее спасибо,
Ответ №1:
Возможно, вы захотите использовать класс FileRepository здесь.
$fileRepository = GeneralUtility::makeInstance(TYPO3CMSCoreResourceFileRepository::class);
$fileObjects = $fileRepository->findByRelation('tablename', 'fieldname', $uid);
Где $uid — это идентификатор записи, к которой файлы подключены через ссылку на файл.
Вы получите обратно массив файловых объектов для обработки.
Комментарии:
1. Да, я уже это сделал, и я решил проблему. В любом случае спасибо 🙂
2. Поэтому, не могли бы вы, пожалуйста, пометить ответ как правильный, а вопрос — как ответ на него, чтобы другие люди могли найти его позже?
Ответ №2:
Я решил свою проблему, удалив первый код и добавив экземпляр filerepository.
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
$fileObjects = $fileRepository->findByRelation('targetTable', 'targetField', $uid);
ОЧЕНЬ ВАЖНО!
Если вы создаете новый элемент, то TYPO3 присваивает временной переменной UID имя, которое выглядит как это NEW45643476 . Чтобы получить $uid из processDatamap_afterDatabaseOperations, вам нужно добавить этот код, прежде чем вы получите экземпляр FileRepository.
if (GeneralUtility::isFirstPartOfStr($uid, 'NEW')) {
$uid = $pObj->substNEWwithIDs[$uid];
}
Теперь, что касается текста, я извлек его из PDF-файла. Сначала мне нужно было получить базовое имя файла, чтобы найти его местоположение для хранения и его имя. Поскольку у меня есть только один файл, мне действительно не нужен цикл foreach, и я также могу использовать [0] . Итак, код выглядел примерно так:
$fileID = $fileObjects[0]->getOriginalFile()->getProperties()['uid'];
$fullPath[] = [PathUtility::basename($fileObjects[0]->getOriginalFile()->getStorage()->getConfiguration()['basePath']), PathUtility::basename($fileObjects[0]->getOriginalFile()->getIdentifier())];
Это возвращает мне массив, выглядящий следующим образом:
array(1 item)
0 => array(2 items)
0 => 'fileadmin' (9 chars)
1 => 'MyPdf.pdf' (9 chars)
Теперь мне нужно сохранить текст с каждой страницы в переменной. Итак, код выглядит следующим образом:
$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();
}
}
Теперь, когда у меня есть свой текст, я хочу добавить его в базу данных, чтобы иметь возможность использовать его при поиске. Теперь я использую пул подключений, чтобы получить файл из 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();
Теперь каждый раз, когда я выбираю PDF-файл из своего расширения, я сохраняю его текст в базе данных.
ДОПОЛНИТЕЛЬНЫЙ КОНТЕНТ
Если вы также хотите включить PDFParser и находитесь в режиме composer, добавьте это в свой composer.json:
"smalot/pdfparser" : "*"
и на автозагрузке:
"Smalot\PdfParser\" : "Packages/smalot/pdfparser/src/"
Затем в разделе: yourExtension/Classes/Hooks/DataHandler.php добавьте пространство имен:
use SmalotPdfParserParser;
Теперь вы можете использовать функции getPages()
и. getText()
Если я что-то пропустил, дайте мне знать, и я добавлю это.