0

这个概念是,在成功保存我的对象后,它应该更新数据库中的文本(使用 Hook)。让我们称该字段为“ succText ”。我想访问的表是 sys_file 但我只在保存对象时获得 sys_file_reference id。所以我想我可以使用 ConnectionPool 来选择这个文件引用的 sys_file,然后在字段“ succText ”上插入数据。

我试过这个:

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();
}

但这给了我 sys_file_reference id,而不是 sys_file 表的 id 和字段值。

至于更新,我还没有尝试过,因为我还没有弄清楚如何获取需要更新的行。我猜想在找到行后使用子查询,我真的不知道。

processDatamap_preProcessFieldArray将被重命名为 post。我只有这种方式才能在后端获得结果。

提前致谢,

4

2 回答 2

1

您可能想在此处使用 FileRepository 类。

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

其中 $uid 是文件通过文件引用连接到的记录的 ID。

您将返回要处理的文件对象数组。

于 2019-04-15T14:37:13.073 回答
1

我通过删除第一个代码并添加一个文件存储库实例解决了我的问题。

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

很重要!

如果您正在创建一个新元素,那么 TYPO3 会分配一个临时UID变量,其名称类似于NEW45643476。为了从 processDatamap_afterDatabaseOperations 中获取 $uid,您需要在获取 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 Smalot\PdfParser\Parser;

现在您可以使用getPages()getText()功能了。

文档_

如果我错过了什么,请告诉我,我会添加它。

于 2019-04-16T05:38:55.767 回答