Skip to content

Commit

Permalink
3.0 see README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecc committed Oct 26, 2020
1 parent de45d59 commit 8eff48c
Show file tree
Hide file tree
Showing 32 changed files with 2,087 additions and 1,234 deletions.
290 changes: 158 additions & 132 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,210 +28,236 @@ And why to use this library?

## Getting started

### 1. Creating an instance
### 1.Creating a Definition

What is a definition class. It is a class that defined the name,namespace, functions and complex-types defined by the web service.

In this example, we are defining a simple function : function hello($param);

```php
use eftec\cloudking\CloudKing;
include "../vendor/autoload.php";

$FILE = 'http://'.$_SERVER["SERVER_NAME"].$_SERVER["SCRIPT_NAME"];
$NAMESPACE="examplenamespace";
$NAME_WS='Example2WS';
$ns=new CloudKing($FILE, $NAMESPACE, $NAME_WS);

$ns->soap12=false;
$ns->verbose=2;
$ns->allowed_format["POST"]=true;
$ns->variable_type="array";
// $service=new Example2WSService(); // we will work with this one later
// $ns->serviceInstance=$service; // we will work with this one later
$ns->description="Example Server";
class ExampleDefinition {
public static $service;

/**
* You must create this file manually.
*
* @param bool $gui if true then it shows the web gui
*/
public static function init($gui = true) {
$FILE = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'];
$NAMESPACE
= 'http://www.examplenamespace.cl/'; // the namespace of the web service. It could be anything and not specifically an existing url
$NAME_WS = 'Example2WS'; // the name of the service

self::$service = new CloudKing($FILE, $NAMESPACE, $NAME_WS);
self::$service->allowed_input['gui'] = $gui; // set to false to disable the web gui.
self::$service->serviceInstance = null;
self::$service->verbose = 2; // for debug purpose
self::$service->description = 'Example server SoapKing';

self::$service->addfunction('hello',
[
self::$service->param('param', 'string', true, false),
],
[
self::$service->param('return', 'string')
],
'Example of function'
);
}

public static function run() {
$r = self::$service->run();
echo $r;
}
}
```

You should create an instance indicating the url, namespace, and the name of the webservice.
We will explain more about it later.

You could also indicates other factors and it depends on every case. In case of doubt, you could use the cases indicates in this example.
### 2. Running the first time.

This variable is important
Let's call the definition as follow

```php
$ns->soap12=false;
<?php

include 'ExampleDefinition.php';

ExampleDefinition::init();
ExampleDefinition::run();
```

JAVA usually doesn't work well with SOAP 1.2 (2.0) so we could disable it. By default, this library supports 1.1 and 1.2 (2.0) at the same time.
Right now, this web service doesn't run because we are not associate the definition with a real function. The functions are defined in a class SERVICE CLASS.

![docs/helloservice.jpg](docs/helloservice.jpg)


If you want to act as a server, then you could specify the instance

### 2. Assigning the Schema
Here you have the definition of the services and the information about it. If you want to disable it, then you could disable the $GUI, or lower the VERBOSE to 0.

This library starts creating the schema, you must create the schema manually and everything else is created based on it.
### 3. Calling the Service

To start creating the schema, you must start adding a new function. You could specify the name of the function, the input, output and optionally, a description.
Right now ,the service is not complete but you can test it. If you click in WSDL description, it will show a huge xml file. You could download it or copy the address (ended with ?wsdl)

Example of a function that input a primitive and output a primitive:
In this example, we will use the program SOAPUI (there is a free and paid version)

```
$ns->addfunction("ping"
, [CloudKing::argPrim('ping_param', 's:string')]
, [CloudKing::argPrim('return', 's:string')]
, "Descripcion :Prueba de conexion");
```
Open the SOAPUI (or the program that you want to use), and paste the url of the wsdl (obtained in the previous step) and runs it.

In this example, the input is an argument called **ping_param** (string) and the result (called return) is a string.
![docs/hellosoap.jpg](docs/hellosoap.jpg)

* s:**name** = means a primitive value
* tns:**Complex** = indicates a complex structure.
And it will show all the methods defined. In our case, there is a single function called "hello". Then, you can run it.

Example: getting a complex object
![docs/hellosoap2.jpg](docs/hellosoap2.jpg)

```php
$ns->addfunction("GetProducto"
, [CloudKing::argPrim('idProducto', 's:integer')]
, [CloudKing::argComplex('return', 'tns:Producto')]
, "Descripcion :obtiene los datos de una objeto");
```
If you run it, it will fail. Why? It is because we are yet to define the service class.

In this case, it uses an complex called tns:**Producto** in the argument return. The name "return" could not be required.
### 4. Service class

You must also specific the complex structure as follow:
In our website, there is a link called SOURCE GENERATION. Click on it and it will show the next screen.

You can generate a c# code, and both php code (from server and client). We need to generate the server source. If you click on the View PHP Server Source, you can look at the code. However, you can also generate it directly. However, for that, you will need to set the folder

![docs/helloservice2.jpg](docs/helloservice2.jpg)

```php
$ns->addtype("Producto", [ // because we use "tns:Producto"
CloudKing::argPrim('idProduct', 's:integer'),
CloudKing::argPrim('nombre', 's:string'),
CloudKing::argPrim('precio', 's:integer')
]);
```

You could also create more complex types as follow

Let's modify the file of the step 2

```php
$ns->addtype("Cart", [
CloudKing::argList('products', 'tns:Producto', 0, 'unbounded'), // a list of products
CloudKing::argPrim('total', 's:integer'), // a primitive
CloudKing::argComplex('category', 'tns:category') // a complex not created for this example
]);
<?php

include 'ExampleDefinition.php';

ExampleDefinition::init();
ExampleDefinition::$service->folderServer=__DIR__; // or you could select any folder.
ExampleDefinition::run();

```

Example of function (input value is a complex):
And if we refresh the website, it will show

![docs/helloservice3.jpg](docs/helloservice3.jpg)

So, you could generate 1 class and 1 interface automatically. Click on it, and it will generate both files

![docs/helloservice4.jpg](docs/helloservice4.jpg)

It will generate the folder service and 2 files

📁 service

___ 📃 ExampleHelloService.php (our service class)

___ 📃 IExampleHelloService.php (the interface class)

### 5. Editing the Service Class.

This class is half-generated. We could edit our operations inside this class, so let's change our code.

```php
$ns->addfunction("InsertProducto"
, array(CloudKing::argComplex('Producto', 'tns:Producto'))
,array(CloudKing::argPrim('return', 's:boolean'))
, "Descripcion :obtiene los datos de una objeto"
);
class ExampleHelloService implements IExampleHelloService {

/**
* @inheritDoc
*/
public function hello(&$param) {
return $param." world!"; // <--- edit this.
}
} // end class
```

### 6. Editing our service


Example: returning a list of objects
Let's modify our service defined in the step 2 again and now, we must indicate our service class (created in the step 4)
```php
$ns->addfunction("GetProductos"
, []
, [CloudKing::argList('return', 'tns:Producto', 0, 'unbounded')]
, "Descripcion :Obtiene una lista de productos");
ExampleDefinition::init();
ExampleDefinition::$service->folderServer=__DIR__; // or you could select any folder.run_initial.php
ExampleDefinition::$service->serviceInstance=new ExampleHelloService();
ExampleDefinition::run();
```
In this case, the function doesn't requires an input value and it returns a list of objects.
And let's run it again using SOAPUI

### 3. Running
![docs/hellosoap3.jpg](docs/hellosoap3.jpg)

Finally, with the instance and the schema, you could run the interface
And now, we have the service up and running.

```
$ns->run();
```
You could later disable the GUI

And open the website to show the interface.
# Definition

In the interface, you could see the WSDL, the methods and the generation of the code.
## Parameters

### 4. Generating the service class
Parameters are used to indicate the arguments of a function, the return value of a function or the fields of a complex structure.

![](docs/generation.jpg)
#### Defining a single parameter.

You could generate the client or server (our service class). Let's generate the PHP Server Source.
> param(name of the parameter, type , reference, required , description)

This generated class lacks of the implementation but everything else is ready.
* name of the parameter : it is the name of the parameter, for example "idCompany", "money" and such
* type: the type of the parameter. It could be a **primitive** value (string,integer,etc.) or it could be defined by a structure/class (called **complex**). If we want to use a **complex** type, we need to define it after we want to use it.
* reference: (optional)If true then the value is also returned. If false, then the value is not returned.
* required: (optional)If true then the value is required.
* description: (optional) An optional description of the parameter.

```php
class Example2WSService {
function ping($ping_param) {
try {
// todo: missing implementation
/*
$_ping_param='';
*/
// End Input Values
$_pingResult='';
return $_pingResult;
} catch (Exception $_exception) {
return(array("soap:Fault"=>'Caught exception: '. $_exception->getMessage()));
}
}
// ....
}
self::$service->param('counter', 'integer') // a parameter called "counter" of the type integer
self::$service->param('name', 'string', true, false, "description") // a string parameter called "name"
self::$service->param('prod', 'Product', true, false, "description") // a parameter called "prod" of the complex type Product (it must be defined)
```

We should create a new PHP file, in our example **Example2WSService.php**
#### Defining an array of parameters

In the step 1, we create the instance of the CloudKing, with the service class up and running, we are ready to finish the implementation of the server.
It is also possible to define an array (list) of parameters.

Uncomment the next line of code (from the step 1)
> paramList(name of the parameter, type , reference, required , description )
```php
include "Example2WSService.php";
$service=new Example2WSService();
$ns->serviceInstance=$service;
self::$service->paramList('names', 'string') // defining an array of string called "names"
self::$service->paramList('productList', 'Product',false,false,'List of products') // defining an array of complex type Product called "productList"
```

And now, our web service is up and running and we could test into SOAPUI (or any other tools compatible with SOAP)
> Note: This function defines automatically a complex type called ArrayOf\<name of the parameter\> . If the complex type exists (complex with the same name), then it uses it instead of create a new one.
![](docs/soap1.jpg)
## Complex Types

> Remember that in the main website, you could obtain the description WSDL. It is required for some programs (see image). You could also obtain by calling the webserver with the argument ?wsdl Example: myws.php?wsdl
It is also possible to define a complex type. A complex type is used when we need to define a model or structure.

### 5. Creating the client
> addType( name of the type , [ parameters ] , description)
We could create the client in the same way (with the UI) and we could change the webport and the default namespace.
* name of the type: it is the name of the time. The case of the name matters.
* parameters: We could define one of more parameters for the type. We could even define list of parameters or even parameters that use complex types.
* description: (optional) The description of the type

```php
<?
class Example2WSClient {
var $url='http://localhost/currentproject/oraclecloud/ws/ws.php';
var $tempuri='examplenamespace';

// Descripcion :Prueba de conexion
// ping_param =
function ping($ping_param) {
$_obj=new CloudKingClient();
$_obj->tempuri=$this->tempuri;
$_obj->soap='1.1'
$_param='';
$_param.=$_obj->array2xml($ping_param,'ts:ping_param',false,false);
$resultado=$_obj->loadurl($this->url,$_param,'ping');
return @$resultado['pingResult'];
}
// ...
}
self::$service->addtype('Product',
[
self::$service->param('idProduct', 'int',false,true, 'comentary'),
self::$service->param('name', 'string'),
self::$service->param('price', 'int')
]);
```

And you could call this class like any other service class
Example: Defining a complex type of an invoice with the invoice detail.

```php
$x=new Example2WSClient();
var_dump($x->ping(20));
self::$service->addtype('InvoiceDetail', [
self::$service->param('idInvoiceDetail', 'int'),
self::$service->param('idInvoice', 'int'),
self::$service->param('detail', 'string')
]);
self::$service->addtype('Invoice', [
self::$service->param('idInvoice', 'int'),
self::$service->paramList('details','InvoiceDetail'),
]);
```

## TODO

There is some broken features but it works in basic examples.

## Versions
* 3.0
* Rebuild the engine. Now SOAP and JSON works correctly.
* 2.6
* Fixed the client when it returns an array of objects.
* 2.5
Expand Down
10 changes: 9 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "library",
"description": "A SOAP webserver for PHP",
"license": "MIT",
"version": "2.6",
"version": "3.0",
"authors": [
{
"name": "Jorge Castro",
Expand All @@ -16,9 +16,17 @@
"ext-xml": "*",
"ext-curl": "*"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
},
"autoload": {
"psr-4": {
"eftec\\cloudking\\": "lib/"
}
},
"autoload-dev": {
"psr-4": {
"eftec\\tests\\": "tests/"
}
}
}
Binary file added docs/helloservice.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/helloservice2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/helloservice3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/helloservice4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/hellosoap.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/hellosoap2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/hellosoap3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 8eff48c

Please sign in to comment.