It is really easy to write a widget to the wordpress blog. So I thought of writing my own widget to show Google ads in my Blog. Here is how I did it.

  1. First generate the JavaScript code for your adsense account from the Google Adsense Page. You can do this by sigining in to the Dashboard of Adsense from https://www.google.com/adsense/. Then click the “Adsense Setup” tab and follow the wizard.
  2. Inside the “wp-content/plugins” directory of your WordPress installation create a file for your plugin. (Say myadsense_widget.php)
  3. Then first write the code that should be appeared in your widget.  In this case you can just echo the the code provide by the Google. Anyway In order to make your widget complaint with the current theme, you have to use the code similar to the following.
    // the function for the widget
    function widget_myadsense($args) {
    	// being aware of the theme
    	extract($args);
    	echo $before_widget;
    	echo $before_title . "Google Adsense". $after_title;
    
    	// here you just echo the code provided by the google 
    	echo <<<GOOGLE_JS
    		<!-- in this space you have to copy paste
                    the code provided by the google-->
    GOOGLE_JS;
    
    	// again being aware of the theme
    	echo $after_widget;
    }
  4. Then write the code to register the above function as a widget with the following piece of code.
    // initiating widget
    function myadsense_init()
    {
    	register_sidebar_widget(__('My Adsense'), 'widget_myadsense');
    }
    
    // adding the action
    add_action("plugins_loaded", "myadsense_init");
  5. We are almost done here, But don’t forget you can mention your information as the widget plugin author with a comment similar to the following template.
    /*
    Plugin Name: MyAdsense
    Plugin URI: http://dimuthu.org
    Description: Adsense Plugin for my blog
    Author: Dimuthu Gamage
    Version: 0.1
    Author URI: http://dimuthu.org
    */
  6. That is all you have to code. Now just go the Plugins section of the wordpress from your Dashboard and enable the plugin (“myadsesne”) you just created.
  7. Go to the Design->Widget section and add your Widget to the Sidebar and click “Save Changes”. And go to your blog URL and make sure that the Ads are shown in there.

Last week I wrote a how to on Writing a SOAP and REST Service with PHP. It shows how to write a single script that enables the SOAP and REST web services interfaces using WSF/PHP. Today I’m going to show you how you can use WSF/PHP to write clients in both SOAP and REST form.

For that I use the Amazon Client Demo hosted in the PHP Web Services Demo Site. With this demo you can do shopping with Amazon using their web services API. It uses a php library (AmazonClient.php) that allows us to connect Amazon using SOAP or REST libraries.

You can see in the library code It is using different values for “useSOAP” argument depending on what form of messaging we like to use. Amazon SOAP service uses the SOAP 1.1 and the REST service uses the “GET” HTTP method for messaging. We can configure these details as mentioned in the following table.

REST SOAP
array(
      "to"=>self::AMAZON_REST_ENDPOINT,
      "HTTPMethod"=>"GET",
      "useSOAP" => FALSE)
array(
      "to"=>self::AMAZON_SOAP_ENDPOINT,
      "useSOAP" => "1.1",
      "action" => "http://soap.amazon.com")

Since Amazon requires different request messages for SOAP and REST services, we have to create them separately depending on the request type. But the response returns by the service is same in both cases so we can handle it using the same code.

Here is how ItemLookup operation of the Amazon service is written within the above mentioned constrains.

    /**
     * ItemLookup
     * @param $ASIN Amaxon Item Id
     * @return associate array consist of the response parameters
     */
    public function ItemLookup($ASIN)
    {

        if($this->is_soap)
        {
             $req_payload = <<<XML
                <ItemLookup xmlns="http://webservices.amazon.com/AWSECommerceService/2007-10-29">
                    <SubscriptionId>{$this->amazon_key}</SubscriptionId>
                    <ResponseGroup>Medium</ResponseGroup>
                    <Request>
                        <ItemId>{$ASIN}</ItemId>
                        <ReviewPage>1</ReviewPage>
                    </Request>
                </ItemLookup>
XML;
        }
        else
        {
             $req_payload = <<<XML
                <ItemLookup xmlns="http://webservices.amazon.com/AWSECommerceService/2007-10-29">
                    <SubscriptionId>{$this->amazon_key}</SubscriptionId>
                    <Service>AWSECommerceService</Service>
                    <ResponseGroup>Large</ResponseGroup>
                    <Operation>ItemLookup</Operation>
                    <ItemId>{$ASIN}</ItemId>
                    <ReviewPage>1</ReviewPage>
                </ItemLookup>
XML;
        }

        $ret_message = $this->request($req_payload);

        $simplexml = new SimpleXMLElement($ret_message->str);

        $res = $simplexml;

        return $res;
    }

WSF/PHP Demo Site contains number of applications that demonstrate the different features of WSO2 WSF/PHP in practice. Calendar Service is one of such application. It demonstrate the use of WSDL Mode for a service with different policies for different operations + the use of Username tokens.

You can view the source code of the Calendar Service from here.

The username token is provided as an arguments to the WSService constructor at the end of the service script.

// our security token
$security_token = new WSSecurityToken(array("passwordCallback" => "get_password",
                                      "passwordType" => "plain"));
// create service in WSDL mode
$service = new WSService(array ("wsdl" =>"Calendar.wsdl",
        "actions" => $actions,
        "classmap" => $class_map,
        "securityToken" => $security_token,
        "operations" => $operations));

// process client requests and reply 
$service->reply();

We use a callback function (“get_password”) to validate the user and give that function name to the securityToken object constructor. Inside that callback function, we retrieve the password for the user from a database call. Here is the code inside the callback function that is again extracted out from the calendar service.

/**
 * call back function.
 * verify the validity of user enterd password with
 * the actual password which is kept in the database.
 */
$current_username = "";
function get_password($username)
{

    $dbhost = DB_HOST;
    $dbname = DB_NAME;
    $dbuname = DB_USERNAME;
    $dbpass = DB_PASSWORD;
    $link=mysql_connect($dbhost,  $dbuname,  $dbpass);
    mysql_select_db($dbname, $link);

    $sql="SELECT password FROM `customer_details` WHERE `user_name` = '".$username."'";
    $result=mysql_query($sql,$link);
    $password=mysql_fetch_array($result, MYSQL_NUM);

    global $current_username;
    if($password) {
         $current_username = $username;
         return $password[0];
    }
    else {
         $current_username = "";
         return NULL;
    }
}

So for all the operations which require authentication like login, getEvents, deleteEvents and addEvent, the WSF/PHP engine validate the user before invoking the operation. If the authentication fails, the engine will send a SOAP fault with the fault details. But in this service there is a operation which doesn’t require authentication. That is the ‘register’ operation. Because until the registration complete you can’t have a username password, so we should not authenticate that ‘register’ operation. So we need to provide a different policy for the ‘register’ operation.

The policies for each of the operation is declared in the Calender.wsdl itself.  If you look at the WSDL you can see each of the policies required by the operations are declared inside the policy elements as mentioned in WS-Policy Specification. And each of the operation refers the corresponding policy element from the binding section of the WSDL.

You can see how it is done for login (which requires authentication) and the register (which doesn’t requires authentication) from the code below.

        <wsdl:operation name="login">
            <soap12:operation soapAction="urn:login" style="document"/>
            <wsdl:input>
                <wsp:PolicyReference URI="#username_token_policy"/>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>
        <wsdl:operation name="register">
            <soap12:operation soapAction="urn:register" style="document"/>
            <wsdl:input>
                <soap12:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap12:body use="literal"/>
            </wsdl:output>
        </wsdl:operation>

I have been working in Linux for a long time and recently moved to windows for a little change. (Hopefully for a little time :) . I find it is really easy to create a project for an Axis2/C client or service with Visual Studio. (I’m using Visual Studio 2005). Anyway I thought it is better to write down it somewhere so someone may find it useful.

Compiling Axis2/C Client

I’m using the math sample for this guide. You can find the source code inside “samples\client\math” directory of any  axis2/c binary or source.

  1. Create a new Visual Studio C++ Project, Select the project type to ‘Win32 Console Application’. Give a name to the project (say ‘math_client’) and in the wizard choose ‘Empty Project’. Then you will have an empty C/C++ project.
  2. Add the source files of the math samples to the project. You can do this by right clicking the project name in the Solution Explorer and clicking Add->Existing Item. After this step you will have axis2_math_stub.h in the Header Files section and the axis2_math_stub.c and math_client.c in the Source files section.
  3. Add Axis2/C include file directory. For this, go to ‘Tools->Options’ from the menu and select ‘Projects and Solutions->VC++ Directories’ from the Tree menu. Select the ‘Include files’ from ‘Show Directories for:’ drop down menu and add the ‘Axis2/C installed dir/includes’ directory. Note that if you follow this to add include directories you only need to do this only once for all the projects. If you want to do this only specifically to this project Go to ‘Project->Properties’ from the menu and Go to ‘Configuration Properties->C/C++->General and add the directories under ‘Additional Include Directories’)
  4. Add Axis2/C library directory. Here is how you do this. Go to the VC++ Directories form mentioned in the step 3 and select ‘Library files’ from the ‘Show Directories for:’ drop down menu. Then add the ‘Axis2/C installed dir/lib’ directory. If you add this here all the following project will use this directory to search for libraries. If you want this only to this project just skip this step and do what is specially mentioned in the step 5.
  5. Declare what libraries to link. For this, go to ‘Project->Properties’ from the menu and select “Configuration Properties->Linker->Input’ from the tree menu. In the ‘Additional Dependencies’ Text box add the following Axis2/C libraries.
    • axiom.lib
    • axutil.lib
    • axis2_engine.lib
    • axis2_parser.lib

    If you skipped the step 4, you have to type the complete path for the libraries.

  6. So that’s all you have to do.  You can compile and run the client using F5 or Ctrl+F5.

Debugging Axis2/C Client

  1. Since by default new project is created with the debug configurations, you can debug the program straight away. To test set a breakpoint at the start of the main function (in the math_client.c) and Run with Debugging (F5)

Compiling Axis2/C Service

We will use the corrosponding math service to create a Visual Studio project. It is same as how you created the math client project. But it has very little differences. (It requires only one additional step)

  1. Create a project in Visual Studio. This time select “Win32 Project” as the project type. Give a name to the project (“math_service”) and continue to the wizard. In there select the “Application Type” to be “DLL” and tick the “Empty Project” so we will have an empty project to build a DLL.
  2. Add the math service sample files to the project. You can find the source for the sample inside “samples\client\math” directory of the Axis2/c distribution.
  3. Add the Axis2/C include directory. If you have done it earlier using “Tools->Options” dialog box you don’t need to do that again since that settings persist over every project. But if you did it using “Project->Properties” dialog box you have to redo the step3 described in compiling client section for this project too.
  4. Add the Axis2/C library directory. Same as the step 4 in compiling client section.
  5. Declare the libraries to link. Same as the step 5 in the comping client section.
  6. Declare the “AXIS2_DECLARE_EXPORT” preprocessor constant. For this go to the “Project->Properties” and click the “Configuration Properties->C/C++->Preprocessor” and add the “AXIS2_DECLARE_EXPORT” at the end separated with a semi column.
  7. That is all needed to compile the service. Now you can build the project using “Build->BuildSolution or just type F7.

Debugging Axis2/C Service

  1. After you compile the source, you cand find the resulted DLL inside the debug directory of your project directory. Just copy it to the <axis2 installed dir>\services\math directory replacing math.dll file.
  2. Then Run the simple Axis2 Http Server in the <axis2 installed dir>\bin.
  3. Start the project you just created for the math service and go to “Debug->Attach To Process”. There you can see the list of running processes. Just select the axis2_http_server process.
  4. Now as a test create a breakpoint at the start of axis2_math_add function in the math.c file. (You will get a warning that no symbol is loaded for the file, but you can ignore that for the moment)
  5. Now send a request using the math client that you compiled earlier. You will see the breakpoint is hit in the service project. So you can debug the service as you like.

WSF/PHP enables you to write both REST and SOAP services in PHP from a single script. I have written about how you can expose your Database as a REST and SOAP services in few of my previous posts using the Data Service capability of WSF/PHP. But there can be situations where your service is not based on a Database. For an example it can use results of some calculations, or a mashup calling other services. In that case you will prefer to write the service logic yourself. Here is how you can do it.

Lets think we have weather forecast data (may be from another service) and I want to make a web service using it and make it accessible via both REST and SOAP protocols.

In our demo service we give forecasts of temperature, humidity and some other parameters for a given date. So I expect

SOAP request payload as following.

<weatherReport>
  <date>{date}</date>
  <parameter>{parameter}</parameter>
</weatherReport>

And REST Request will be like

weatherReport/{date}/forecast/{parameter}

Note that here parameter can hold values like temperature, humidity or sunset-time.

First we declare our operation and the REST Request Mapping like this,

$operations = array("weatherReport" => "weather_report");
$restmap = array("weatherReport" =>
				array("HTTPMethod" =>"GET",
				      "RESTLocation" => "weatherReport/{date}/forecast/{parameter}"));

When you declare your rest mapping like above , in the service operation you will have the same request XML for both SOAP and REST form like this,

<weatherReport>
  <date>{date}</date>
  <parameter>{parameter}</parameter>
</weatherReport>

So in your service logic you just handling the request in only above format. You can easily extract out the request parameters using SimpleXML functions and return the corresponding result. So you service operation would be something like this,

function weather_report($in_message) {

	// create the simple xml element for the request xml
	$request_xml = new SimpleXMLElement($in_message->str);

	// extract out the parameter and the date
	$date = $request_xml->date;
	$parameter = $request_xml->parameter;

	// It is up to you to retrun the weather data ($result) for the requested date and parameter

	return "<response>$result</response>";
}

Finally you create the WSService object with the “operations” and “RESTMapping” and call its reply method which actually response to the requests.

$service = new WSService(array("operations" => $operations, "RESTMapping" => $restmap));
$service->reply();

You just created a web service which will handle both SOAP and REST requests.

In WSF/PHP WDL Mode we have two APIs, first one is the class based API which we give a class object as the input parameter for the operation and expect to retrieve a class object as the response as well. The other API is the array based API. which we give an array (in fact an associated map) containing all the necessary information and returns an array filled with response information.

If you are using WSDL2PHP script you are always using the class based API. But there are situations where you can easily use array based API instead of the class based API. Here is an example.

Take the simple add operation of the following WSDL, http://labs.wso2.org/wsf/php/example.xml.

If you generated the code using wsdlphp tool (Here is the complete generated code for the above wsdl using online wsdlphp tool) You can see two classes are generated for the above operation, one for the input object and the other for the output object.

class simpleAdd {

    /**
     * @var int
     */
    public $param0;

    /**
     * @var int
     */
    public $param1;

}

class simpleAddResponse {

    /**
     * @var int
     */
    public $return;

}

So in order to invoke the service you need to create an object of the simpleAdd and set your input parameters and return the value from the simpleAddResponse object.

  $input = new simpleAdd();

  $input->param0 = 3;
  $input->parma1 = 4;

  // call the operation
  $response = $proxy->simpleAdd($input);

  // extract the return value
  echo $response->return;

But if you are using array mode for the same operation it will be something like this.

  // input as an array
  $input = array("param0" => 3, "param1" => 4);

  // call the operation
  $response = $proxy->simpleAdd($input);

  // extract out the return value from the array
  echo $response["return"];

In this approach you don’t need to declare classes at the start. So you can write the code without the support of WSDL2PHP tool. Anyway for complex scenarios it is not easy to find the keys needed to be in the input array, so it is better depend on the generated code. But you can use array based approach more productively for simple scenarios like this.

WSF/PHP Demo Site services can be accessed via https (Secured HTTP)  transport. For an example you can access the echo service via https from https://2ec2.wso2.org/samples/echo_service.php endpoint. This can be used to identify whether you WSF/PHP instance is built with SSL enabled. (Note that from WSF/PHP 2.0.0 onwards, You have SSL enabled by default both in Linux and Windows, so for newer releases you don’t need explicitly set that when compiling).

Here is a sample client I used to connect to the https service. The only thing new from the traditional echo client is it has specified “CACert” option and the URL is pointing to a https service.

<?php
$requestPayloadString = <<<XML
<ns1:echoString xmlns:ns1="http://wso2.org/wsfphp/samples"><text>Hello World!</text></ns1:echoString>
XML;

try {

    $client = new WSClient(array( "to" => "https://2ec2.wso2.org/samples/echo_service.php",
                                "CACert" => "./resources/cacert.pem"));

    $responseMessage = $client->request( $requestPayloadString );

    printf("Response = %s <br>", htmlspecialchars($responseMessage->str));

} catch (Exception $e) {

    if ($e instanceof WSFault) {
        printf("Soap Fault: %s\\n", $e->Reason);
    } else {
        printf("Message = %s\\n",$e->getMessage());
    }

}
?>

If you are behind a proxy server you need to configure your client to send the request through proxy. With WSF/PHP you can do it in two ways.

1. Setting proxy configuration in WSClient itself

You can use the ‘proxyHost’ and ‘proxyPort’ options to provide the proxy information through WSClient.

$client = new WSClient(array("to" => "http://my.external.host/service_url",
                  "proxyHost" => PROXY_HOST,
                  "proxyPort" => PROXY_PORT));

2. Use the axis2.xml

Change the axis2.xml to the following. (axis2.xml is in the wsf_c directory which is by default installed inside the php extension directory unless you specified it explicitly in your php.ini ‘wsf.home’ entry)

    <transportSender name="http" class="axis2_http_sender">
        <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
      <parameter name="xml-declaration" insert="false"/>
      <!--Here is where you set the proxy host and the port-->
      <parameter name="PROXY" proxy_host="MY_PROXY_HOST" proxy_port="MY_PROXY_IP" locked="true"/>
    </transportSender>

So if you want only to use the proxy for particular clients, you can use the former approach. But if you want to use the proxy for all the clients in your system just use the later approach so you don’t need to edit each client.

Yesterday I wrote a how-to on doing MSSQL DataService in PHP. It was just about installing necessary PDO drivers and setting the following configurations about your Database.

// database configurations
$config = array(
		"db" => "mssql",
		"username" => DB_USERNAME
		"password" => DB_PASSWORD
		"dbname" => DB_NAME,
		"dbhost" => DB_SERVER_NAME
		);

But when it comes to SQLite you don’t have such thing called database server, name, username or password. It is just a file in your computer. In this kind of situation you can directly use the PDO DSN (standards for Data Source Name) string to configure your database.

// giving my sqlite database file information
$config = array(
    "dsn" => "sqlite2:mydbfile.db");

So this is all specific to SQLite. For the rest of the code, you don’t need to worry about the underlying database you use. Please read the blog about the PHP DataServices 2 Minutes Introduction for short guide on PHP data services in general.

PHP in most percentage is used with MySQL Server in LAMP or WAMP stacks. But there may be situations where PHP uses MSSQL databases in back-end. And PHP scripts can be used to make Web services exposing MSSQL Databases. That is enabled by the  Data Services capability in WSF/PHP 2.0.0.

Here are the steps to get the PHP Data Services working with MSSQL in windows. You can safelty skip the starting point if you have already have the necessory software installed.

  • Download Apache Web Server, PHP and MSSQL server. (You can download the MSSQL server 2005 expess edition from here.
  • Enable the php_mssql, php_pdo and php_pdo_mssql extension from the php.ini.
  • If you have MSSQL server 2005, the default client DLL (ntwdblib.dll) use to connect to MSSQL server will not work. So you need to download a newer version of this dll. You can easily find this googling the name of the dll. (The dll version worked for me is 2000.80.194.0). Copy this dll to following directories.
    • <your_windows_drive>/windows/system32
    • <your_apache_installation>/apache2/bin
  • To Demo purpose I have created a MSSQL database called “RESTFulSchool” and and table called ‘Subjects” with the following schema. If you already have a MSSQL database you can just continue with that.
    Column Name Data Type
    subjectID int
    subjectName text
    subjectTeacher text

    And make sure you fill some data into the table. You can get this done easily with MSSQL Server Management Studio downloadable from http://www.microsoft.com/sql/editions/express/default.mspx

  • So here is my code to the Data Service. Note in the config variable I have given the information about my MSSQL connection.
    <?php
    
    //Including the Data Services library
    require_once("wso2/DataServices/DataService.php");
    
    //Including the connection information for my MSSQL Connection
    require_once("constants.php");
    
    // database configurations
    $config = array(
    		"db" => "mssql",
    		"username" => MSSQL_USERNAME
    		"password" => MSSQL_PASSWORD
    		"dbname" => "RESTfulSchool",
    		"dbhost" => MSSSQL_SERVER_NAME
    		);
    
    $output_format = array(
                        "resultElement" => "subjects",
                        "rowElement" => "subject",
                        "elements" => array(
                                "name" => "subjectName",
                                "teacher" => "subjectTeacher"));
    
    $sql = "SELECT subjectName, subjectTeacher FROM Subjects";
    
    $get_subjects_op = array("outputFormat" => $output_format, "sql" => $sql);
    
    $get_subjects_url = array("HTTPMethod" => "GET", "RESTLocation" => "subjects");
    
    // list of operations
    $operations = array(
                    "getSubjects" => $get_subjects_op,
                    );
    
    // list of rest url mappping (operation => url)
    $restmap = array(
                    "getSubjects" => $get_subjects_url,
                    );
    
    // creating DSService and reply
    $service = new DataService(array("config" => $config, "operations" => $operations, "RESTMapping"=>$restmap));
    $service->reply();
    
    ?>
  • You just wrote a SOAP+REST Data Service to expose your MSSQL Data as a Web Service. Now Put this script (say school_service.php) in to the Apache web directory and access it using a browser with the following url.
    http://localhost//school_service.php/subjects

    If you have done every thing right, you should see a nice xml showing your data. Note that here we used REST interface to test our service. You don’t need to do any thing special to expose it as SOAP. Its SOAP endpoint would be simply

    http://localhost//school_service.php

Get the WSDL Generation working with MSSQL
If you try to retrieve the WSDL for the above service using this URL

http://localhost//school_service.php?wsdl

You will get an error message saying that the meta data retrieval is not supported for this particular driver (MSSQL Driver). For the time being, in order to get rid of this warning you have to disable showing warnings in your PHP programs. You can get it done by editing the php.ini with this entry

error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING

But even with this fix, the schema types of the name and teacher entries will be shown as “xsd:anyType”. If you want to have a more specific type associated with them, Just change the $output_format variable to the following.

$output_format = array(
                    "resultElement" => "subjects",
                    "rowElement" => "subject",
		    "elements" => array(
			"name" => array("column" => "subjectName", "xsdType" => "xsd:string"),
			"teacher" => array("column" => "subjectTeacher", "xsdType" => "xsd:string")));

Here instead of giving a string to ‘teacher’ and ‘name’ entries, we give an array containing both column name and the the custom xsd type we want to appear in the WSDL.  Note that this fix is needed only for databases that doesn’t provide the meta data interface through the PHP PDO layer. For database like mysql wsdl generation works straight away.


© 2007 Dimuthu’s Blog | iKon Wordpress Theme by Windows Vista Administration | Powered by Wordpress