allow setting some dompdf options
authordemeritcowboy <demeritcowboy@hotmail.com>
Fri, 17 Sep 2021 19:31:53 +0000 (15:31 -0400)
committerdemeritcowboy <demeritcowboy@hotmail.com>
Fri, 17 Sep 2021 19:31:53 +0000 (15:31 -0400)
CRM/Admin/Form/Setting/Miscellaneous.php
CRM/Utils/PDF/Utils.php
settings/Core.setting.php
templates/CRM/Admin/Form/Setting/Miscellaneous.tpl
tests/phpunit/CRM/Utils/PDF/UtilsTest.php [new file with mode: 0644]

index 1540e6a52d3e7c736534908313b1a3795c0c0848..dfe75c761fa72366ddef5a849efbc43dce69fb40 100644 (file)
@@ -31,6 +31,9 @@ class CRM_Admin_Form_Setting_Miscellaneous extends CRM_Admin_Form_Setting {
     'recordGeneratedLetters' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'secondDegRelPermissions' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'checksum_timeout' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
+    'dompdf_font_dir' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
+    'dompdf_chroot' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
+    'dompdf_enable_remote' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'wkhtmltopdfPath' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'recentItemsMaxCount' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'recentItemsProviders' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
index 2459ce3af24d252599e6b4f2de72e23519e4fd48..8c97d681a80569fe7fb17460ffde7d3568969215 100644 (file)
@@ -179,10 +179,7 @@ class CRM_Utils_PDF_Utils {
    * @return string
    */
   public static function _html2pdf_dompdf($paper_size, $orientation, $html, $output, $fileName) {
-    // CRM-12165 - Remote file support required for image handling.
-    $options = new Options();
-    $options->set('isRemoteEnabled', TRUE);
-
+    $options = self::getDompdfOptions();
     $dompdf = new DOMPDF($options);
     $dompdf->set_paper($paper_size, $orientation);
     $dompdf->load_html($html);
@@ -300,4 +297,28 @@ class CRM_Utils_PDF_Utils {
     return $value;
   }
 
+  /**
+   * Allow setting some dompdf options.
+   *
+   * We don't support all the available dompdf options.
+   *
+   * @return \Dompdf\Options
+   */
+  private static function getDompdfOptions(): Options {
+    $options = new Options();
+    $settings = [
+      // CRM-12165 - Remote file support required for image handling so default to TRUE
+      'enable_remote' => \Civi::settings()->get('dompdf_enable_remote') ?? TRUE,
+    ];
+    // only set these ones if a setting exists for them
+    foreach (['font_dir', 'chroot', 'log_output_file'] as $setting) {
+      $value = \Civi::settings()->get("dompdf_$setting");
+      if (isset($value)) {
+        $settings[$setting] = $value;
+      }
+    }
+    $options->set($settings);
+    return $options;
+  }
+
 }
index 64778e4d87bae74397b25d45c6abe335db0be7e8..b01373382d6a9be22c9810fb973948f851827d33 100644 (file)
@@ -529,6 +529,78 @@ return [
       'callback' => 'CRM_Contact_Form_Task_PDFLetterCommon::getLoggingOptions',
     ],
   ],
+  'dompdf_font_dir' => [
+    'is_domain' => 1,
+    'is_contact' => 0,
+    'group_name' => 'CiviCRM Preferences',
+    'group' => 'core',
+    'name' => 'dompdf_font_dir',
+    'title' => ts('DOMPDF Font Folder'),
+    'description' => ts('Additional folder where DOMPDF will look for fonts.'),
+    'type' => 'String',
+    'quick_form_type' => 'Element',
+    'html_type' => 'text',
+    'html_attributes' => [
+      'size' => 64,
+      'maxlength' => 256,
+    ],
+    'default' => NULL,
+    'help_text' => NULL,
+    'add' => '5.43',
+  ],
+  'dompdf_chroot' => [
+    'is_domain' => 1,
+    'is_contact' => 0,
+    'group_name' => 'CiviCRM Preferences',
+    'group' => 'core',
+    'name' => 'dompdf_chroot',
+    'title' => ts('DOMPDF Local Images Folder'),
+    'description' => ts('Folder to restrict where DOMPDF looks when loading local images. By default it is the DOMPDF folder itself for security reasons. It will search in subfolders.'),
+    'type' => 'String',
+    'quick_form_type' => 'Element',
+    'html_type' => 'text',
+    'html_attributes' => [
+      'size' => 64,
+      'maxlength' => 256,
+    ],
+    'default' => NULL,
+    'help_text' => NULL,
+    'add' => '5.43',
+  ],
+  'dompdf_enable_remote' => [
+    'is_domain' => 1,
+    'is_contact' => 0,
+    'group_name' => 'CiviCRM Preferences',
+    'group' => 'core',
+    'name' => 'dompdf_enable_remote',
+    'title' => ts('DOMPDF Enable Remote Images'),
+    'description' => ts('Enable the use of remote images. By default this is enabled, but if not using remote images you may wish to turn it off for security reasons.'),
+    'type' => 'Boolean',
+    'quick_form_type' => 'YesNo',
+    'html_type' => '',
+    'default' => TRUE,
+    'help_text' => NULL,
+    'add' => '5.43',
+  ],
+  'dompdf_log_output_file' => [
+    'is_domain' => 1,
+    'is_contact' => 0,
+    'group_name' => 'CiviCRM Preferences',
+    'group' => 'core',
+    'name' => 'dompdf_log_output_file',
+    'title' => ts('DOMPDF Log File'),
+    'description' => ts('DOMPDF will log debugging output in this file.'),
+    'type' => 'String',
+    'quick_form_type' => 'Element',
+    'html_type' => 'text',
+    'html_attributes' => [
+      'size' => 64,
+      'maxlength' => 256,
+    ],
+    'default' => NULL,
+    'help_text' => NULL,
+    'add' => '5.43',
+  ],
   'wkhtmltopdfPath' => [
     'group_name' => 'CiviCRM Preferences',
     'group' => 'core',
index 6b761b840eabe38d8304223a833faf29c1f06f2c..bb7fc8892cf3b741b26a29abaf4348098ef97fea 100644 (file)
           <p class="description">{ts}When generating a letter (PDF/Word) via mail-merge, how should the letter be recorded?{/ts}</p>
         </td>
       </tr>
+      <tr class="crm-miscellaneous-form-block-dompdf_font_dir">
+        <td class="label">{$form.dompdf_font_dir.label}</td>
+        <td>{$form.dompdf_font_dir.html}<br />
+          <p class="description">{ts}Additional folder where DOMPDF will look for fonts.{/ts}</p>
+        </td>
+      </tr>
+      <tr class="crm-miscellaneous-form-block-dompdf_chroot">
+        <td class="label">{$form.dompdf_chroot.label}</td>
+        <td>{$form.dompdf_chroot.html}<br />
+          <p class="description">{ts}Folder to restrict where DOMPDF looks when loading local images. By default it is the DOMPDF folder itself for security reasons. It will search in subfolders.{/ts}</p>
+        </td>
+      </tr>
+      <tr class="crm-miscellaneous-form-block-dompdf_enable_remote">
+        <td class="label">{$form.dompdf_enable_remote.label}</td>
+        <td>{$form.dompdf_enable_remote.html}<br />
+          <p class="description">{ts}Enable the use of remote images. By default this is enabled, but if not using remote images you may wish to turn it off for security reasons.{/ts}</p>
+        </td>
+      </tr>
       <tr class="crm-miscellaneous-form-block-wkhtmltopdfPath">
         <td class="label">{$form.wkhtmltopdfPath.label}</td>
         <td>{$form.wkhtmltopdfPath.html}<br />
diff --git a/tests/phpunit/CRM/Utils/PDF/UtilsTest.php b/tests/phpunit/CRM/Utils/PDF/UtilsTest.php
new file mode 100644 (file)
index 0000000..fbc459f
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Class CRM_Utils_PDF_UtilsTest
+ * @group headless
+ */
+class CRM_Utils_PDF_UtilsTest extends CiviUnitTestCase {
+
+  /**
+   * Test user-supplied settings for DOMPDF
+   */
+  public function testDOMPDFSettings() {
+    $old_setting = \Civi::settings()->get('dompdf_log_output_file');
+
+    $log_file = tempnam(sys_get_temp_dir(), 'pdf');
+    \Civi::settings()->set('dompdf_log_output_file', $log_file);
+
+    $pdf_output = CRM_Utils_PDF_Utils::html2pdf('<p>Some output</p>', 'civicrm.pdf', TRUE);
+    // Not much of a test but this isn't the main thing we're testing.
+    $this->assertEquals('%PDF', substr($pdf_output, 0, 4));
+
+    // If the setting worked, we should have some debug output in this file.
+    // The exact contents might change between dompdf versions but it's likely
+    // to contain a span tag.
+    // If this is too brittle, it might be ok to just check it's not empty,
+    // since if it's empty then our setting didn't work.
+    $this->assertStringContainsString('<span', file_get_contents($log_file));
+    unlink($log_file);
+
+    \Civi::settings()->set('dompdf_log_output_file', $old_setting);
+  }
+
+}