Files
stemcell/app/code/Stemcell/Catalog/Console/Command/ProtocolsDocumentationPdfUpdate.php
2026-09-15 10:26:34 +08:00

163 lines
6.0 KiB
PHP

<?php
namespace Stemcell\Catalog\Console\Command;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\State;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\StateException;
use Magento\Framework\UrlInterface;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Exception;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
/**
* 更新产品详情的产品说明书及文档中PDF的URL,如果PDF在服务器上存在,就用当前域名替换pdf的域名。
*/
class ProtocolsDocumentationPdfUpdate extends Command
{
private OutputInterface $output;
private string $baseUrl;
private array $notExistPdf = [];
public function __construct(
private ProductCollection $productCollection,
private DirectoryList $directoryList,
private UrlInterface $url,
private ProductRepository $productRepository,
private State $state,
private \Magento\Store\Model\StoreManagerInterface $storeManager,
) {
parent::__construct('protocols:documentation:update');
}
protected function updatePdfUrl(Product $product){
$html = $product->getData('protocols_documentation');
$html = preg_replace('/<\/?body[^>]*>/i', '', $html);
$dom = new \DOMDocument();
libxml_use_internal_errors(true); // 避免 HTML 解析警告
$dom->loadHTML(mb_encode_numericentity($html, [0x80, 0x10FFFF, 0, ~0], 'UTF-8'));
libxml_clear_errors();
$links = $dom->getElementsByTagName('a');
foreach ($links as $link) {
$href = $link->getAttribute('href');
// $output->writeln('old pdf href: ' . $href);
if ($href && preg_match('/\.pdf$/i', $href)) {
$pdfPath = parse_url($href, PHP_URL_PATH);
$pdfPath = $this->directoryList->getPath(DirectoryList::PUB).'/'.$pdfPath;
// 检查 PDF 是否存在
if (file_exists($pdfPath)) {
$this->output->writeln(sprintf('product %s old pdf href: %s', $product->getSku(), $href));
$newUrl = preg_replace(
'#^https?://[^/]+/#i',
$this->baseUrl,
$href
);
$this->output->writeln(sprintf('<info>product %s updated pdf href: %s</info>', $product->getSku(), $newUrl));
// 更新 <a> 标签的 href
$link->setAttribute('href', $newUrl);
} else {
$md5 = md5(strtolower($href));
if (!isset($this->notExistPdf[$md5])) {
$this->notExistPdf[$md5] = $href;
}
}
}
}
$body = $dom->getElementsByTagName("body")->item(0);
return $dom->saveHTML($body);
}
/**
* @throws Exception
* @throws FileSystemException
*/
protected function exportNotExistPdf()
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->getStyle('A1:' . 'B1')->getFont()->setBold(true);
$sheet->setCellValue('A1', 'pdf links');
$rowIndex = 2;
foreach ($this->notExistPdf as $link) {
// $sheet->setCellValue('B' . $rowIndex, implode("\n", $links));
$sheet->getStyle('A' . $rowIndex)->getAlignment()->setWrapText(true);
$sheet->setCellValueExplicit('A' . $rowIndex, $link, DataType::TYPE_STRING);
$sheet->getColumnDimension('A')->setWidth(100);
$rowIndex++;
}
$writer = new Xlsx($spreadsheet);
$pdfPath = $this->directoryList->getPath(DirectoryList::VAR_DIR).'/share/产品说明书及文档不存在的PDF-'.date('Ymd').'.xlsx';
$writer->save($pdfPath);
}
public function execute(InputInterface $input, OutputInterface $output)
{
$this->state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML);
$this->output = $output;
$this->baseUrl = $this->url->getBaseUrl();
foreach ($this->storeManager->getStores(true) as $store) {
$collection = $this->productCollection
->setStoreId($store->getId())
->addAttributeToFilter('protocols_documentation', ['neq' => 'NULL']);
foreach ($collection as $product) {
// if ($product->getSku()=='100-0237_C') {
// $output->writeln(preg_replace('/<\/?body[^>]*>/i', '', $product->getData('protocols_documentation')));
// } else {
// continue;
// }
$output->writeln(sprintf('product: %s', $product->getSku()));
$html = preg_replace('/<\/?body[^>]*>/i', '', $this->updatePdfUrl($product));
// $output->writeln('updated html: ');
// $output->writeln($html);
// $output->writeln('');
$product->setData('protocols_documentation', $html);
try {
$product->setData('_edit_mode', true);
$product->setStoreId($store->getId());
$this->productRepository->save($product);
} catch (\Exception $e) {
$this->output->writeln(sprintf('<error>product %s updated pdf fail, msg: %s</error>', $product->getSku(), $e->getMessage()));
}
// if ($product->getSku()=='100-0237_C') {
// break;
// }
}
}
$this->exportNotExistPdf();
return Command::SUCCESS;
}
}