Skip to content

Instantly share code, notes, and snippets.

@kmoll
Created December 23, 2015 16:21
Show Gist options
  • Save kmoll/4b8a5f9278b1e9808692 to your computer and use it in GitHub Desktop.
Save kmoll/4b8a5f9278b1e9808692 to your computer and use it in GitHub Desktop.
<?php
/**
* Implements hook_element_info().
*
* The managed file element may be used anywhere in Drupal.
*/
function obfuscate_textfield_element_info() {
$file_path = drupal_get_path('module', 'obfuscate_textfield');
$types['obfuscate_textfield'] = array(
'#input' => TRUE,
'#process' => array('obfuscate_textfield_element_process'),
'#value_callback' => 'obfuscate_textfield_element_value',
'#element_validate' => array('obfuscate_textfield_element_validate'),
'#pre_render' => array('obfuscate_textfield_element_pre_render'),
'#theme' => 'obfuscate_textfield_element',
'#theme_wrappers' => array('form_element'),
'#progress_indicator' => 'throbber',
'#progress_message' => NULL,
//'#upload_validators' => array(),
// '#upload_location' => NULL,
'#size' => 22,
'#extended' => FALSE,
// '#attached' => array(
// 'css' => array($file_path . '/file.css'),
// 'js' => array($file_path . '/file.js'),
// ),
);
return $types;
}
/**
* Implements hook_theme().
*/
function obfuscate_textfield_theme() {
return array(
'obfuscate_textfield_element' => array(
'render element' => 'element',
),
);
}
function theme_obfuscate_textfield_element($variables) {
$element = $variables['element'];
$attributes = array();
if (isset($element['#id'])) {
$attributes['id'] = $element['#id'];
}
if (!empty($element['#attributes']['class'])) {
$attributes['class'] = (array) $element['#attributes']['class'];
}
$attributes['class'][] = 'form-obfuscate-textfield';
// This wrapper is required to apply JS behaviors and CSS styling.
$output = '';
$output .= '<div' . drupal_attributes($attributes) . '>';
$output .= drupal_render_children($element);
$output .= '</div>';
return $output;
}
function obfuscate_textfield_element_process($element, &$form_state, $form) {
// Append the '-upload' to the #id so the field label's 'for' attribute
// corresponds with the file element.
$original_id = $element['#id'];
$element['#id'] .= '-text';
$value = isset($element['#value']) ? $element['#value'] : '';
// Set some default element properties.
$element['#progress_indicator'] = empty($element['#progress_indicator']) ? 'none' : $element['#progress_indicator'];
// $element['#file'] = $fid ? file_load($fid) : FALSE;
//$element['#tree'] = TRUE;
$ajax_settings = array(
'path' => 'file/ajax/' . implode('/', $element['#array_parents']) . '/' . $form['form_build_id']['#value'],
'wrapper' => $original_id . '-ajax-wrapper',
'effect' => 'fade',
'progress' => array(
'type' => $element['#progress_indicator'],
'message' => $element['#progress_message'],
),
);
// Force the progress indicator for the remove button to be either 'none' or
// 'throbber', even if the upload button is using something else.
$ajax_settings['progress']['type'] = ($element['#progress_indicator'] == 'none') ? 'none' : 'throbber';
$ajax_settings['progress']['message'] = NULL;
$ajax_settings['effect'] = 'none';
$element['change_button'] = array(
'#name' => implode('_', $element['#parents']) . '_change_button',
'#type' => 'submit',
'#value' => t('Change'),
'#validate' => array(),
'#submit' => array('obfuscate_textfield_element_submit'),
'#limit_validation_errors' => array($element['#parents']),
'#ajax' => $ajax_settings,
'#weight' => -5,
);
// The file upload field itself.
$element['text'] = array(
//'#name' => 'files[' . implode('_', $element['#parents']) . ']',
'#type' => 'textfield',
'#title' => t('Choose a file'),
'#title_display' => 'invisible',
'#size' => $element['#size'],
'#theme_wrappers' => array(),
'#weight' => -10,
'#default_value' => $value,
);
if ($value) {
$element['markup'] = array(
'#type' => 'markup',
'#markup' => '**********',//theme('file_link', array('file' => $element['#file'])) . ' ',
'#weight' => -10,
);
}
// Prefix and suffix used for Ajax replacement.
$element['#prefix'] = '<div id="' . $original_id . '-ajax-wrapper">';
$element['#suffix'] = '</div>';
return $element;
}
function obfuscate_textfield_element_value(&$element, $input = FALSE, $form_state = NULL) {
$value = '';
$force_default = FALSE;
// Process any input and save new uploads.
if ($input !== FALSE && isset($input['text'])) {
return $input['text'];
}
// If there is no input or if the default value was requested above, use the
// default value.
if ($input === FALSE || $force_default) {
if ($element['#extended']) {
$value = isset($element['#default_value']['value']) ? $element['#default_value']['value'] : '';
// $return = isset($element['#default_value']) ? $element['#default_value'] : '';
}
else {
if (is_array($element['#default_value']) && isset($element['#default_value']['text'])) {
$value = $element['#default_value']['text'];
}
else {
$value = $element['#default_value'];
}
//$value = isset($element['#default_value']) ? $element['#default_value']: '';
//$return = array('value' => $value);
}
}
return $value; // $return;
}
function obfuscate_textfield_element_pre_render($element) {
// If we already have a file, we don't want to show the upload controls.
if (!empty($element['#value'])) {
$element['text']['#access'] = FALSE;
}
// If we don't already have a file, there is nothing to remove.
else {
if (isset($element['display_value'])) {
$element['display_value']['#access'] = FALSE;
}
$element['change_button']['#access'] = FALSE;
}
return $element;
}
function obfuscate_textfield_element_validate($element, &$form_state) {
}
function obfuscate_textfield_element_submit($form, &$form_state) {
// Determine whether it was the upload or the remove button that was clicked,
// and set $element to the managed_file element that contains that button.
$parents = $form_state['triggering_element']['#array_parents'];
$button_key = array_pop($parents);
$element = drupal_array_get_nested_value($form, $parents);
// No action is needed here for the upload button, because all file uploads on
// the form are processed by file_managed_file_value() regardless of which
// button was clicked. Action is needed here for the remove button, because we
// only remove a file in response to its remove button being clicked.
if ($button_key == 'change_button') {
// If it's a temporary file we can safely remove it immediately, otherwise
// it's up to the implementing module to clean up files that are in use.
// if ($element['#file'] && $element['#file']->status == 0) {
// file_delete($element['#file']);
// }
// Update both $form_state['values'] and $form_state['input'] to reflect
// that the file has been removed, so that the form is rebuilt correctly.
// $form_state['values'] must be updated in case additional submit handlers
// run, and for form building functions that run during the rebuild, such as
// when the managed_file element is part of a field widget.
// $form_state['input'] must be updated so that file_managed_file_value()
// has correct information during the rebuild.
$values_element = $element['#extended'] ? $element['value'] : $element;
form_set_value($values_element, NULL, $form_state);
drupal_array_set_nested_value($form_state['input'], $values_element['#parents'], NULL);
}
// Set the form to rebuild so that $form is correctly updated in response to
// processing the file removal. Since this function did not change $form_state
// if the upload button was clicked, a rebuild isn't necessary in that
// situation and setting $form_state['redirect'] to FALSE would suffice.
// However, we choose to always rebuild, to keep the form processing workflow
// consistent between the two buttons.
$form_state['rebuild'] = TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment