From 4222117ea27253a462fcaf0a5146f0ad8f725a69 Mon Sep 17 00:00:00 2001
From: Zack <zack@uberbur.(none)>
Date: Sat, 18 Jun 2011 05:29:41 -0400
Subject: [PATCH] user_edit_Form

---
 page_manager/plugins/tasks/user_edit.inc |  153 ++++++++++++++++++++++++
 plugins/arguments/user_edit.inc          |   48 ++++++++
 plugins/contexts/user_edit_form.inc      |  188 ++++++++++++++++++++++++++++++
 3 files changed, 389 insertions(+), 0 deletions(-)
 create mode 100644 page_manager/plugins/tasks/user_edit.inc
 create mode 100644 plugins/arguments/user_edit.inc
 create mode 100644 plugins/contexts/user_edit_form.inc

diff --git a/page_manager/plugins/tasks/user_edit.inc b/page_manager/plugins/tasks/user_edit.inc
new file mode 100644
index 0000000..6b16ebb
--- /dev/null
+++ b/page_manager/plugins/tasks/user_edit.inc
@@ -0,0 +1,153 @@
+<?php
+
+/**
+ * @file
+ * Overrides the user profile display at user/%user.
+ *
+ * Specialized implementation of hook_page_manager_task_tasks(). See api-task.html for
+ * more information.
+ */
+function page_manager_user_edit_page_manager_tasks() {
+  return array(
+    // This is a 'page' task and will fall under the page admin UI
+    'task type' => 'page',
+    'title' => t('User Edit Template'),
+    'admin title' => t('User edit template'),
+    'admin description' => t('When enabled, this overrides the default Drupal behavior for displaying user edit form at <em>user/%user/edit</em>.'),
+    'admin path' => 'user/%user/edit',
+
+    // Callback to add items to the page managertask administration form:
+    'task admin' => 'page_manager_user_edit_task_admin',
+
+    'hook menu' => 'page_manager_user_edit_menu',
+    'hook menu alter' => 'page_manager_user_edit_menu_alter',
+
+    // This is task uses 'context' handlers and must implement these to give the
+    // handler data it needs.
+    'handler type' => 'context', // handler type -- misnamed
+    'get arguments' => 'page_manager_user_edit_get_arguments',
+    'get context placeholders' => 'page_manager_user_edit_get_contexts',
+
+    // Allow this to be enabled or disabled:
+    'disabled' => variable_get('page_manager_user_edit_disabled', TRUE),
+    'enable callback' => 'page_manager_user_edit_enable',
+  );
+}
+
+/**
+ * Callback defined by page_manager_user_view_page_manager_tasks().
+ *
+ * Alter the user view input so that user view comes to us rather than the
+ * normal user view process.
+ */
+function page_manager_user_edit_menu_alter(&$items, $task) {
+  if (variable_get('page_manager_user_edit_disabled', TRUE)) {
+    return;
+  }
+ 
+  // Override the user view handler for our purpose.
+  if ($items['user/%user/edit']['page callback'] == 'drupal_get_form' || variable_get('page_manager_override_anyway', FALSE)) {
+    $items['user/%user/edit']['page callback'] = 'page_manager_user_edit_page';
+    $items['user/%user/edit']['page arguments'] = array(1);
+    $items['user/%user/edit']['file path'] = $task['path'];
+    $items['user/%user/edit']['file'] = $task['file'];
+  }
+  else {
+    // automatically disable this task if it cannot be enabled.
+    variable_set('page_manager_user_edit_disabled', TRUE);
+    if (!empty($GLOBALS['page_manager_enabling_user_edit'])) {
+      drupal_set_message(t('Page manager module is unable to enable user/%user/edit because some other module already has overridden with %callback.', array('%callback' => $items['user/%user']['page callback'])), 'error');
+    }
+  }
+}
+
+/**
+ * Entry point for our overridden user view.
+ *
+ * This function asks its assigned handlers who, if anyone, would like
+ * to run with it. If no one does, it passes through to Drupal core's
+ * user edit, which is drupal_get_form('user_profile_form',$account).
+ */
+function page_manager_user_edit_page($account) {
+  
+  // Load my task plugin:
+  $task = page_manager_get_task('user_edit');
+
+  // Load the account into a context.
+  ctools_include('context');
+  ctools_include('context-task-handler');
+  $contexts = ctools_context_handler_get_task_contexts($task, '', array($account));
+  // Build content. @todo -- this may not be right.
+  user_build_content($account);
+
+  $output = ctools_context_handler_render($task, '', $contexts, array($account->uid));
+  if ($output != FALSE) {
+    return $output;
+  }
+
+  $function = 'drupal_get_form';
+  foreach (module_implements('page_manager_override') as $module) {
+    $call = $module . '_page_manager_override';
+    if (($rc = $call('user_edit')) && function_exists($rc)) {
+      $function = $rc;
+      break;
+    }
+  }
+
+  // Otherwise, fall back.
+  if ($function == 'drupal_get_form') {
+    
+    //In order to ajax fields to work we need to run form_load_include.  
+    //Hence we eschew drupal_get_form and manually build the info and
+    //call drupal_build_form.
+    $form_state = array();
+    $form_id = 'user_profile_form';
+    $args = array($account);
+    $form_state['build_info']['args'] = $args;
+    form_load_include($form_state, 'inc', 'user', 'user.pages');
+    $output = drupal_build_form($form_id, $form_state);
+    return $output;
+  }
+  //fire off "view" op so that triggers still work
+  // @todo -- this doesn't work anymore, and the alternatives seem bad.
+  // will have to figure out how to fix this.
+  // user_module_invoke('view', $array = array(), $account);
+  return $function($account);
+}
+
+/**
+ * Callback to get arguments provided by this task handler.
+ *
+ * Since this is the node view and there is no UI on the arguments, we
+ * create dummy arguments that contain the needed data.
+ */
+function page_manager_user_edit_get_arguments($task, $subtask_id) {
+  return array(
+    array(
+      'keyword' => 'user',
+      'identifier' => t('User being edited'),
+      'id' => 1,
+      'name' => 'user_edit',
+      'settings' => array(),
+    ),
+  );
+}
+
+/**
+ * Callback to get context placeholders provided by this handler.
+ */
+function page_manager_user_edit_get_contexts($task, $subtask_id) {
+  return ctools_context_get_placeholders_from_argument(page_manager_user_edit_get_arguments($task, $subtask_id));
+}
+
+/**
+ * Callback to enable/disable the page from the UI.
+ */
+function page_manager_user_edit_enable($cache, $status) {
+  variable_set('page_manager_user_edit_disabled', $status);
+  // Set a global flag so that the menu routine knows it needs
+  // to set a message if enabling cannot be done.
+  if (!$status) {
+    $GLOBALS['page_manager_enabling_user_edit'] = TRUE;
+  }
+}
diff --git a/plugins/arguments/user_edit.inc b/plugins/arguments/user_edit.inc
new file mode 100644
index 0000000..fc77f80
--- /dev/null
+++ b/plugins/arguments/user_edit.inc
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ *
+ * Plugin to provide an argument handler for a Taxonomy term
+ */
+
+/**
+ * Plugins are described by creating a $plugin array which will be used
+ * by the system that includes this file.
+ */
+$plugin = array(
+  'title' => t("User edit form: User ID"),
+  // keyword to use for %substitution
+  'keyword' => 'user',
+  'description' => t('Creates a user edit form context from a user ID argument.'),
+  'context' => 'ctools_user_edit_context',
+  'placeholder form' => array(
+    '#type' => 'textfield',
+    '#description' => t('Enter the user ID for this argument.'),
+  ),
+);
+
+/**
+ * Discover if this argument gives us the term we crave.
+ */
+function ctools_user_edit_context($arg = NULL, $conf = NULL, $empty = FALSE) {
+  // If unset it wants a generic, unfilled context.
+  if ($empty) {
+    return ctools_context_create_empty('user_edit_form');
+  }
+  if(is_object($arg)){
+    return ctools_context_create('user_edit_form', $arg);
+  }
+  if (!is_numeric($arg)) {
+    return FALSE;
+  }
+
+  $account= user_load($arg);
+  if (!$account) {
+    return NULL;
+  }
+
+  // This will perform a node_access check, so we don't have to.
+  return ctools_context_create('user_edit_form', $account);
+  return NULL;
+}
\ No newline at end of file
diff --git a/plugins/contexts/user_edit_form.inc b/plugins/contexts/user_edit_form.inc
new file mode 100644
index 0000000..55f3723
--- /dev/null
+++ b/plugins/contexts/user_edit_form.inc
@@ -0,0 +1,188 @@
+<?php
+
+/**
+ * @file
+ *
+ * Plugin to provide a node_edit_form context
+ */
+
+/**
+ * Plugins are described by creating a $plugin array which will be used
+ * by the system that includes this file.
+ */
+$plugin = array(
+  'title' => t("User edit form"),
+  'description' => t('A user edit form.'),
+  'context' => 'ctools_context_create_user_edit_form',
+  'edit form' => 'ctools_context_user_edit_form_settings_form',
+  'defaults' => array('uid' => ''),
+  'keyword' => 'user_edit',
+  'context name' => 'user_edit_form',
+  'convert list' => 'ctools_context_user_edit_convert_list',
+  'convert' => 'ctools_context_user_edit_convert',
+  'placeholder form' => array(
+    '#type' => 'textfield',
+    '#description' => t('Enter the user ID of a user for this argument:'),
+  ),
+);
+
+/**
+ * It's important to remember that $conf is optional here, because contexts
+ * are not always created from the UI.
+ */
+function ctools_context_create_user_edit_form($empty, $user = NULL, $conf = FALSE) {
+  static $created;
+  $context = new ctools_context(array('form', 'user_edit', 'user_form', 'user_edit_form'));
+  $context->plugin = 'user_edit_form';
+
+  if ($empty || (isset($created) && $created)) {
+    return $context;
+  }
+  $created = TRUE;
+
+  if ($conf) {
+    // In this case, $node is actually our $conf array.
+    $uid = is_array($user) && isset($user['uid']) ? $node['uid'] : (is_object($user) ? $user->uid : 0);
+
+    if (module_exists('translation')) {
+      if ($translation = module_invoke('translation', 'user_uid', $uid, $GLOBALS['language']->language)) {
+        $uid = $translation;
+        $reload = TRUE;
+      }
+    }
+
+    if (is_array($user) || !empty($reload)) {
+      $user = user_load($uid);
+    }
+  }
+
+  if (!empty($user)) {
+    $form_id = 'user_profile_form';
+
+    $form_state = array('want form' => TRUE, 'build_info' => array('args' => array($user)));
+
+    $file = drupal_get_path('module', 'user') . '/user.pages.inc';
+    require_once DRUPAL_ROOT . '/' . $file;
+    // This piece of information can let other modules know that more files
+    // need to be included if this form is loaded from cache:
+    $form_state['build_info']['files'] = array($file);
+
+    $form = drupal_build_form($form_id, $form_state);
+
+    // Fill in the 'node' portion of the context
+    $context->data     = $user;
+    $context->title    = isset($user->name) ? $user->name : '';
+    $context->argument = $user->uid;
+
+    $context->form       = $form;
+    $context->form_state = &$form_state;
+    $context->form_id    = $form_id;
+    $context->form_title = isset($user->name) ? $user->name : '';
+    //$context->node_type  = $node->type;
+    //$context->restrictions['type'] = array($node->type);
+    $context->restrictions['form'] = array('form');
+    return $context;
+  }
+}
+
+function ctools_context_user_edit_form_settings_form($form, &$form_state) {
+  $conf = &$form_state['conf'];
+
+  $form['user'] = array(
+    '#title' => t('Enter the name or UID of a node'),
+    '#type' => 'textfield',
+    '#maxlength' => 512,
+    '#autocomplete_path' => 'ctools/autocomplete/user',
+    '#weight' => -10,
+  );
+
+  if (!empty($conf['uid'])) {
+    $info = db_query('SELECT * FROM {user} WHERE uid = :uid', array(':uid' => $conf['uid']))->fetchObject();
+    if ($info) {
+      $link = l(t("'%name' [user id %uid]", array('%name' => $info->name, '%uid' => $info->uid)), "user/$info->uid", array('attributes' => array('target' => '_blank', 'title' => t('Open in new window')), 'html' => TRUE));
+      $form['user']['#description'] = t('Currently set to !link', array('!link' => $link));
+    }
+  }
+
+  $form['uid'] = array(
+    '#type' => 'value',
+    '#value' => $conf['uid'],
+  );
+
+  $form['set_identifier'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => FALSE,
+    '#title' => t('Reset identifier to user name'),
+    '#description' => t('If checked, the identifier will be reset to the user name of the selected user.'),
+  );
+
+  return $form;
+}
+
+/**
+ * Validate a node.
+ */
+function ctools_context_user_edit_form_settings_form_validate($form, &$form_state) {
+  // Validate the autocomplete
+  if (empty($form_state['values']['uid']) && empty($form_state['values']['user'])) {
+    form_error($form['user'], t('You must select a user.'));
+    return;
+  }
+
+  if (empty($form_state['values']['user'])) {
+    return;
+  }
+
+  $uid          = $form_state['values']['user'];
+  $preg_matches = array();
+  $match        = preg_match('/\[id: (\d+)\]/', $uid, $preg_matches);
+  if (!$match) {
+    $match = preg_match('/^id: (\d+)/', $uid, $preg_matches);
+  }
+
+  if ($match) {
+    $uid = $preg_matches[1];
+  }
+  if (is_numeric($uid)) {
+    $user = db_query('SELECT uid FROM {user} WHEREuid = :uid', array(':uid' => $uid))->fetchObject();
+  }
+  else {
+    $node = db_query('SELECT uid FROM {user} WHERE LOWER(name) = LOWER(:name)', array(':name' => $uid))->fetchObject();
+  }
+
+  // Do not allow unpublished nodes to be selected by unprivileged users
+  /*if (!$node || (empty($node->status) && !(user_access('administer nodes')))) {
+    form_error($form['node'], t('Invalid node selected.'));
+  }
+   * */
+  
+  form_set_value($form['uid'], $user->uid, $form_state);
+}
+function ctools_context_user_edit_form_settings_form_submit($form, &$form_state) {
+  if ($form_state['values']['set_identifier']) {
+    $node = user_load($form_state['values']['uid']);
+    $form_state['values']['identifier'] = $user->name;
+  }
+
+  // This will either be the value set previously or a value set by the
+  // validator.
+  $form_state['conf']['uid'] = $form_state['values']['uid'];
+}
+
+/**
+ * Provide a list of ways that this context can be converted to a string.
+ */
+function ctools_context_user_edit_convert_list() {
+  // Pass through to the "node" context convert list.
+  $plugin = ctools_get_context('user');
+  return ctools_context_user_convert_list();
+}
+
+/**
+ * Convert a context into a string.
+ */
+function ctools_context_user_edit_convert($context, $type) {
+  // Pass through to the "node" context convert list.
+  $plugin = ctools_get_context('user');
+  return ctools_context_user_convert($context, $type);
+}
-- 
1.7.4.1

