0

I am using display suite to customize the look of my node. I created a code field in display suite named Download Code and customize the downloading of file field called field_code_file using the following code:

<?php
global $user;

if (!isset($_SESSION['downinc'])) $_SESSION['downinc'] = 1;

if ($user->uid) $_SESSION['downinc'] = 0;
?>

<form id="form1" name="form1" method="post" action="/download-code">
    <input type="hidden" name="download_code" id="download_code" value="[node:field_code_file]" />  
    <input type="hidden" name="uri" id="uri" value="[node:url:relative]" />
    <input type="submit" class="downloadButton" value="Download Code">
</form>

When my visitors download the code, he/she will be redirected to the download-code page. A normal Page node I created with PHP Code as text format. Since I learned that it is not advisable to use PHP code in node, I have created a module (not for this one) and transfer all the code from it to my simple module. You can find the module that I have created at this link. That works great. But what I want now is also transfer the code I have above and below into a module.

Here's my code in the download-page node:

<script language="javascript">
var time_left = 5;
var cinterval;

function time_dec(){
  time_left--;
  document.getElementById('countdown').innerHTML = time_left;
  if(time_left == 0){
    clearInterval(cinterval);
  }
}

cinterval = setInterval('time_dec()', 1000);
</script>

<?php
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

if (!isset($_SERVER['HTTP_REFERER'])) 
{ 
    echo 'Do not call this file directly'; 
    exit(); 
} 

$tracker = array(
    'database' => 'c1tracker',
    'username' => 'c1tracker',
    'password' => 'mypass',
    'host' => 'localhost',
    'driver' => 'mysql',
);

Database::addConnectionInfo('tracker', 'default', $tracker);
db_set_active('tracker');

$current_ip = $_SERVER['REMOTE_ADDR'];
$referrer = $_SERVER['HTTP_REFERER'];
$user_agent = $_SERVER['HTTP_USER_AGENT'];

global $user;

if (!isset($_SESSION['downinc'])) {
    //set session here since it was not set from the referrer page because of caching.
    $_SESSION['downinc'] = 1;

    $error = "Invalid download. No Session.";

    $sql = "INSERT INTO `download_log` (`id`, `error`, `ip_address`, `referrer`, `user_agent`, `date_time`) VALUES (NULL, '$error', '$current_ip', '$referrer', '$user_agent', now())";

    db_query($sql); 
}

if (!isset($_POST['download_code'])){
    $error = "Invalid download. File not set.";

    echo "<p>$error</p>";
    echo "<p>Please clear your browser's cache.</p>";
    echo "<h4><a href=\"http://www.mysite.com/user/register\">Sign up</a> now or <a href=\"http://www.mysite.com/user/login\">login</a> if you are an existing member.</h4>";

    $sql = "INSERT INTO `download_log` (`id`, `error`, `ip_address`, `referrer`, `user_agent`, `date_time`) VALUES (NULL, '$error', '$current_ip', '$referrer', '$user_agent', now())";

    db_query($sql);     
}else{
    $file = $_POST['download_code'];

    if ( $_SESSION['downinc'] < 4 || $user->uid ) {
        header("Refresh: 5; URL=$file");

        $_SESSION['downinc'] = $_SESSION['downinc'] + 1;

        echo "<p>Your download will start in <span id=\"countdown\">5</span> seconds...</p>";
    }else{
        $uri = substr($_POST['uri'],1);

        echo "<p>You have downloaded code 3 times.</p>";
        echo "<p>To continue downloading, please login or register.</p>";
        echo "<h3><a href=\"http://www.mysite.com/user/register?destination=$uri\">Sign up</a> now or <a href=\"http://www.mysite.com/user/login?destination=$uri\">login</a> if you are an existing member.</h3>";
    }
}

db_set_active();
?> 
<p>Problems with the download? Please go back to previous <a href="<?php echo $referrer ?>">page.</a></p>
<p>If you have problem downloading this file, kindly <a href="http://www.mysite.com/contact">contact us</a>.</p>

So anyone can guide me on where to start? What hook do I need in order to catch the link from Download Code created using display suite?

BTW, I'm using drupal 7.

1 Answer 1

0

I'm not sure how to integrate with Display Suite, I have some idea for putting a form in an individual page and then make your logic work.

In your module you should implement hook_menu() to tell Drupal that there's an URL to handle. For that URL you could specify a callback that will show your form.

Using Drupal's From API, you can build a nice form (with CSRF protection) with all the logic you need.

Here's some code example. Please keep in mind that this is untested code and it should only give you some ideas to write yours.

function site_visitors_menu() {
  $items['download-code'] = array(
    'title' => 'Download my stuff',
    'page callback' => 'drupal_get_form('site_visitors_download_form')',
    'access arguments' => array('access content'),
  );
  return $items;
}

function site_visitors_download_form($form, &$form_state) {
  $form['download_code'] = array(
    '#type' => 'hidden',
    '#value' => token_replace('[node:field_code_file]', array('node' => $node)), //not sure how to deal with this, you should load the node first with a node_load()
  );
  $form['uri'] = array(
    '#type' => 'hidden',
    '#value' => token_replace('[node:url:relative]', array('node' => $node)), //same as above
  );
  $form['submit'] = array(
    '#type' => 'button',
    '#value' => t('Download Code'),
    '#weight' => 10,
  );
  return $form;
}

function site_visitors_download_form_validate($form, &$form_state) {
  if (!empty($form_state['values']['download_code'])){

      $sql = "INSERT INTO `download_log` (`id`, `error`, `ip_address`, `referrer`, `user_agent`, `date_time`) VALUES (NULL, '$error', '$current_ip', '$referrer', '$user_agent', now())";

      Database::addConnectionInfo('tracker', 'default', $tracker);
      db_set_active('tracker');
      db_query($sql);
      db_set_active();
      form_set_error('download_code', "<p>Invalid download. File not set.</p><p>Please clear your browser's cache.</p><h4><a href=\"http://www.mysite.com/user/register\">Sign up</a> now or <a href=\"http://www.mysite.com/user/login\">login</a> if you are an existing member.</h4>"); //not sure about this, because the field is hidden
  }
}

function site_visitors_download_form_submit($form, &$form_state) {
  $js = "var time_left = 5;
  var cinterval;

  function time_dec(){
    time_left--;
    document.getElementById('countdown').innerHTML = time_left;
    if(time_left == 0){
      clearInterval(cinterval);
    }
  }

  cinterval = setInterval('time_dec()', 1000);"
  drupal_add_js($js, 'inline');

  drupal_add_http_header("Last-Modified", gmdate("D, d M Y H:i:s") . " GMT");
  drupal_add_http_header("Cache-Control", "no-store, no-cache, must-revalidate"); // HTTP/1.1
  drupal_add_http_header("Cache-Control", "post-check=0, pre-check=0", false);
  drupal_add_http_header("Pragma", "no-cache"); // HTTP/1.0
  drupal_add_http_header("Expires", "Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

  /* this should not be necessary any more
  if (!isset($_SERVER['HTTP_REFERER'])) 
  { 
      echo 'Do not call this file directly'; 
      exit(); 
  } 
  */
  $tracker = array(
      'database' => 'c1tracker',
      'username' => 'c1tracker',
      'password' => 'mypass',
      'host' => 'localhost',
      'driver' => 'mysql',
  );

  $current_ip = $_SERVER['REMOTE_ADDR'];
  $referrer = $_SERVER['HTTP_REFERER'];
  $user_agent = $_SERVER['HTTP_USER_AGENT'];

  global $user;

  if (!isset($_SESSION['downinc'])) {
      //set session here since it was not set from the referrer page because of caching.
      $_SESSION['downinc'] = 1;

      $error = "Invalid download. No Session.";

      Database::addConnectionInfo('tracker', 'default', $tracker);
      db_set_active('tracker');

      $sql = "INSERT INTO `download_log` (`id`, `error`, `ip_address`, `referrer`, `user_agent`, `date_time`) VALUES (NULL, '$error', '$current_ip', '$referrer', '$user_agent', now())";

      db_query($sql); 
      db_set_active();
  }

  /* moved into _validate()
  if (!isset($form_state['values']['download_code'])){
      $error = "Invalid download. File not set.";

      echo "<p>$error</p>";
      echo "<p>Please clear your browser's cache.</p>";
      echo "<h4><a href=\"http://www.mysite.com/user/register\">Sign up</a> now or <a href=\"http://www.mysite.com/user/login\">login</a> if you are an existing member.</h4>";

      $sql = "INSERT INTO `download_log` (`id`, `error`, `ip_address`, `referrer`, `user_agent`, `date_time`) VALUES (NULL, '$error', '$current_ip', '$referrer', '$user_agent', now())";

      db_query($sql);     

  }else{*/
      $file = $form_state['values']['download_code'];

      if ( $_SESSION['downinc'] < 4 || $user->uid ) {
          drupal_add_http_header("Refresh", "5; URL=$file");

          $_SESSION['downinc'] = $_SESSION['downinc'] + 1;

          return "<p>Your download will start in <span id=\"countdown\">5</span> seconds...</p>";
      }else{
          $uri = substr($form_state['values']['uri'],1);

          return "<p>You have downloaded code 3 times.</p><p>To continue downloading, please login or register.</p><h3><a href=\"http://www.mysite.com/user/register?destination=$uri      \">Sign up</a> now or <a href=\"http://www.mysite.com/user/login?destination=$uri\">login</a> if you are an existing member.</h3>";
      }
  //}
}
10
  • Thanks for the reply. However I received an error Parse error: syntax error, unexpected $end in /var/www/clients/client1/web2/web/sites/all/modules/custom_download/custom_download.module on line 141 when I enabled the module. BTW, I created another module and you can find it here. In your code, the last line is being commented as //}. I tried to uncomment that, but still the same error.
    – jaypabs
    Commented Aug 6, 2013 at 9:54
  • Yep, function custom_download_menu() is not closed. There's a missing } in the end. Please use a text editor like Notepad++ or Sublime Text to highlight syntax and easily spot syntax errors.
    – ermannob
    Commented Aug 6, 2013 at 9:58
  • sorry, there were also some errors in function names. Please check my edited code.
    – ermannob
    Commented Aug 6, 2013 at 10:00
  • I changed this line $items['download-code'] = array( to $items['downloadcode'] = array( (noticed I removed the dash (-) sign)so it will not conflict with the existing menu. But when I try to download the file it says: Page not found The requested page could not be found. It seems it does not create that menu. If I am right, it shoult create this menau www.mysite.com/downloadcode, right? How to fix this?
    – jaypabs
    Commented Aug 6, 2013 at 13:10
  • You are right, that url should work. Most of the times it's a problem of cache. Did you flush the cache?
    – ermannob
    Commented Aug 6, 2013 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.