You are here

function fillpdf_execute_parse in FillPDF 7

Same name and namespace in other branches
  1. 6 fillpdf.module \fillpdf_execute_parse()
  2. 7.2 fillpdf.module \fillpdf_execute_parse()

Utility to allow other functions to parse PDFs.

Utility function to allow other functions to parse PDFs with the various methods in a consistent way.

Parameters

string $method: The service or program being used. Possible values: local, remote, pdftk.

mixed $fillpdf: When in URL mode, this is the filename to the PDF to parse. When in Stream mode, this is the PDF data.

string $mode: A special flag to control the behavior of this function. URL mode parses using a PDF on the file system and Stream mode merges using the value of $fillpdf directly. Possible values: url, stream.

Return value

array|false The parsed fields.

1 call to fillpdf_execute_parse()
fillpdf_parse_pdf in ./fillpdf.module
This function generates the form fields from the specified PDF.

File

./fillpdf.module, line 1717

Code

function fillpdf_execute_parse($method, $fillpdf, $mode = 'url') {
  switch ($mode) {
    case 'url':
      $filename = $fillpdf;
      $content = _fillpdf_get_file_contents($filename, "<front>");
      break;
    case 'stream':
      $filename = file_unmanaged_save_data($fillpdf, file_directory_temp() . '/pdf_data.pdf', FILE_EXISTS_RENAME);
      $content = $fillpdf;
      break;
  }
  switch ($method) {
    case 'remote':
      $result = _fillpdf_xmlrpc_request(FILLPDF_DEFAULT_SERVLET_URL, 'parse_pdf_fields', base64_encode($content));
      if ($result->error == TRUE) {
        if ($mode == 'stream') {
          file_unmanaged_delete($filename);
        }

        // After error message set in _fillpdf_xmlrpc_request().
        return FALSE;
      }
      $fields = $result->data;
      break;
    case 'local_service':
      $request = array(
        'pdf' => base64_encode($content),
      );
      $json = drupal_json_encode($request);
      $parse_endpoint = variable_get('fillpdf_local_service_endpoint') . '/api/v1/parse';
      $result = drupal_http_request($parse_endpoint, array(
        'method' => 'POST',
        'data' => $json,
        'headers' => array(
          'Content-Type' => 'application/json',
        ),
      ));
      if ((int) $result->code !== 200) {
        if ($result->code) {
          drupal_set_message('Error ' . $result->code . '. Reason: ' . $result->error, 'error');
        }
        else {
          drupal_set_message('Error occurred parsing PDF: ' . $result->error, 'error');
        }
        $fields = array();
        break;
      }
      $fields = drupal_json_decode($result->data);
      break;
    case 'local':
      $require = drupal_get_path('module', 'fillpdf') . '/lib/JavaBridge/java/Java.inc';
      require_once DRUPAL_ROOT . '/' . $require;
      try {
        $fillpdf = new java('com.ocdevel.FillpdfService', base64_encode($content), 'bytes');
        $fields = java_values($fillpdf
          ->parse());
      } catch (JavaException $e) {
        if ($mode == 'stream') {
          file_unmanaged_delete($filename);
        }
        $error = check_plain(java_truncate((string) $e));
        drupal_set_message($error, 'error');
        watchdog('fillpdf', $error, array(), WATCHDOG_ERROR);

        // After setting error message.
        return FALSE;
      }
      break;
    case 'pdftk':
      $path_to_pdftk = fillpdf_pdftk_path();
      $status = fillpdf_pdftk_check($path_to_pdftk);
      if ($status === FALSE) {
        drupal_set_message(t('pdftk not properly installed.'), 'error');
        return array();
      }

      // Use exec() to call pdftk (because it will be easier to go line-by-line
      // parsing the output) and pass $content via stdin. Retrieve the fields
      // with dump_data_fields_utf8.
      $output = array();
      $pdftk_command = array();
      $pdftk_command[] = $path_to_pdftk;
      $pdftk_command[] = escapeshellarg(drupal_realpath($filename));
      $pdftk_command[] = 'dump_data_fields_utf8';
      exec(implode(' ', $pdftk_command), $output, $status);
      if (count($output) === 0) {
        drupal_set_message(t('PDF does not contain fillable fields.'), 'warning');
        return array();
      }

      // Build a simple map of dump_data_fields_utf8 keys to our own array keys.
      $data_fields_map = array(
        'FieldType' => 'type',
        'FieldName' => 'name',
        'FieldFlags' => 'flags',
        'FieldJustification' => 'justification',
      );

      // Build the fields array.
      $fields = array();
      $fieldindex = -1;
      foreach ($output as $line => $lineitem) {
        if ($lineitem == '---') {
          $fieldindex++;
          continue;
        }

        // Separate the data key from the data value.
        list($key, $value) = explode(':', $lineitem);
        if (in_array($key, array_keys($data_fields_map))) {
          $fields[$fieldindex][$data_fields_map[$key]] = trim($value);
        }
      }
      break;
    case 'test':
      $fields = array(
        0 => array(
          'name' => 'ImageField',
          'value' => '',
          'type' => 'Pushbutton',
        ),
        1 => array(
          'name' => 'Button',
          'value' => '',
          'type' => 'Pushbutton',
        ),
        2 => array(
          'name' => 'TextField',
          'value' => '',
          'type' => 'Text',
        ),
        // Test field name only different in case.
        3 => array(
          'name' => 'textfield',
          'value' => '',
          'type' => 'Text',
        ),
        // Test duplicate field name that should be consolidated.
        4 => array(
          'name' => 'ImageField',
          'value' => '',
          'type' => 'Pushbutton',
        ),
      );
      break;
  }
  if ($mode == 'stream') {
    file_unmanaged_delete($filename);
  }
  return $fields;
}