0

GWT 2.4. Static Google Map in Frame not working

Before this static Google map can be viewed using Frame object and what I need to do is to give the URL of the static map. Please refer to my previous post http://peyotest.blogspot.com/2011/03/gwt-google-map-static-and-dynamic.html
 
Unfortunately, when I upgraded the GWT to version 2.4, it didn't display the image.
It works fine with web page but not image.
So I searched in Google, but there is no one having problem like I did.

Since the static map is an image, so I decided to use image object in GWT and it can be loaded from URL. That's nice and easy solution for me.

Here is the new code :


package com.vcari.jscadav2.client;

import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.Image;

public class SiteMapStaticMapPanel extends SiteMapPanel {

    public SiteMapStaticMapPanel(){
        super();
    }    
    
    Frame frame = new Frame("http://google.com");
    final Image image = new Image();


    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        //setLayout(new FitLayout());
        setBorders(false);
        image.setWidth("640");
        image.setHeight("430");
        image.setVisible(true);
        add(image);
    }
    
    /**
     * Set map center to the defined latitude and longitude
     * @param latitude
     * @param longitude
     */
    public void setMapCenter(Double latitude, Double longitude, int zoomLevel) {                
       Integer width=this.getWidth();
       Integer height=this.getHeight();
       String url="http://maps.google.com/maps/api/staticmap?center={0},{1}&zoom={2}&size={3}x{4}&maptype=roadmap&sensor=false";
       url+="&markers=color:red7C%{0},{1}";
       //url=String.format(url, latitude,longitude,zoomLevel,width,height);
       url=url.replace("{0}", latitude.toString());
       url=url.replace("{1}", longitude.toString());
       url=url.replace("{2}", String.valueOf(zoomLevel));
       url=url.replace("{3}", width.toString());
       url=url.replace("{4}", height.toString());
       url=url.replace("{5}",  Application.areaName);      
       image.setUrl(url);
    }
}
0

Win 7 Can't Login to Windows Sharing

There is a PC with newly installed Windows 7.
The computer failed to be connected to my office's file server on Windows 2003.
The server keep fail to authenticate the computer and the computer keep asking for user name and password.

The solution:

  • Browse to "Local Policies" -> "Security Options". 
  • Now look for the entry "Network Security: LAN Manager authentication level" and open it. 
  • Click on the dropdown menu and select "Send LM & NTLM - use NTLMv2 session security if negotiated".  Apply the settings.
      Jonathan Ravzin (MCT - Microsoft Certified Trainer)
      URL: http://social.technet.microsoft.com/Forums/en-US/w7itpronetworking/thread/68ffbe2a-09a7-4e29-859c-ca1aaf75dcd1/

0

Ghost Explorer

Ghost Explorer can be downloaded for free from Symantec.

ftp://ftp.symantec.com/public/english_us_canada/products/ghost/utilities/GHO_Explorer.exe

Using this software, ghost file can be view and extracted.
I use ghost software to create image for my Embedded Linux on VortexSx86.
0

GXT Paging ListView

Simply bind the store to ListView and loader to PagingToolBar.
Here is the source code. You might need to refer to my previous posting on JSON reader and paging grid.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ppktechnology.assetmanagement.client;

import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.ListViewEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Format;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.ppktechnology.assetmanagement.client.model.ImagesModel;
import com.vcari.client.utils.DataUtils;

/**
 * 
 * @author peyo
 */
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
public class ImagesList extends LayoutContainer {

    ListStore store = ImagesModel.getInstance().getPagingStore();
    int limit = 20;

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        final ContentPanel panel = new ContentPanel();
        setLayout(new FitLayout());
        
        panel.setCollapsible(true);
        panel.setAnimCollapse(false);
        panel.setFrame(true);
        panel.setId("images-view");
        panel.setHeading("Simple ListView (0 items selected)");
        panel.setBodyBorder(false);
        panel.setLayout(new FitLayout());
                
        ListView<ModelData> view = new ListView<ModelData>() {
            @Override
            protected ModelData prepareData(ModelData model) {
                String s = model.get("imagedesc");
                model.set("imagedesc", Format.ellipse(s, 15));
                String thumbnail="images/" +  model.get("thumbnail");
                model.set("thumbnail", DataUtils.formatURL(thumbnail));
                String imagefile="images/" +  model.get("imagefile");
                model.set("imagefile", DataUtils.formatURL(imagefile));
                return model;
            }

        };

         view.addListener(Events.OnDoubleClick, new Listener<ListViewEvent<ModelData>>() {

                @Override
                public void handleEvent(ListViewEvent<ModelData> be) {
                    String imgurl = be.getModel().get("imagefile");
                    com.google.gwt.user.client.Window.open(imgurl, "_blank", "");
                }
            });
        
        final PagingToolBar pagingToolBar = new PagingToolBar(limit);
        pagingToolBar.bind((BasePagingLoader) store.getLoader());
        panel.setBottomComponent(pagingToolBar);
          
        view.setTemplate(getTemplate());
        view.setStore(store);
        view.setItemSelector("div.thumb-wrap");
        view.getSelectionModel().addListener(Events.SelectionChange, new Listener<SelectionChangedEvent<ModelData>>() {

            public void handleEvent(SelectionChangedEvent<ModelData> be) {
                panel.setHeading("Simple ListView (" + be.getSelection().size() + " items selected)");
            }

        });
        panel.add(view);
        add(panel);
        store.getLoader().load();
    }

    private native String getTemplate() /*-{
        return [ '<tpl for=".">', '<div class="thumb-wrap" id="{imageid}">',
                '<div class="thumb"><img src="{imagefile}" title="{imagedesc}"></div>',
                '<span class="x-editable">{imagedesc}</span></div>', '</tpl>',
                '<div class="x-clear"></div>' ].join("");

    }-*/;

}

0

Eclipse JAVA Formatter Line Wrapper Setting

Personally I don't like Eclipse line wrapper default setting since it's not properly wrap my code.
As the result, my code look ugly and harder to be read.

Before : (It will look worse if the code is longer)
adminTree.addListener(Events.OnDoubleClick,
                new Listener<TreePanelEvent<ModelData>>() {

                    @SuppressWarnings("unchecked")
                    @Override
                    public void handleEvent(TreePanelEvent<ModelData> be) {
                        ModelData p = be.getItem();
                        System.out.println(p.get("name"));
                        // MenuHandler.handleMenu(p);
                        Application.defaultViewNavigationTree.getTree()
                                .getSelectionModel().select(p, false);
                        Application.defaultViewNavigationTree.getTree()
                                .setExpanded(p, true);
                    }
                });

Finally I found the solution.

ANSWER:
Source: http://minimalbugs.com/questions/disable-line-wrapping-in-eclipse

You can’t disable line wrapping, but you can add more maximum characters to appear in a single line, by accessing :
  • Window – Preferences – Java – Code Style – Formatter – Edit
  • Insert New profile name because you can’t edit the default profile
  • Click Line wrapping tab in the maximum width, put the maximum character you wanted to be appeared in a single line
After :

adminTree.addListener(Events.OnDoubleClick, new Listener<TreePanelEvent<ModelData>>() {

            @SuppressWarnings("unchecked")
            @Override
            public void handleEvent(TreePanelEvent<ModelData> be) {
                ModelData p = be.getItem();
                System.out.println(p.get("name"));
                // MenuHandler.handleMenu(p);
                Application.defaultViewNavigationTree.getTree().getSelectionModel().select(p, false);
                Application.defaultViewNavigationTree.getTree().setExpanded(p, true);
            }
        });

0

OCI_INVALID_HANDLE (ext\pdo_oci\oci_driver.c:579)

In my project, I need to pull data from Oracle Server.
I need to enable oci8 and PDO_OCI extensions but there is a problem since PHP couldn't find OCI.dll.
I had downloaded the oracle Instant Client, extract and copy the oci.dll file to windows folder and successfully enable the extension. But when I tried to connect to the server, PHP gave me this error message:

OCI_INVALID_HANDLE (ext\pdo_oci\oci_driver.c:579)

So, I take a look on oracle Instant Client installation manual. Actually, it's very simple solution.

How to solve :
  1. Set the variable ORACLE_HOME in the Windows environment setting  to the path of the extracted Oracle Instant Client folder.
  2. Restart Apache
It works.
0

GWT - PHP on Apache 3rd Review

Yesterday, on the GWT training session at PPK, Ilhamy (one of my internship student) told me he found another way to communicate GWT with PHP. Actually it's very simple solution without need to configure Apache.

In the solution, the project must located in /htdocs folder and compiler argument must be configured.

The original argument:

-remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -startupUrl GWTPHP.html -logLevel INFO -codeServerPort 9997 -port 8888 -war C:\xampp\htdocs\GWTPHP\war com.vcari.jscadav2.Jscadav2_gwt

New configuration

-noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -startupUrl http://localhost/GwtPhp/war/GWTPHP.html -logLevel INFO -codeServerPort 9997 -war C:\xampp\htdocs\GWTPHP\war com.peyotest.gwtphp.GWTPHP


Steps :
  1. add -noserver 
  2. change startup url from GWTPHP.html to full url http://localhost/GwtPhp/war/GWTPHP.html
  3. remove server port  -codeServerPort 9997 
The full article about this can be found here:
http://cambiatablog.wordpress.com/2010/11/22/gwt-developing-with-hosted-mode-and-phpxampp/
0

GWT XMLRPC

On my previous work on XMLRPC, I had work with C# and PHP.
This morning I decide to try a library written for GWT.
The project can be found at:

http://code.google.com/p/xmlrpc-gwt/

Since there is no compiled .jar files, so I need create the .jar file myself.
Since I just used Eclipse for 2 weeks (before this using Netbeans + GWT4NB), it take me a long way just to create the .jar file. Actually to create .jar file is very simple step and require less than a minute.

Simply put the library inherits setting in the project.

<inherits name='com.fredhat.gwt.xmlrpc.XMLRPC'>

I just modify the sample given on the project's wiki and call the add function in my previous XMLRPC server sample.


XmlRpcClient client = new XmlRpcClient("http://127.0.0.1/xmlrpc/server.php");
String methodName = "add";
Object[] params = new Object[]{3, 4};
 
XmlRpcRequest<Integer> request = new XmlRpcRequest<Integer>(client, methodName, params, new AsyncCallback<Integer>() {
   public void onSuccess(Integer response) {
           // Handle integer response logic here
     Console.writeLine(response);
   }

   public void onFailure(Throwable response) {
           String failedMsg = response.getMessage();
           // Put other failed response handling logic here
           Console.writeLine(failedMsg);
   }
});
request.execute();


Done and it work just fine.
The .jar file can be found here.

GXT HighCharts

In my project, I had implement GXT chart. It works well on my system but my client wants to print the graph. Since the chart is in Flash, it can't be printed directly from the webpage. Actually I found an article to make it printable, but for it's not a good solution.

I found several project for JavaScript chart, but I to make it work with GWT & GXT is big problem for me.
Luckily, somebody has been working with Highchart (one of my candidate before) and give it a try.
I just follow the sample, and it works.

The project require jquery and highchart library.
After this I will found out whether it is work without jQuery since I can do AJAX query using GWT.

The project can found here: 
http://highcharts-gxt.sourceforge.net/wordpress/

Highchart
http://www.highcharts.com/

I'm going to replace the existing chart. Hopefully, there is no big issues arise.

0

GWT Google Map (Static and Dynamic)

In my project, my client want to use Google map.
I had put the Google Map V3 but due to poor internet connection, the retrieval time is very slow. They want to use static map.

I decide to create an option for them to choose whether to use dynamic or static Google map. To change between dynamic and static just simply change the instance.

The dynamic map, I use a library from http://code.google.com/p/gwt-google-maps-v3/

SitemapPanel.java
package com.vcari.jscadav2.client;

import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.google.gwt.user.client.Element;

public abstract class SiteMapPanel extends LayoutContainer{

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
    }
    
     public abstract void setMapCenter(Double latitude, Double longitude, int zoomLevel);
}



SiteMapStaticMapPanel.java (Static Map)
This solution is working for GWT 2.4. Please refer to my new post below for solution. http://peyotest.blogspot.com/2011/09/gwt-24-static-google-map-in-frame-not.html

package com.vcari.jscadav2.client;

import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Frame;

public class SiteMapStaticMapPanel extends SiteMapPanel {

    public SiteMapStaticMapPanel(){
        super();
    }    
    
    Frame frame = new Frame();

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        setLayout(new FitLayout());
        setBorders(false);
        add(frame);
    }
    
    /**
     * Set map center to the defined latitude and longitude
     * @param latitude
     * @param longitude
     */
    public void setMapCenter(Double latitude, Double longitude, int zoomLevel) {                
       Integer width=this.getWidth();
       Integer height=this.getHeight();
       String url="http://maps.google.com/maps/api/staticmap?center={0},{1}&zoom={2}&size={3}x{4}&maptype=roadmap&sensor=false";
       url+="&markers=color:red7C%{0},{1}";
       url=String.format(url, latitude,longitude,zoomLevel,width,height);
       url=url.replace("{0}", latitude.toString());
       url=url.replace("{1}", longitude.toString());
       url=url.replace("{2}", String.valueOf(zoomLevel));
       url=url.replace("{3}", width.toString());
       url=url.replace("{4}", height.toString());
       url=url.replace("{5}",  Application.areaName);
      
       frame.setUrl(url);
    }
}



Dynamics Google Map Version 3

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vcari.jscadav2.client;

import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.maps.client.MapOptions;
import com.google.gwt.maps.client.MapTypeId;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.base.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.Element;

/**
 *
 * @author peyo
 */
public class SiteMapV3Panel extends SiteMapPanel {

    private Marker marker;
    private MapWidget mapWidget;

    public SiteMapV3Panel() {
        setLayout(new FitLayout());
                      
        final MapOptions options = new MapOptions();
        // Zoom level. Required
        options.setZoom(8);
        // Open a map centered on Cawker City, KS USA. Required
        options.setCenter(new LatLng(5.519216, 116.822204));
        // Map type. Required.
        options.setMapTypeId(new MapTypeId().getRoadmap());

        marker=new Marker();
        
        // Enable maps drag feature. Disabled by default.
        options.setDraggable(true);
        // Enable and add default navigation control. Disabled by default.
        options.setNavigationControl(true);
        // Enable and add map type control. Disabled by default.
        options.setMapTypeControl(true);
        mapWidget = new MapWidget(options);
        mapWidget.setSize("800px", "600px");
        add(mapWidget);
    }
    
   
    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
    }

    /**
     * Set map center to the defined latitude and longitude
     * @param latitude
     * @param longitude
     */
    public void setMapCenter(Double latitude, Double longitude, int zoomLevel) {                
        mapWidget.getMap().setZoom(zoomLevel);
        mapWidget.getMap().panTo(new LatLng(latitude, longitude));
        marker.setPosition(new LatLng(latitude, longitude));
        marker.setMap(mapWidget.getMap());
        marker.setTitle(Application.areaName);
    }
}

2

PHP Fatal error: date(): Timezone database is corrupt - this should *never* happen!

When I tried to execute a script that using date function on my Vortex, i got this error message.

"PHP Fatal error: date(): Timezone database is corrupt - this should *never* happen!".

Actually, this happened a long time ago, but only today I gave my efficient time tried to solve this problem. Luckily,I found the solution with just a few minutes.

Solution :

Make sure that web server(I'm using lighttpd on vortex) has enough access to read
/etc/localtime
/usr/share/zoneinfo

if localtime is not exist, you can copy the file from any Linux system.
1

GXT Remote Paging With GWT RPC

This code example shows how to make GXT grid with remote paging to work with GWT RPC.That's means you can use POST to send the request. I'm not sure whether it can be done before.

To do that,we need just need to use RpcProxy and override the load method.

Anyway, I put the sample code below.
I take it from GXT demo code.

final ExampleServiceAsync service = (ExampleServiceAsync) Registry.get(Examples.SERVICE);
RpcProxy<PagingLoadResult<Post>> proxy = new RpcProxy<PagingLoadResult<Post>>() {

    @Override
    public void load(Object loadConfig, AsyncCallback<PagingLoadResult<Post>> callback) {
        service.getPosts((PagingLoadConfig) loadConfig, callback);
    }
};

// loader  
final PagingLoader<PagingLoadResult<ModelData>> loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy);
loader.setRemoteSort(true);
ListStore<Post> store = new ListStore<Post>(loader);

GXT ModelData Cloning

It's easy to clone a GXT ModelData.

 public static void cloneModelData(ModelData source, ModelData dest) {
        Iterator<String> iterator = source.getPropertyNames().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            dest.set(key, source.get(key));
        }
    }
0

PHP XML-RPC Client Simplified

In my previous for XML-RPC client helper, I suggested to create a client instance to make your methods exposed and developer friendly. But may be some of us are too lazy write all the wrapper code. There is solution for that.

In this case you still need to create client instance which extends XMLRPCClientHelper, but this time you don't need to write all the wrapper code. Just simply add __call overload methods.

It's easy but you need to remember the service API.

Here is the code:

<?php
class TestXMLRPCClientSimplified extends XMLRPCClientHelper {
    public function __call($name, $arguments) {
        return $this->sendRequest("$name", $arguments);
    }    
}
?>

0

PHP XML-RPC Client Helper

I wrote a helper for XMLRPC client.
I also added the automatic base64 type setting for bytes data.
Just need to create the client instance and supply the service URL, then you can start to call the service.

To make you client methods is expose and developer friendly, you can create your own client class which extends XMLRPCClientHelper.

<?php
class TestXMLRPCClient extends XMLRPCClientHelper {

    /**
     * Add two number
     * @param <int> $A
     * @param <int> $B
     * @return <int>
     */
    public function add($A, $B) {
        $params = array($A, $B);
        return $this->sendRequest("add", $params);
    }
}
?>


Here is the simple example :

$url = "http://192.168.56.1:5678/service.rem";
$client = new TestXMLRPCClient();
$client->setURL($url);
$result=$client->add(1,4);  //test add
print "Add Result: $result <br>\n";

It also support the exception when there is any error occurs it will throw the exception.So you just need to use try and catch to handle that.

XMLRPCClientHelper.php. This file also included in my training materials on my previous post.

<?php

/**
 * This helper class help to create a simple XML-RPC client
 * @author Mohamad Fairol Zamzuri B Che Sayut <mfz_peyo@yahoo.com>
 */
class XMLRPCClientHelper {

    private $url;

    /**
     * Get URL
     */
    public function getURL() {
        return $this->url;
    }

    /**
     * Set URL
     * @param <string> $url URL
     */
    public function setURL($url) {
        $this->url = $url;
    }

    /**
     * Send RPC request
     * @param <string> $methodname method name
     * @param <array> $parameters parameters
     */
    public function sendRequest($methodname, $parameters) {
        for ($i = 0; $i < count($parameters); $i++) {
            if (mb_detect_encoding($parameters[$i]) === false) {
                xmlrpc_set_type(&$parameters[$i], "base64");
            }
        }
        $request = xmlrpc_encode_request($methodname, $parameters);
        $context = stream_context_create(array('http' => array(
                        'method' => "POST",
                        'header' => "Content-Type: text/xml",
                        'content' => $request
                        )));
        $file = file_get_contents($this->url, false, $context);
        $response = xmlrpc_decode($file);
        if (is_array($response) && xmlrpc_is_fault($response)) {
            throw new Exception($response['faultString'], $response['faultCode']);
        }
        return $response;
    }

}

?>

0

PHP XML-RPC Server Helper

I wrote a XMLRPCServerHelper to help me to create XML-RPC service in PHP.
It's easy to use and you just need to set the classname of service and all the methods will be extracted automatically using ReflectionClass.

The example of the server :

<?php
error_reporting(E_ERROR | E_PARSE);
require_once("autoload.php");

$server = new XMLRPCServerHelper();
$server->setClassName("TestXMLRPCService");
$answer = $server->handle();
header('Content-Type: text/xml');
print($answer);
?>


The service can be access from your normal webserver url.
To generate php client class, just simply add ?phpwrapper to the url. E.g :

 http://localhost/xmlrpc/server.php?phpwrapper


XMLRPCServerHelper.php . This file also incuded in my training materials on my previous post.

<?php

/**
 * This helper class help to create XML-RPC server
 */
class XMLRPCServerHelper {

    /**
     * Server handler holder
     * @var <Object> Server handler holder
     */
    private $serverHandler;
    /**
     * Class name holder
     * @var <string> Class name holder
     */
    private $classname;
    /**
     * External function list holder
     * @var <array>  External function list holder
     */
    private $externalFunctions;

    /**
     * Contructor
     */
    public function __construct() {
        $this->serverHandler = xmlrpc_server_create();
        $this->externalFunctions = array();
    }

    /**
     * Set object class.
     * All class methods will be extracted and registerd automatically
     * @param <Object> $class
     */
    public function setClassName($classname) {
        $this->classname = $classname;
        $reflection = new ReflectionClass($classname);
        $methods = $reflection->getMethods();
        $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        for ($i = 0; $i < count($methods); $i++) {
            $reflectmethod = $methods[$i];
            $methodname = $reflectmethod->name;
            $reflectparams = $reflectmethod->getParameters();
            if (count($reflectparams) > 0) {
                for ($j = 0; $j < count($reflectparams); $j++) {
                    $methodparams[] = $reflectparams[$j]->name;
                }
            } else {
                $methodparams = array();
            }
            $this->registerMethod($methodname, array(&$classname, $methodname), $methodparams);
        }
    }

    /**
     * Generate client wrapper
     */
    private function generatePHPClientWrapper() {
        $classfunctions = "";
        $reflection = new ReflectionClass($this->classname);
        $methods = $reflection->getMethods();
        $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        for ($i = 0; $i < count($methods); $i++) {
            $reflectmethod = $methods[$i];
            $methodname = $reflectmethod->name;
            $reflectparams = $reflectmethod->getParameters();
            $funcParams = "";
            $funcContent = "";
            if (count($reflectparams) > 0) {
                for ($j = 0; $j < count($reflectparams); $j++) {
                    //$funcContent.= "\$params[] = \$" . $reflectparams[$j]->name . ";\n";
                    if ($funcParams != "") {
                        $funcParams.=",";
                    }
                    $funcParams.='$' . $reflectparams[$j]->name;
                }
                $funcContent = "\$params = array($funcParams);\n";
            } else {
                $funcContent = "\$params = array();\n";
            }

            $classfunctions.="public function $methodname($funcParams) {\n";
            $classfunctions.=$funcContent;
            $classfunctions.="return \$this->sendRequest(\"$methodname\", \$params);\n";
            $classfunctions.="}\n\n";
        }

        $wrapper = "<pre>class " . $this->classname . "XMLRPCClient extends XMLRPCClientHelper {\n";
        $wrapper .= "$classfunctions";
        $wrapper .= "}\n</pre>";
        return $wrapper;
    }

    /**
     * Register method
     * @param <string> $externalName class name
     * @param <Object> $function class pointer
     * @param <array> $parameterNames parameters name
     */
    public function registerMethod($externalName, $function, $parameterNames) {
        if ($function == null) {
            $function = $externalName;
        }
        xmlrpc_server_register_method($this->serverHandler, $externalName, array(&$this, 'callMethod'));
        $this->externalFunctions[$externalName] = array('function' => $function, 'parameterNames' => $parameterNames);
    }

    /**
     * Invoke class method
     * @param <string> $functionName method name
     * @param <array> $parametersFromRequest parameters
     * @return <variant> function call result
     */
    public function callMethod($functionName, $parametersFromRequest) {
        if ($functionName == "generatePHPClientWrapper") {
            return $this->generatePHPClientWrapper();
        }

        $function = $this->externalFunctions[$functionName]['function'];
        $parameterNames = $this->externalFunctions[$functionName]['parameterNames'];
        return call_user_func_array($function, $parametersFromRequest);
    }

    /**
     * Handle server call
     * @return <variant>  function call result
     */
    public function handle() {
        $bWrapper = false;
        foreach ($_GET as $key => $value) {
            if ($key == "phpwrapper") {
                $bWrapper = true;
                continue;
            }
        }

        if ($bWrapper) {
            print $this->generatePHPClientWrapper();
            exit();
        }
        return xmlrpc_server_call_method($this->serverHandler, file_get_contents('php://input'), null);
    }

}

?>

XMLRPC Training (C# and PHP)

Today, I'm going to conduct a simple training on XML-RPC at my previous company.
You can access to the training materials on my googleDocs.


Presentation Slide
PHP source code
C# source code
0

PHP Simple Auto Load

Just wanna share my PHP autoload function.
In my application, I have several types of classes and may located in different folder such as :
  • Helper
  • Model
  • Component
  • Web Service
  • etc
The easiest way to use the classes is to create an auto load function so the classes file will be included automatically.

Hope this could be useful to you too.
<?php
/**
 * Auto function
 * @param <string> $classname class name
 * @return <void> void
 */
function __autoload($classname) {
    global $global_helper_path;
    global $global_model_path;
    global $global_component_path;
    global $global_wsobject_path;

    //load helper
    $pos = strrpos($classname, "Helper");
    if ($pos === false) { // note: three equal signs
    } else {
        //print $classname;
        $filepath = "$global_helper_path/$classname.php";
        require_once "$filepath";
        return;
    }

    // load component
    $pos = strrpos($classname, "com_");
    if ($pos === false) { // note: three equal signs
    } elseif ($pos == 0) {
        $filepath = "$global_component_path/$classname/$classname.php";
        require_once "$filepath";
        return;
    }

    // load database driver
    $pos = strrpos($classname, "DB");
    if ($pos === false) { // note: three equal signs
    } elseif ($pos == 0) {
        $filepath = "$global_helper_path/database/$classname.php";
        require_once "$filepath";
        return;
    }

    // load model
    $pos = strrpos($classname, "Model");
    if ($pos === false) { // note: three equal signs
    } else {
        $filepath = "$global_model_path/$classname.php";
        require_once "$filepath";
        return;
    }

    // load webservice class
    $pos = strrpos($classname, "WS");
    if ($pos === false) { // note: three equal signs
    } elseif ($pos == 0) {
        $filepath = "$global_wsobject_path/$classname.php";
        require_once "$filepath";
        return;
    }
}

?>

0

PHP Web Service Library

I gave a look on my PHP web service class. It's quite hard to extends and create a new web service application. I search on Google and found several open source projects and gave them a test.

I found "php-webservice-class" is the best since the implementation is simple,easy and fully commented. It also use ReflectionClass, makes the code simpler without need to create phpDoc parser to get your parameter settings.

The project url:
http://code.google.com/p/php-webservice-class/


Update on 28th Feb 2011

The wsdl output is not standard. :(
You can't call the web service from other language.
I'm considering to use David Kingma library (my old library also based on his work) for replacement.
 
Copyright © peyotest