droe9376 2015-11-19 13:39
浏览 70
已采纳

使用PhantomJS Capture模块创建块

I've added a PhantomJS Capture module to my Drupal website. Test function showed my configuration works and I can use it from an administration interface. Now, I want to put it on a website, as a custom block. I added this piece of the code at the end of the module, so the form appears on the website.

/**
* Implements hook_block_info().
*/

function phantomjs_capture_block_info() {
  $blocks = array();
  $blocks['Scraping Block'] = array(
    'info' => t('scraping block'),
  );
  return $blocks;
}

/**
* Implements hook_block_view().
*/

function phantomjs_capture_block_view($delta = '') {
  $block = array();
  switch ($delta) {
    case 'Scraping Block':
      $block['subject'] = 'Scraper';
      $block['content'] = phantomjs_capture_admin_form();
      break;
  }
  return $block;
}

However ajax callback is not firing on submit. What's wrong with the code or my understanding of this module? Thanks.

This is all code I've got in phantomjs_capture.module, I haven't changed any other files.

<?php
/**
 * @file
 * Defines the administration interface and utility functions to use PhantomJS
 * and test screenshot capture functions.
 */


// @todo: hook_help.

/**
 * Implements hook_menu().
 */
function phantomjs_capture_menu() {
  $items = array();

  $items['admin/config/user-interface/phantomjs_capture'] = array(
    'title' => 'PhantomJS Screen capture',
    'description' => 'Screen capture with PhantomJS',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('phantomjs_capture_admin_form'),
    'access arguments' => array('adminster site'),
  );

  return $items;
}

/**
 * The administration form that allows site admins to enter information about
 * the systems installation of PhantomJS.
 *
 * @return array $form
 *  Drupal form array witht the administration form.
 */
function phantomjs_capture_admin_form() {
  $form = array();

  $form['phantomjs_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('PhantomJS settings'),
    '#collapsible' => FALSE,
  );

  $form['phantomjs_settings']['phantomjs_capture_binary'] = array(
    '#type' => 'textfield',
    '#required' => TRUE,
    '#title' => t('Path to phantomJS'),
    '#description' => t('This module requries that you install PhantomJS on your server and enter the path to the executable. The program is not include in the module due to linces and operation system constrains. See !url for information about download.', array(
      '!url' => l('PhantomJs.org', 'http://phantomjs.org/'),
    )),
    '#default_value' => variable_get('phantomjs_capture_binary', _phantomjs_capture_get_binray()),
  );

  $form['phantomjs_settings']['phantomjs_capture_dest'] = array(
    '#type' => 'textfield',
    '#required' => TRUE,
    '#title' => t('Default destination'),
    '#description' => t('The default destination for screenshots captures with PhantomJS'),
    '#default_value' => variable_get('phantomjs_capture_dest', 'phantomjs'),
  );

  $form['phantomjs_settings']['phantomjs_capture_script'] = array(
    '#type' => 'textfield',
    '#required' => TRUE,
    '#title' => t('PhantomJS capture script'),
    '#description' => t('The script used by PhantomJS to capture the screen. It captures full HD images (1920 x 1080).'),
    '#default_value' => variable_get('phantomjs_capture_script', drupal_get_path('module', 'phantomjs_capture') . '/js/phantomjs_capture.js'),
  );

  $form['phantomjs_capture_test'] = array(
    '#type' => 'fieldset',
    '#title' => t('Phantom JS test'),
    '#description' => t('You can use the form in this section to test your installation of PhantomJS.'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#tree' => TRUE,
  );

  $form['phantomjs_capture_test']['url'] = array(
    '#type' => 'textfield',
    '#title' => t('URL'),
    '#description' => t('Absolute URL to the homepage that should be capture (it has to be a complet URL with http://).'),
    '#default_value' => 'http://www.google.com',
  );

  $form['phantomjs_capture_test']['format'] = array(
    '#type' => 'select',
    '#title' => 'File format',
    '#options' => array(
      '.png' => 'png',
      '.jpg' => 'jpg',
      '.pdf' => 'pdf',
    ),
  );

  $form['phantomjs_capture_test']['result'] = array(
    '#prefix' => '<div id="phantomjs-capture-test-result">',
    '#suffix' => '</div>',
    '#markup' => '',
  );

  $form['phantomjs_capture_test']['button'] = array(
    '#type' => 'button',
    '#value' => t('Capture'),
    "#ajax" => array(
      "callback" => "phantomjs_capture_test_submit",
      "wrapper" => "phantomjs-capture-test-result",
      "method" => 'replace',
      "effect" => "fade"
    )
  );

  return $form;
}

/**
 * Ajax callback for the test PhantomJS form on the administration page.
 *
 * @param type $form
 * @param type $form_state
 * @return type
 */
function phantomjs_capture_test_submit($form, $form_state) {
  // Build urls and destionation.
  $url = $form_state['values']['phantomjs_capture_test']['url'];
  $file = 'test' . $form_state['values']['phantomjs_capture_test']['format'];
  $dest = file_default_scheme() . '://' . variable_get('phantomjs_capture_dest', 'phantomjs');

  // Get the screenshot and create success/error message.
  $output = '<div class="messages status"><ul><li>' . t('File have been generated. You can get it !url', array('!url' => l(t('here'), file_create_url($dest . '/' . $file)))) . '.</ul></li></div>';
  if (!phantomjs_capture_screen($url, $dest, $file)) {
    $output = '<div class="messages error"><ul><li>' . t('The address entered could not be retrieved.') . '</ul></li></div>';
  }

  // Return
  return array(
   'phantomjs_capture_test' => array(
     'result' => array(
       '#prefix' => '<div id="phantomjs-capture-test-result">',
       '#suffix' => '</div>',
       '#markup' => $output,
      ),
    ),
  );
}

/**
 * Validation of the administration form. It tests that the locations given
 * exists and that the PhantomJS binary is executable (by getting its version
 * number).
 *
 * @param type $form
 * @param type $form_state
 */
function phantomjs_capture_admin_form_validate(&$form, &$form_state) {
  // Check that phantomjs exists.
  if (!file_exists($form_state['values']['phantomjs_capture_binary'])) {
    form_set_error('phantomjs_capture_binary', t('PhantomJS was not found at the location given.'));
  }
  else {
    // Only show version message on "Save configuration" submit.
    if ($form_state['clicked_button']['#value'] == t('Save configuration')) {
      drupal_set_message(t('PhantomJS version @version found.', array(
        '@version' => _phantomjs_capture_get_version($form_state['values']['phantomjs_capture_binary']),
      )));
    }
  }

  // Check that destination can be created.
  $dest = file_default_scheme() . '://' . $form_state['values']['phantomjs_capture_dest'];
  if (!file_prepare_directory($dest, FILE_CREATE_DIRECTORY)) {
    form_set_error('phantomjs_capture_dest', t('The path was not writeable or could not be created.'));
  }

  // Check that capture script exists.
  if (!file_exists($form_state['values']['phantomjs_capture_script'])) {
    form_set_error('phantomjs_capture_script', t('PhantomJS script was not found at the location given.'));
  }

  // Remove test form.
  unset($form_state['values']['phantomjs_capture_test']);
}

/**
 * Returns the version number of the currently install PhantomJS.
 *
 * @param string $binary
 *  Optional absolute path with the PhantomJS binary. If not given the default
 *  location is used.
 * @return string|boolean
 *  If PhantomJS is found and executeable the version number is returned else
 *  FALSE is returned.
 */
function _phantomjs_capture_get_version($binary = NULL) {
  // If the binary is not given try the default path.
  if (is_null($binary)) {
    $binary = _phantomjs_capture_get_binray();
    if (!$binary) {
      drupal_set_message(t('PhantomJS binary was not found. Plase intall PhantomJS on the system.'));
      return FALSE;
    }
  }

  // Execute PhantomJS to get its version, if PhantomJS was found.
  $output = array();
  exec($binary . ' -v', $output);
  return $output[0];
}

/**
 * Returns the absolute path with the binray to the installed PhantomJS.
 *
 * @return string|boolean
 *  The executable PhantomJS binary or FALSE if not found.
 */
function _phantomjs_capture_get_binray() {
  $binary = variable_get('phantomjs_capture_binary', '/usr/local/bin/phantomjs');
  if (!file_exists($binary)) {
    return FALSE;
  }
  return $binary;
}

/**
 * Captures a screenshot using PhantomJS by calling the program.
 *
 * @param string $url
 *  The ULR/http(s) to render the screenshot from.
 * @param type $dest
 *  The destionation for the rendered file (e.g. public://fecthed_images).
 * @param type $filename
 *  The filename to store the file as in the destination.
 * @param type $element
 *  The id of the DOM element to render in the document.
 * @return boolean
 *  Returns TRUE if the screenshot was taken else FALSE on error.
 */
function phantomjs_capture_screen($url, $dest, $filename, $element = NULL) {
  // Get PhantomJS binary.
  $binary = _phantomjs_capture_get_binray();
  if (!$binary) {
    drupal_set_message(t('PhantomJS binary was not found. Plase intall PhantomJS on the system.'));
    return FALSE;
  }

  // Check that destination is writeable.
  if (!file_prepare_directory($dest, FILE_CREATE_DIRECTORY)) {
    drupal_set_message(t('The PhantomJS destination path (@dest) was not writeable or could not be created.', array(
      '@dest' => $dest,
    )));
    return FALSE;
  }

  // Get absolute path to PhantomJS script and the destionation file.
  $script = realpath(variable_get('phantomjs_capture_script', drupal_get_path('module', 'phantomjs_capture') . '/js/phantomjs_capture.js'));
  $dest = drupal_realpath($dest . '/' . $filename);

  // Run PhantomJS to create the screen shot.
  $output = array();
  if ($element) {
    exec($binary . ' ' . $script . ' ' . $url . ' ' . $dest . ' ' . escapeshellarg($element), $output);
  } else {
    exec($binary . ' ' . $script . ' ' . $url . ' ' . $dest, $output);
  }

  // Check that PhantomJS was able to load the page.
  if ($output[0] == '500') {
    return FALSE;
  }
  return TRUE;
}

/**
* Implements hook_block_info().
*/
function phantomjs_capture_block_info() {
  $blocks = array();
  $blocks['Scraping Block'] = array(
    'info' => t('scraping block'),
  );
  return $blocks;
}
/**
* Implements hook_block_view().
*/
function phantomjs_capture_block_view($delta = '') {
  $block = array();
  switch ($delta) {
    case 'Scraping Block':
      $block['subject'] = 'Scraper';
      $block['content'] = phantomjs_capture_admin_form();
      break;
  }
  return $block;
}
  • 写回答

1条回答 默认 最新

  • douchi2022 2015-11-28 18:25
    关注

    I got the solution on a different website provided by @zaporylie. The problem wasn my approach to the problem. In short, he suggested to create a new custom module dependent on PhantomJS Capture and then to declare a block.

    Here's working code:

    phantomjs_capture_block.info

    name = PhantomJS Capture Block
    description = Adds block with simple form.
    core = 7.x
    package = Other
    dependencies[] = phantomjs_capture
    

    phantomjs_capture_block.module

    <?php
    
    /**
     * @file
     * Simple form placed in block.
     */
    
    /**
     * Implements hook_block_info().
     */
    function phantomjs_capture_block_block_info() {
      $blocks['screenshot'] = array(
        'info' => t('Screenshot'),
        'cache' => DRUPAL_NO_CACHE,
      );
    
      return $blocks;
    }
    
    /**
     * Implements hook_block_view().
     */
    function phantomjs_capture_block_block_view($delta = '') {
      $block = array();
      if ($delta === 'screenshot') {
        $block['title'] = t('Screenshot');
        $block['content'] = drupal_get_form('phantomjs_capture_block_form');
      }
      return $block;
    }
    
    /**
     * Simple form.
     */
    function phantomjs_capture_block_form($form, &$form_state) {
      $form['url'] = array(
        '#type' => 'textfield',
        '#title' => t('URL'),
        '#ajax' => array(
          'callback' => 'phantomjs_capture_block_form_callback',
          'wrapper' => 'phantomjs-capture-block-form-preview',
          'method' => 'replace',
        ),
      );
    
      $form['preview'] = array(
        '#type' => 'container',
        '#attributes' => array(
          'id' => 'phantomjs-capture-block-form-preview',
        ),
      );
    
      if (!empty($form_state['values']['url'])) {
        $directory = 'public://';
        $filename = REQUEST_TIME . '.png';
        if (phantomjs_capture_screen($form_state['values']['url'], $directory, $filename)) {
          $form['preview']['image'] = array(
            '#theme' => 'image',
            '#path' => $directory . '/' . $filename,
            '#width' => '100%',
          );
        }
        else {
          drupal_set_message(t('Unable to create screenshot'), 'error');
        }
      }
    
      return $form;
    }
    
    function phantomjs_capture_block_form_callback($form, $form_state) {
     return $form['preview'];
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog