2009-10-15 21:19:31 +00:00
< ? php
/**
* @ file
* Helper functions and form handlers used for the authorize . php script .
*/
/**
2011-12-05 12:52:27 +00:00
* Form constructor for the file transfer authorization form .
*
* Allows the user to choose a FileTransfer type and supply credentials .
*
* @ see authorize_filetransfer_form_validate ()
* @ see authorize_filetransfer_form_submit ()
* @ ingroup forms
2009-10-15 21:19:31 +00:00
*/
2011-01-04 04:37:27 +00:00
function authorize_filetransfer_form ( $form , & $form_state ) {
2009-11-01 23:02:13 +00:00
global $base_url , $is_https ;
2009-10-15 21:19:31 +00:00
$form = array ();
2012-09-02 04:50:06 +00:00
// If possible, we want to post this form securely via HTTPS.
2009-11-01 23:02:13 +00:00
$form [ '#https' ] = TRUE ;
2009-10-15 21:19:31 +00:00
// Get all the available ways to transfer files.
2010-12-01 00:23:36 +00:00
if ( empty ( $_SESSION [ 'authorize_filetransfer_info' ])) {
2009-10-15 21:19:31 +00:00
drupal_set_message ( t ( 'Unable to continue, no available methods of file transfer' ), 'error' );
return array ();
}
2010-12-01 00:23:36 +00:00
$available_backends = $_SESSION [ 'authorize_filetransfer_info' ];
2009-10-15 21:19:31 +00:00
2009-11-01 23:02:13 +00:00
if ( ! $is_https ) {
2011-01-04 04:37:27 +00:00
$form [ 'information' ][ 'https_warning' ] = array (
'#prefix' => '<div class="messages error">' ,
'#markup' => t ( 'WARNING: You are not using an encrypted connection, so your password will be sent in plain text. <a href="@https-link">Learn more</a>.' , array ( '@https-link' => 'http://drupal.org/https-information' )),
'#suffix' => '</div>' ,
);
2009-11-01 23:02:13 +00:00
}
2009-10-15 21:19:31 +00:00
// Decide on a default backend.
if ( isset ( $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ])) {
$authorize_filetransfer_default = $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ];
}
elseif ( $authorize_filetransfer_default = variable_get ( 'authorize_filetransfer_default' , NULL ));
else {
$authorize_filetransfer_default = key ( $available_backends );
}
$form [ 'information' ][ 'main_header' ] = array (
'#prefix' => '<h3>' ,
2010-01-09 23:03:22 +00:00
'#markup' => t ( 'To continue, provide your server connection details' ),
2009-10-15 21:19:31 +00:00
'#suffix' => '</h3>' ,
);
$form [ 'connection_settings' ][ '#tree' ] = TRUE ;
$form [ 'connection_settings' ][ 'authorize_filetransfer_default' ] = array (
'#type' => 'select' ,
'#title' => t ( 'Connection method' ),
'#default_value' => $authorize_filetransfer_default ,
'#weight' => - 10 ,
);
/*
* Here we create two submit buttons . For a JS enabled client , they will
* only ever see submit_process . However , if a client doesn ' t have JS
2009-10-22 00:52:03 +00:00
* enabled , they will see submit_connection on the first form ( when picking
2010-01-25 10:38:35 +00:00
* what filetransfer type to use , and submit_process on the second one ( which
2009-10-22 00:52:03 +00:00
* leads to the actual operation ) .
2009-10-15 21:19:31 +00:00
*/
$form [ 'submit_connection' ] = array (
'#prefix' => " <br style='clear:both'/> " ,
2009-10-22 00:52:03 +00:00
'#name' => 'enter_connection_settings' ,
2009-10-15 21:19:31 +00:00
'#type' => 'submit' ,
2009-10-22 00:52:03 +00:00
'#value' => t ( 'Enter connection settings' ),
2009-10-15 21:19:31 +00:00
'#weight' => 100 ,
);
$form [ 'submit_process' ] = array (
2009-10-27 03:27:00 +00:00
'#name' => 'process_updates' ,
2009-10-15 21:19:31 +00:00
'#type' => 'submit' ,
2009-10-27 03:27:00 +00:00
'#value' => t ( 'Continue' ),
2009-10-15 21:19:31 +00:00
'#weight' => 100 ,
);
2011-01-04 04:37:27 +00:00
// Build a container for each connection type.
2009-10-15 21:19:31 +00:00
foreach ( $available_backends as $name => $backend ) {
$form [ 'connection_settings' ][ 'authorize_filetransfer_default' ][ '#options' ][ $name ] = $backend [ 'title' ];
$form [ 'connection_settings' ][ $name ] = array (
2011-01-04 04:37:27 +00:00
'#type' => 'container' ,
2010-05-14 04:50:18 +00:00
'#attributes' => array ( 'class' => array ( " filetransfer- $name " , 'filetransfer' )),
2012-05-16 02:58:58 +00:00
'#states' => array (
'visible' => array (
'select[name="connection_settings[authorize_filetransfer_default]"]' => array ( 'value' => $name ),
),
),
2011-01-04 04:37:27 +00:00
);
// We can't use #prefix on the container itself since then the header won't
// be hidden and shown when the containers are being manipulated via JS.
$form [ 'connection_settings' ][ $name ][ 'header' ] = array (
'#markup' => '<h4>' . t ( '@backend connection settings' , array ( '@backend' => $backend [ 'title' ])) . '</h4>' ,
2009-10-15 21:19:31 +00:00
);
2010-12-01 00:23:36 +00:00
$form [ 'connection_settings' ][ $name ] += _authorize_filetransfer_connection_settings ( $name );
2009-10-15 21:19:31 +00:00
// Start non-JS code.
if ( isset ( $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ]) && $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ] == $name ) {
// Change the submit button to the submit_process one.
$form [ 'submit_process' ][ '#attributes' ] = array ();
unset ( $form [ 'submit_connection' ]);
// Activate the proper filetransfer settings form.
$form [ 'connection_settings' ][ $name ][ '#attributes' ][ 'style' ] = 'display:block' ;
// Disable the select box.
$form [ 'connection_settings' ][ 'authorize_filetransfer_default' ][ '#disabled' ] = TRUE ;
// Create a button for changing the type of connection.
$form [ 'connection_settings' ][ 'change_connection_type' ] = array (
'#name' => 'change_connection_type' ,
'#type' => 'submit' ,
'#value' => t ( 'Change connection type' ),
'#weight' => - 5 ,
2011-01-04 04:37:27 +00:00
'#attributes' => array ( 'class' => array ( 'filetransfer-change-connection-type' )),
2009-10-15 21:19:31 +00:00
);
}
// End non-JS code.
}
return $form ;
}
2010-12-01 00:23:36 +00:00
/**
2011-12-05 12:52:27 +00:00
* Generates the Form API array for a given connection backend ' s settings .
2010-12-01 00:23:36 +00:00
*
* @ param $backend
* The name of the backend ( e . g . 'ftp' , 'ssh' , etc ) .
2011-12-05 12:52:27 +00:00
*
2010-12-01 00:23:36 +00:00
* @ return
* Form API array of connection settings for the given backend .
*
* @ see hook_filetransfer_backends ()
*/
function _authorize_filetransfer_connection_settings ( $backend ) {
$defaults = variable_get ( 'authorize_filetransfer_connection_settings_' . $backend , array ());
$form = array ();
// Create an instance of the file transfer class to get its settings form.
$filetransfer = authorize_get_filetransfer ( $backend );
if ( $filetransfer ) {
$form = $filetransfer -> getSettingsForm ();
}
// Fill in the defaults based on the saved settings, if any.
_authorize_filetransfer_connection_settings_set_defaults ( $form , NULL , $defaults );
return $form ;
}
/**
2011-12-05 12:52:27 +00:00
* Sets the default settings on a file transfer connection form recursively .
2010-12-01 00:23:36 +00:00
*
* The default settings for the file transfer connection forms are saved in
* the database . The settings are stored as a nested array in the case of a
* settings form that has fieldsets or otherwise uses a nested structure .
* Therefore , to properly add defaults , we need to walk through all the
* children form elements and process those defaults recursively .
*
2011-05-08 19:50:38 +00:00
* @ param $element
2010-12-01 00:23:36 +00:00
* Reference to the Form API form element we ' re operating on .
* @ param $key
* The key for our current form element , if any .
* @ param array $defaults
* The default settings for the file transfer backend we ' re operating on .
*/
function _authorize_filetransfer_connection_settings_set_defaults ( & $element , $key , array $defaults ) {
// If we're operating on a form element which isn't a fieldset, and we have
// a default setting saved, stash it in #default_value.
if ( ! empty ( $key ) && isset ( $defaults [ $key ]) && isset ( $element [ '#type' ]) && $element [ '#type' ] != 'fieldset' ) {
$element [ '#default_value' ] = $defaults [ $key ];
}
// Now, we walk through all the child elements, and recursively invoke
// ourself on each one. Since the $defaults settings array can be nested
// (because of #tree, any values inside fieldsets will be nested), if
// there's a subarray of settings for the form key we're currently
// processing, pass in that subarray to the recursive call. Otherwise, just
// pass on the whole $defaults array.
foreach ( element_children ( $element ) as $child_key ) {
_authorize_filetransfer_connection_settings_set_defaults ( $element [ $child_key ], $child_key , (( isset ( $defaults [ $key ]) && is_array ( $defaults [ $key ])) ? $defaults [ $key ] : $defaults ));
}
}
2009-10-15 21:19:31 +00:00
/**
2011-12-05 12:52:27 +00:00
* Form validation handler for authorize_filetransfer_form () .
2009-10-15 21:19:31 +00:00
*
* @ see authorize_filetransfer_form ()
2011-12-05 12:52:27 +00:00
* @ see authorize_filetransfer_submit ()
2009-10-15 21:19:31 +00:00
*/
function authorize_filetransfer_form_validate ( $form , & $form_state ) {
2011-01-04 04:37:27 +00:00
// Only validate the form if we have collected all of the user input and are
// ready to proceed with updating or installing.
2011-06-30 06:16:23 +00:00
if ( $form_state [ 'triggering_element' ][ '#name' ] != 'process_updates' ) {
2011-01-04 04:37:27 +00:00
return ;
}
2009-10-15 21:19:31 +00:00
if ( isset ( $form_state [ 'values' ][ 'connection_settings' ])) {
$backend = $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ];
$filetransfer = authorize_get_filetransfer ( $backend , $form_state [ 'values' ][ 'connection_settings' ][ $backend ]);
try {
if ( ! $filetransfer ) {
2012-06-29 13:22:19 +00:00
throw new Exception ( t ( 'The connection protocol %backend does not exist.' , array ( '%backend' => $backend )));
2009-10-15 21:19:31 +00:00
}
$filetransfer -> connect ();
}
catch ( Exception $e ) {
2011-01-03 02:41:33 +00:00
// The format of this error message is similar to that used on the
// database connection form in the installer.
form_set_error ( 'connection_settings' , t ( 'Failed to connect to the server. The server reports the following message: !message For more help installing or updating code on your server, see the <a href="@handbook_url">handbook</a>.' , array (
'!message' => '<p class="error">' . $e -> getMessage () . '</p>' ,
'@handbook_url' => 'http://drupal.org/documentation/install/modules-themes' ,
)));
2009-10-15 21:19:31 +00:00
}
}
}
/**
2011-12-05 12:52:27 +00:00
* Form submission handler for authorize_filetransfer_form () .
2009-10-15 21:19:31 +00:00
*
* @ see authorize_filetransfer_form ()
2011-12-05 12:52:27 +00:00
* @ see authorize_filetransfer_validate ()
2009-10-15 21:19:31 +00:00
*/
function authorize_filetransfer_form_submit ( $form , & $form_state ) {
global $base_url ;
2011-06-30 06:16:23 +00:00
switch ( $form_state [ 'triggering_element' ][ '#name' ]) {
2009-10-15 21:19:31 +00:00
case 'process_updates' :
// Save the connection settings to the DB.
$filetransfer_backend = $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ];
// If the database is available then try to save our settings. We have
// to make sure it is available since this code could potentially (will
// likely) be called during the installation process, before the
// database is set up.
2010-04-23 05:21:19 +00:00
try {
2009-10-15 21:19:31 +00:00
$connection_settings = array ();
foreach ( $form_state [ 'values' ][ 'connection_settings' ][ $filetransfer_backend ] as $key => $value ) {
// We do *not* want to store passwords in the database, unless the
// backend explicitly says so via the magic #filetransfer_save form
// property. Otherwise, we store everything that's not explicitly
// marked with #filetransfer_save set to FALSE.
if ( ! isset ( $form [ 'connection_settings' ][ $filetransfer_backend ][ $key ][ '#filetransfer_save' ])) {
if ( $form [ 'connection_settings' ][ $filetransfer_backend ][ $key ][ '#type' ] != 'password' ) {
$connection_settings [ $key ] = $value ;
}
}
// The attribute is defined, so only save if set to TRUE.
elseif ( $form [ 'connection_settings' ][ $filetransfer_backend ][ $key ][ '#filetransfer_save' ]) {
$connection_settings [ $key ] = $value ;
}
}
// Set this one as the default authorize method.
variable_set ( 'authorize_filetransfer_default' , $filetransfer_backend );
// Save the connection settings minus the password.
2009-10-22 00:52:03 +00:00
variable_set ( 'authorize_filetransfer_connection_settings_' . $filetransfer_backend , $connection_settings );
2009-10-15 21:19:31 +00:00
$filetransfer = authorize_get_filetransfer ( $filetransfer_backend , $form_state [ 'values' ][ 'connection_settings' ][ $filetransfer_backend ]);
2010-01-30 07:59:26 +00:00
2009-10-15 21:19:31 +00:00
// Now run the operation.
authorize_run_operation ( $filetransfer );
}
2010-04-23 05:21:19 +00:00
catch ( Exception $e ) {
// If there is no database available, we don't care and just skip
// this part entirely.
}
2009-10-15 21:19:31 +00:00
break ;
case 'enter_connection_settings' :
$form_state [ 'rebuild' ] = TRUE ;
break ;
case 'change_connection_type' :
$form_state [ 'rebuild' ] = TRUE ;
unset ( $form_state [ 'values' ][ 'connection_settings' ][ 'authorize_filetransfer_default' ]);
break ;
}
}
/**
2011-12-05 12:52:27 +00:00
* Runs the operation specified in $_SESSION [ 'authorize_operation' ] .
2009-10-15 21:19:31 +00:00
*
* @ param $filetransfer
* The FileTransfer object to use for running the operation .
*/
function authorize_run_operation ( $filetransfer ) {
$operation = $_SESSION [ 'authorize_operation' ];
unset ( $_SESSION [ 'authorize_operation' ]);
if ( ! empty ( $operation [ 'page_title' ])) {
2010-12-29 04:07:52 +00:00
drupal_set_title ( $operation [ 'page_title' ]);
2009-10-15 21:19:31 +00:00
}
require_once DRUPAL_ROOT . '/' . $operation [ 'file' ];
call_user_func_array ( $operation [ 'callback' ], array_merge ( array ( $filetransfer ), $operation [ 'arguments' ]));
}
/**
2011-12-05 12:52:27 +00:00
* Gets a FileTransfer class for a specific transfer method and settings .
2009-10-15 21:19:31 +00:00
*
* @ param $backend
* The FileTransfer backend to get the class for .
* @ param $settings
* Array of settings for the FileTransfer .
2011-12-05 12:52:27 +00:00
*
2009-10-15 21:19:31 +00:00
* @ return
* An instantiated FileTransfer object for the requested method and settings ,
* or FALSE if there was an error finding or instantiating it .
*/
function authorize_get_filetransfer ( $backend , $settings = array ()) {
$filetransfer = FALSE ;
2010-12-01 00:23:36 +00:00
if ( ! empty ( $_SESSION [ 'authorize_filetransfer_info' ][ $backend ])) {
$backend_info = $_SESSION [ 'authorize_filetransfer_info' ][ $backend ];
if ( class_exists ( $backend_info [ 'class' ])) {
2011-06-11 23:33:58 +00:00
$filetransfer = $backend_info [ 'class' ] :: factory ( DRUPAL_ROOT , $settings );
2010-12-01 00:23:36 +00:00
}
2009-10-15 21:19:31 +00:00
}
return $filetransfer ;
}