Hi, I need help porting some custom code to Drupal 6. The goal of this code is to move the "User picture upload interface" to its own tab on the Account edit page. It currently fails at validation and removing the original Upload Picture interface. I've tried my hardest and could get it to work, but I have limited understanding of the internals. Code provided by Josh Koenig from chapterthree.com

<?php
function avatar_user($op, &$edit, &$account, $category = NULL) {
  if ($op == 'categories') {
    $categories = array(array(
      'name' => 'avatar', 
      'title' => t('User picture'), 
      'weight' => 1)
    );
    return $categories;
  }
  if ($op == 'form' && $category == 'avatar') {
    $form = array();
    $form['avatar'] = array(
      '#type' => 'fieldset',
    );
    $form['avatar']['preview'] = array(
      '#type' => 'markup',
      '#value' => theme('user_picture', $account),
      '#prefix' => '<h2>'. t('Your current picture'). '</h2>',
    );
    $form['avatar']['picture_upload'] = array(
      '#type' => 'file',
      '#title' => t('Upload a new picture'),
      '#size' => 20,
    );
    return $form;
  }
  if ($op == 'validate' && $category == 'avatar') {
    if ($file = file_check_upload('picture_upload')) {
      // user.module's function for validating pictures is plenty good
      user_validate_picture($file, $edit, $account);
    }
  }
}

function avatar_form_alter($form_id, &$form) {
  if($form_id == 'user_edit' && arg(3) == NULL) {
    // only fire this if it's user/<uid>/edit, not any other category
    unset($form['picture']);
  }
}
?>

Comments

mariusooms’s picture

I meant to say, "I've tried my hardest and could NOT get it to work", sorry for the typo.

Kind regards,

Marius

liliplanet’s picture

Marius Hi,

Did you find a solution to move the user picture to it's own tab? That would be wonderful, thanx!

mariusooms’s picture

nope....sorry...I just change the weight in core (shhh, don't tell anyone) so that it is the first item in settings and live with it.

Regards,

Marius

sangamreddi’s picture

The form id = user_profile_form

freestylegary@yahoo.com’s picture

I managed to get it on another page. You could change the menu callbacks to make it a tab. Did it this way:

1. create your module file and its .info file
2. in your module, first write a hook_menu to point to you page like so:

fuction mymodule_menu(){

  $items[] = array();
  
  $items['upload-picture'] = array(
    'title' => 'Upload Profile Picture',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('mymodule_picture_form'),
    'access arguments' => array('create content'),
    'type' => MENU_CALLBACK,
  );

}

3. write your function to grab the form from the user module:

function mymodule_picture_form(){
	global $user;
	$uid = $user->uid;
	//if we have a user id get the form
	if ($uid > 0) {
  		include_once drupal_get_path('module', 'user') . '/user.pages.inc';
		// get the user edit form
		$form =  user_profile_form($form_state, $user);
	}
	//we hide the account information since it is require during validation
	$form['account']['#type'] = 'hidden';
	//unset any other fields you do not want
	unset($form['contact']);

	return $form;
}
freestylegary@yahoo.com’s picture

Ran into a few issues with this implementation. Though it work well initially, but had problems with imagecache etc. A deeper look into the user module and I came up with a few changes:

Change Step 2:
This create an url that calls the original user edit page with an additional argument

    $items['user/%user/edit/account/upload-picture'] = array(
    'title' => 'Upload Profile Picture',
    'page callback' => 'user_edit',
    'page arguments' => array(1),
    'access callback' => 'user_edit_access',
    'access arguments' => array(1),
    'type' => MENU_CALLBACK,
    'load arguments' => array('%map', '%index'),
    'file' => 'user.pages.inc',
    'file path' => drupal_get_path('module', 'user'),
  );

Change Step 3:
Call a form alter for the particular url

function mymodule_form_alter(&$form, $form_state, $form_id){
  if($form_id == 'user_profile_form' && arg(4) == 'upload-picture'){
  //if changing username is disallowed, it will be hidden by default
  $form['account']['pass']['#type'] = 'hidden';
  $form['account']['#title'] = t('');
  $form['account']['mail']['#type'] = 'hidden';
			
  unset($form['contact']);
  }
}
manoz_79’s picture

Can you share your .module file, am trying to create a page which has only upload picture feature using your above said code, but when I go to page user/uid/edit/account/upload-picture i get a 'page not found' error.

freestylegary@yahoo.com’s picture

Did you flush the cache?

manoz_79’s picture

yes I did flush the cache, i am putting my .module code below for your review, please correct if I am doing anything wrong.

<?php

function userpictureupload_menu(){
$items['user/%user/edit/account/upload-picture'] = array(
'title' => 'Upload Profile Picture',
'page callback' => 'user_edit',
'page arguments' => array(1),
'access callback' => 'user_edit_access',
'access arguments' => array(1),
'type' => MENU_CALLBACK,
'load arguments' => array('%map', '%index'),
'file' => 'user.pages.inc',
'file path' => drupal_get_path('module', 'user'),
);
}

function userpictureupload_form_alter(&$form, $form_state, $form_id){
if($form_id == 'user_profile_form' && arg(4) == 'upload-picture'){
//if changing username is disallowed, it will be hidden by default
$form['account']['pass']['#type'] = 'hidden';
$form['account']['#title'] = t('');
$form['account']['mail']['#type'] = 'hidden';
unset($form['contact']);
}
}

Thanks for your help, also to let you know I am using 'me' module

Thanks and regards

AgaPe’s picture

Hi,

i am trying to put an upload picture form in a block, but it behaves strangely...
I print it
print drupal_get_form("user_profile_form");
clear the cache and it shows there but only once, if i reload the page it disappears when i print out the form variables there is something but not the fields.. any idea?

I would apreciate any help!

drupalina’s picture

I tried creating a module as per above, but nothing happens. (yes, I cleared the caches - still nothing)

From reading the code, it seems like you're unsetting all other elements on the Account Settings page. But what is needed is only moving the Picture Upload form to a separate tab.

Can someone PLEASE post the code for a module that works?

drupalina’s picture

Here is my own module code for 6.x (create a module called "Avatar" with its .info file and in avatar.module file paste this code)

Note: I use Avatar Crop module, so I deliberately commented out the default picture upload form/buttons. I also tried to get rid of the "Save" and "Delete" buttons because those come from 'user_profile_form' (the account settings form) and therefore are confusing and dangerous, but I couldn't do remove them. If you know how to remove the "Save" and "Delete" button from this tab, I would greately appreciate it.

<?php
function avatar_user($op, &$edit, &$account, $category = NULL) {
  if ($op == 'categories') {
    $categories = array(array(
      'name' => 'avatar', 
      'title' => t('Picture'), 
      'weight' => 1)
    );
    return $categories;
  }
  if ($op == 'form' && $category == 'avatar') {
    $form = array();
    $form['avatar'] = array(
      '#type' => 'fieldset',
    );
    $form['avatar']['preview'] = array(
      '#type' => 'markup',
      '#value' => theme('user_picture', $account),
      '#prefix' => '<h2>'. t('Your current picture'). '</h2>',
    );
//  Removing the default Drupal picture upload form, because I'm using Avatar Crop module
//    $form['avatar']['picture_upload'] = array(
//      '#type' => 'file',
//      '#title' => t('Upload a new picture'),
//      '#size' => 20,
//    );
    return $form;
  }
  if ($op == 'validate' && $category == 'avatar') {
    if ($file = file_save_upload('picture_upload')) {
      // user.module's function for validating pictures is plenty good
      user_validate_picture($file, $edit, $account);
    }
  }
}

function avatar_form_alter($form_id, &$form_state, &$form) {
  if($form_id == 'user_profile_form' && arg(3) == NULL) {
    // only fire this if it's user/<uid>/edit, not any other category
    unset($form['picture']);
//	unset($form['save']);
  }
//  I tried to get rid of the Save and Delete buttons on this form, but I couldn't.  If you know how to do it, please help 
//  if($form_id == 'user_profile_form' && arg(3) != NULL) {
    // getting rid of the Save button
//	unset($form['save']);
//	unset($form['buttons']['submit']);
//  }

}

If you know how to remove the "Save" and "Delete" buttons on this form, without removing them on the Account Settings page, please help and write your solution.

andrii_svirin’s picture

<?php

function userpictureupload_user($op, &$edit, &$account, $category = NULL) {
	//drupal_set_message($op);
  if ($op == 'categories') {
    $categories = array(array(
      'name' => 'avatar',
      'title' => t('Picture'),
      'weight' => 1)
    );
    return $categories;
  }
  if ($op == 'form' && $category == 'avatar') {
    $form = array();
    $form['avatar'] = array(
      '#type' => 'fieldset',
    );
    $form['avatar']['preview'] = array(
      '#type' => 'markup',
      '#value' => theme('user_picture', $account),
      '#prefix' => '<h2>'. t('Your current picture'). '</h2>',
    );
//  Removing the default Drupal picture upload form, because I'm using Avatar Crop module
    $form['avatar']['picture_upload'] = array(
      '#type' => 'file',
      '#title' => t('Upload a new picture'),
      '#size' => 20,
    );
    $form['#validate'][] = 'user_profile_form_validate';
    $form['#validate'][] = 'user_validate_picture';
    $form['#uid'] = $account->uid;
    return $form;
  }
  //if ($op == 'validate' && $category == 'avatar') {
  	//drupal_set_message("Validate 1");
    //if ($file = file_save_upload('picture_upload', $validators)) {
    	//print_r($file);
    	//drupal_set_message("Validate 2");
      // user.module's function for validating pictures is plenty good
      //user_profile_form_validate($form, &$form_state);
     // user_validate_picture(&$form, &$form_state);
   // }
  //}
}

function userpictureupload_form_alter(&$form, &$form_state, $form_id) {
  if($form_id == 'user_profile_form' && arg(3) == NULL) {
    // only fire this if it's user/<uid>/edit, not any other category
    unset($form['picture']);
	//unset($form['save']);
  }
//  I tried to get rid of the Save and Delete buttons on this form, but I couldn't.  If you know how to do it, please help
 //if($form_id == 'user_profile_form' && arg(3) != NULL) {
    // getting rid of the Save button
 //unset($form['save']);
 //unset($form['buttons']['submit']);
  //}

}

Buttons *Save|Delete* only for root account. Other user see only *Save*

drupalina’s picture

With your module the "Picture" tab didn't appear at all. In functions I changed "userpictureupload" to "avatar" and it worked. But the Save|Delete buttons still appear. This is dangerous if you allow users to delete their own accounts. (they'll be thinking that they are deleting only the picture, but in fact would be deleting their own accounts)

sol roth’s picture

I'm looking for a start on a d7 solution.

rickyoh’s picture

For any user profile field in D7 I use this:

function my_module_page_callback($user){
	module_load_include('inc', 'user', 'user.pages');
	$form = drupal_get_form('user_profile_form', $user);
        //If you wanna move signature settings to another form, simply replace 'picture' with the index for the signature settings
	$onlyAllowedNonHashStartingIndexes = array('form_build_id', 'form_token', 'form_id', 'actions', 'picture');
	foreach($form as $k => $v){
		if(($k[0] !=  '#') && (!in_array($k, $onlyAllowedNonHashStartingIndexes))){
			unset($form[$k]);
		}
	}
	return drupal_render($form);
}