2

This is my first newbie module (drupal 7). It's 'simple' but needs help x2.

Intention: To create an online image-name generator i.e, user types their name into a formfield and the browser outputs the text as a jpg image so they can right-click and save.

What I've done: 1. created one hook menu with two callback functions, one for the form and one for the image output. 2. A working form where user types in their name. 3. Able to output Image by setting name input manually through code, not by submitting the form!

What doesn't work: I created a $name variable within the form function, but using that same $name variable within the image-output function won't work. So I can't output a text-image when users submit the form. Also I don't know how to render both form and image output onto the same page.

I need help with: 1. How to render both form and image onto the same page?. 2: How to associate $name variable so inputted text will render upon submit button.

Frameyourname.module:

<?php

//Create simple image-generator.

//Implements hook_menu(). 

function frameyourname_menu() { 
$items['frameyourname'] = array( 
'title' => 'Frame Your Name form', 
'page callback' => 'drupal_get_form', 
'page arguments' => array('frameyourname_nameform'), 
'access callback' => TRUE, 
'type' => MENU_NORMAL_ITEM ,
); 

//not entirely sure what to put here.

$items['image'] = array(
'title' => 'image',
'page callback' => 'drupal_get_form',
'page arguments' => array('create_textimage'), 
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM ,
  );

return $items; 

} 

// Define a form. 

function frameyourname_nameform() { 
$form['user_name'] = array( 
'#title' => t('Your Name'), 
'#type' => 'textfield', 
'#description' => t('Please enter your name.'), 
); 
$form['submit'] = array( 
'#type' => 'submit', 
'#value' => t('Submit') 
); 
return $form; 
} 


// Validate the form. 
function frameyourname_nameform_validate($form, &$form_state) { 
}

// Handle post-validation form submission. 
function frameyourname_nameform_submit($form, &$form_state) { 

//set name variable associated with user input and test if works.
$name = $form_state['values']['user_name']; 
drupal_set_message(t('Thanks for adding your name,'.  $name)); 
}

// create image
function create_textimage() {

// Create a blank image and add text as per form input
$im = imagecreatetruecolor(400, 400);
$text_color = imagecolorallocate($im, 233, 14, 91);

//trying to reference $name variable not sure how.
imagestring($im, 1, 5, 5,  $name, $text_color);

// Set the content type header
drupal_add_http_header('Content-Type', 'image;jpeg');

// Output the image
imagejpeg($im);

// free from memory
imagejpeg($im);


} 
1
  • Brilliant format, Question is well focused on the problem. You need to submit the form through the ajax then update image using same callback. For reference check on Drupal AJAX form submit examples. Commented Jul 24, 2014 at 12:33

1 Answer 1

1

If you put $form_state['rebuild'] = TRUE in your submit handler then the form's redisplayed and you have access to $form_state['values'] in the form constructor. This is typically how multi-step forms are done. So in this case something like:

if (empty($form_state['values']['user_name'])) {
  $form['user_name'] = array(
    '#title' => t('Your Name'),
    '#type' => 'textfield',
    '#description' => t('Please enter your name.'),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit')
  );
}
else {
  $form['image'] = array(
    '#theme' => 'image__nameform',
    '#path' => $path,
    '#width' => $width,
    '#height' => $height,
    '#alt' => $form_state['values']['user_name'],
  );
}

To pass the name to your image generation function you want to change its entry in hook_menu(): the path should be image/% (which says there's an argument), page callback create_textimage (because that's what generates the content) and page arguments array(1) (because the text is the second argument, and you start numbering at 0). There are more details in the documentation for hook_menu().

A few other points not directly related to the Q:

  1. Currently the image generation function is a bit of a DOS vector (because it's a bit CPU intensive, isn't cached, doesn't require auth, and doesn't require a form submission).
  2. You should use drupal_set_message(t('Thanks for adding your name, %name.', array('%name' => $name));. This is secure and translatable - see t() and format_string().
  3. The function names are a bit all over the place. If your module's called frameyourname then all your functions should start with that (with a few exceptions). Also I'd suggest avoiding a path like image/% in favour of something more specific like frameyourname/%.
3
  • RE: Dos vector comment, if I apply Honeypot or Captcha module to the form, will that improve my module? (thanks, great help)
    – user20154
    Commented Jul 25, 2014 at 2:23
  • 1
    If you want the form open to anonymous users then a captcha makes sense to me - but adding it to the form alone won't make any difference because you can just use the image creation URL directly. The two methods I see are a) generate the image in the submit handler itself, or b) use a token to verify the link came from the site. For an example of the latter approach see image_style_path_token() and image_style_deliver(). Btw is the focus on learning how to do this yourself, or on creating a working product?
    – Andy
    Commented Jul 25, 2014 at 8:43
  • Good question--the focus for a working product (for my own personal blog though) where I just wanted to have some quirky interactivity for users, I thought something simple, yet fun would be the best approach to learning how to make a module too. great input thanks.
    – user20154
    Commented Jul 25, 2014 at 14:16

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.