Problem/Motivation
The module breaks when trying to view a PDF generated using views_pdf if the display has a header. This is because
FPDI->_format_header_footer() uses format_string() - a Drupal function which was deprecated in Drupal 8 and removed in Drupal 9.
Steps to reproduce
- Install Drupal 10
- Install views_pdf and dependencies using composer
- Create a new view
- Add a PDF display and give it a path
- View the PDF display at the path you gave it
- Add any Views Header (I've tried Global: Text area, Global: Unfiltered text and Global: View area) and save the view.
- View the PDF display at the path you gave it
- The view is now broken with the error
- Error: Call to undefined function Drupal\views_pdf\PdfLibrary\format_string() in Drupal\views_pdf\PdfLibrary\FPDI->_format_header_footer() (line 198 of [snip]/web/modules/contrib/views_pdf/src/PdfLibrary/FPDI.php).
Proposed resolution
Use \Drupal\Component\Render\FormattableMarkup instead of format_string()
So far I've not had massive success, but I'm working on it. But would welcome any assistance.
I've tried changing the original function from
function _format_header_footer($h_f) {
$display = $this->display;
// Get the leading/trailing header/footer option (e.g. "succeed_header").
if ((empty($this->position) || $this->position == 'closing' || $display->getOption("{$this->position}_{$h_f}")) &&
!empty($rendered = $display->renderArea("$h_f"))) {
$this->SetTextColorArray($display->getOption("{$h_f}_font_color"));
$this->SetFont(
$display->getOption("{$h_f}_font_family"),
implode('', $display->getOption("{$h_f}_font_style")),
$display->getOption("{$h_f}_font_size")
);
$yvar = "y_$h_f";
$this->writeHTMLCell(0, 0,
(float)$this->lMargin, (float)$this->$yvar,
format_string($rendered, array('!page' => $this->getPage())),
0, 0,
FALSE, TRUE,
$display->getOption("{$h_f}_text_align")
);
}
if ($h_f == 'footer' && $this->position == 'closing') {
$this->position = 'succeed';
}
}
to this
use Drupal\Component\Render\FormattableMarkup;
function _format_header_footer($h_f) {
$display = $this->display;
// Get the leading/trailing header/footer option (e.g. "succeed_header").
if ((empty($this->position) || $this->position == 'closing' || $display->getOption("{$this->position}_{$h_f}")) &&
!empty($rendered = $display->renderArea("$h_f"))) {
$this->SetTextColorArray($display->getOption("{$h_f}_font_color"));
$this->SetFont(
$display->getOption("{$h_f}_font_family"),
implode('', $display->getOption("{$h_f}_font_style")),
$display->getOption("{$h_f}_font_size")
);
$yvar = "y_$h_f";
$text = new FormattableMarkup($rendered, array('!page' => $this->getPage()));
$this->writeHTMLCell(0, 0,
(float)$this->lMargin, (float)$this->$yvar,
$text,
0, 0,
FALSE, TRUE,
$display->getOption("{$h_f}_text_align")
);
}
if ($h_f == 'footer' && $this->position == 'closing') {
$this->position = 'succeed';
}
}
which stops it breaking, but is passing in the header as an array. So far I've not quite worked out how to resolve that.