How to create resource,end point and use web service using Services module in Drupal?

As per my requirement, I was to fetch some data from third party and store into Drupal database.

For this, I created my own web service using Services module.
Here are steps for creating Service -


Note - I developed web service using Services 6.x module which is not in projects now in drupal.org.

So here steps are based on the Drupal6. 

1. First of all install services and all its dependent modules.

2. Go to the admin/build/services and click on Add to add end point.

3. Give respective name to the end point and path to endpoint for your service.(I would suggest to you keep same name for both).

4. In server drop down, you will found XML/RPC and REST by default.(Only if you have enabled these two modules from admin).

5. I will suggest you to use soap_server module.(Its easy to implement and test). Install soap_server and enable it. then select it form server drop down while adding end point. Leave other settings as it is.

6. Once you save your end point, you can see Resources, Server, Authentication etc links. Our main focus in Resources. There will be some default resources listed  but here we have to add our resource.

7. For adding resource, create a module. and add hook_services_resources - 


/**

 * Implementation of hook_services_reources().

 */

function hook_services_resources() {

  return array(

    // change your_resource_name

    'your_resource_name' => array(

    // change your_opration_name_under_resource

     'your_opration_name_under_resource' => array(

        'help' => 'Add help text here',

        'callback' => '_survey_custom_survey_data',     // change callback function

        'access callback' => '_survey_custom_survey_data_access',  // change access callback

        // Keep below settings as it is

        'access arguments append' => TRUE,

        'args' => array(

          array(

            'name' => 'input_xml',

            'type' => 'string',

            'description' => 'Data in XML Format',

            'source' => array('path' => '0'),

            'optional' => FALSE,

          ),

        ),

      ),

    ),

  );

}


/**

 * Implementation of Resource access callback().

 */

function _survey_custom_survey_data_access() {

  return TRUE;

}


/**

 * This is th main callback function which will recieve data when service gets called().

 * It will recieve data in json format and decode it to store in Drupal database.

 */

function _survey_custom_survey_data($json_object) {

  $decoded_json_data = json_decode($json_object);

  return $decoded_json_data;

 }

 

8. Next step is to select this resource for the particular end point. Click on Edit Resources in admin/build/services for the end point you want to add this resource. You can see your create resource will be appear in the resource list. Select it.


9. Its time to test the service. For this create one test.php file.This file you can create in some other server add below code -

<?PHP

    ini_set('display_errors', 'On');

 // Add full url of your domain, where you have create "your_resource_name" end point.

// We are concatenating $base_url with resource name which we have create using code to create wsdl.

    $client = new SoapClient("http://your-domain/your_resource_name?wsdl");

// Third party who will use this service, they need to create json object of data and pass like below

    $json_object ='[{"FieldName":"survey_id","FieldValue":"110"},{"FieldName":"survey_title","FieldValue":"Century Survey"}]';

 // Here you need to call method name and pass json object.

 // To get method name, you can copy and paste wsdl url in web browser and check the opration name. That will be your method name.

    $result = $client->module_name_soap_your_resource_name($json_object);

    print '<pre>';

    print_r($result);

    die;

?>


10. This function _survey_custom_survey_data() will return decoded json of the data which we have recieved from service.


An Introduction to the Drupal Features Module

Most of the people get confused when they plan to use Drupal features module. I am giving few useful steps which will help you to create your own features. 

Features can be anything. A view, block, menus or content type etc.

You must be thinking that what is the actual use of features module. So I will a small example for your clarification.

For example you create a complex view in your local Drupal instance. Now you want to use the same view in development server or in some other server, than how will you do that? You will again create thw same complex view again in development server. Personally I would not suggest you to do that. Here comes a concept of features.

Steps- 

1. Once you are done with views creation than download features modules from here. Install and enable it. 
2. Go to the Structure->Features->Create Feature. 
3. Give a appropriate name for the view and select your view from drop down list.
4. Now at the end of page, click Download Feature. Once you download it, it will come as rar file which contains a module.
5. Next steps is to create one folder called features inside sites/all/modules folder so that you can differentiate  between your custom, contrib modules and features.
6. Paste your download feature inside sites/all/modules/features folder. Extract it and now this feature will be available in module list in admin. 
7. Enable this feature and it is ready to use.

Note- These above steps I explained for views example. These steps you can use for content type, blocks, menus etc.


How to create Multiple Forms in Drupal 7

After spending couple of hours finally I got solution to create multiple custom forms and display on single page with proper UI.
Follow the below steps to create the same-
1. First of all create a menu item in hook_menu() where you want to display forms.
function example_menu() {
  $items['user-login'] = array(
    'title' => 'Multiple Forms on Single Page',
    'page callback' => 'custom_salesforce_user_login_page',
    'access callback' => 'user_is_anonymous',
  );
  return $items;
}

2. Second step is to write a callback function which is written in hook_menu(). Inside this callback, write all the forms which you want to display on one page.
function custom_salesforce_user_login_page() {
  $custom_salesforce_login_form = drupal_get_form('custom_salesforce_login_form');
  $custom_salesforce_update_form = drupal_get_form('custom_salesforce_update_form');
  $combine_form = array('arg1' => $custom_salesforce_login_form, 'arg2' => $custom_salesforce_update_form);
  $output = theme('custom_salesforce_login_and_update', $combine_form);
  return $output;
}

3. Now create these two forms.
First Form-
function custom_salesforce_login_form($form, &$form_state) {
  $form['rtc_registered_email'] = array(
    '#type' => 'textfield',
    '#required' => FALSE,
    '#title' => t('Registered Email'),
  );
  $form['rtc_password'] = array(
    '#type' => 'password',
    '#required' => FALSE,
    '#title' => t('Password'),
  );
  $form['rtc_submit'] = array(
    '#type' => 'submit',
    '#id' => 'salesforce_ret_couple_login',
    '#value' => t('Login'),
  );
  return $form;
}

Second Form-
function custom_salesforce_update_form($form, &$form_state) {
  $form['fth_registered_email'] = array(
    '#type' => 'textfield',
    '#required' => FALSE,
    '#title' => t('Registered Email'),
  );
  $form['fth_create_password'] = array(
    '#type' => 'password',
    '#required' => FALSE,
    '#title' => t('Password'),
  );
  $form['fth_confirm_password'] = array(
    '#type' => 'password',
    '#required' => FALSE,
    '#title' => t('Confirm Password'),
  );
  $form['fth_submit'] = array(
    '#type' => 'submit',
    '#id' => 'salesforce_fth_login',
    '#value' => t('Create Password'),
  );
  return $form;
}

4. Next step is to create a hook_theme() function to theame these forms.
function custom_salesforce_theme() {
  return array(
 // this template is containing theme style for update form
    'custom_salesforce_update_form' => array(
      'template' => 'theme/custom_salesforce_update_form',
      'render element' => 'form',
    ),
 // this template is containing theme style for login form
    'custom_salesforce_login_form' => array(
      'template' => 'theme/custom_salesforce_login_form',
      'render element' => 'form',
    ),
 // this template is containing theme style for both forms
    'custom_salesforce_login_and_update' => array(
      'template' => 'theme/custom_salesforce_login_and_update',
      'arguments' => array('combine_form' => NULL),
    ),
  );
}


Note- Don't forget to create three template files inside theme folder inside your module.
5. Next step to write template preprocessor functions to display individual fields in separate template files.
/**
 * Implements Template Preprocessor For User Login().
 */

function template_preprocess_custom_salesforce_login_form(&$variables) {
  $variables['rtc_registered_email'] = drupal_render($variables['form']['rtc_registered_email']);
  $variables['rtc_password'] = drupal_render($variables['form']['rtc_password']);
  $variables['rtc_submit_form'] = drupal_render_children($variables['form']);
}

Note:- Use these above variable names with "$" inside respective templates and give design as you want. For example use below html code for inside 
custom_salesforce_login_form template.
<html>
<head>
</head>
<body>
<div class="login-form-fields">
<?php print $rtc_registered_email; ?>
</div>
<div class="login-form-fields">
<?php print $rtc_password; ?>
</div>
<div class="login-form-fields">
<?php print $rtc_submit_form; ?>
</div>
</body>
</html>


Follow the same procedure inside custom_salesforce_update_form template for second form also.Just change the variable names as defined below.
/**
 * Implements Template Preprocessor For Update User().
 */

function template_preprocess_custom_salesforce_update_form(&$variables) {
  $variables['fth_registered_email'] = drupal_render($variables['form']['fth_registered_email']);
  $variables['fth_create_password'] = drupal_render($variables['form']['fth_create_password']);
  $variables['fth_confirm_password'] = drupal_render($variables['form']['fth_confirm_password']);
  $variables['fth_submit'] = drupal_render_children($variables['form']);
}


Now we need to display above two forms together on one page. For that just print these two below variables in custom_salesforce_login_and_update template. 
Examples-
<html>
<head>
</head>
<body>
<div class="login-form-fields">
<?php print $arg_return_couple_form; ?>
</div>
<div class="login-form-fields">
<?php print $arg_first_time_login_form; ?>
</div>
</body>
</html>

/**
 * Implements Template Preprocessor For Login and Update User().
 */

function template_preprocess_
custom_salesforce_login_and_update(&$variables) {
  $variables['arg_return_couple_form'] = drupal_render($variables['arg1']);
  $variables['arg_first_time_login_form'] = drupal_render($variables['arg2']);
}