Saoscope logo

Introduction

Description

Saoscope is born from a very simple idea : when you want to write a simple web interface to publish dynamic data, you spend lot of your precious time on writing html forms, validating data inputed by the user, querying information from database, formating output, ... and for each page you write, the same kind of code has to be rewritten.

Saoscope aims at simplifying this situation. Its goal is to allow you to design such portal without having to deal with the boring part. In short, its goals are :

  • Minimum technical skills: creation and extention of portal just by pushing xml files
  • Quick: no time to loose on boring development

Saoscope is a PHP API that deal with low level component of simple data querying and presentation. More precisely, its features are :

  • Automatically generate form to customize query
  • Validate data inputed by user
  • Automatically fetch data from databases according to data inputed by user
  • Lay out the queried data on web page

Saoscope is written entierly in PHP in a "framework shape" spirit, meaning that it is made to be included in other PHP page with a very few lines of code. The API is used in a simple way : you just have to push a XML file describing what the API should do, and you call a single method of the API ginving this XML file.

Requirement

What you will nee to run Saoscope is :
  • A web server (typically apache, but other may also works)
  • PHP support for the web server, at least 5.0 (Saoscope make intensive use of Reflexion that is not available in PHP 4.x versions).
  • Some PHP external libs, depending on which plugins you wants to use
We try to do our best to make the core of Saoscope running with the minimum of not-builtin libraries to allow you to use it in a "plug and play" mode. But depending on the plugin you wants to use, you may need to install dependencies. Read the doc of the plugins about their requirements.

Getting Saoscope

Saoscope is hosted on Sourceforge. Download can be achieve from download page for the project (http://sourceforge.net/project/platformdownload.php?group_id=233540).

Installation

Installation is pretty straightforward : just untar the archive somewhere accessible on your web server.
The standard installation does not require external dependencies, but if you which to install plugins, you may look at the plugin documentation to look for required dependencies.

Quick start

The database

Let's take a simple example. We are a small store that sells some goods. Our data is stored in the superstore mysql database hosted on db.superstore.com, login jdoe, password azerty. There are three tables in this database :
  • PRODUCTS : contains the listing of all sold products, in two columns ID and LABEL
  • ORDERS : contains the orders made by customers, in four columns ID, CUSTOMER, DATE_ORDER, DATE_DELIVERY. To simplify, CUSTOMER will only contain the name of the customer
  • ORDER_DETAIL : contains the detail of an order, in three columns ORDER_ID, PRODUCT_ID, QUANTITY.

Here is the shema of this database:

The web site

We already have a template of web site, index.html :

<html>
<head/>
<body>
  <div align="center">!! Superstore !!</div><hr>
  <div id="content">
    What do you want to do ?
    <ul>
      <li><a href="pendings.php">See pending orders</a></li>
	  <li><a href="details.php">See the detail of an order</a></li>
    </ul>
  </div>
  <hr><div align="center">-~-~-~- a small footer -~-~-~-</div>
</body>
</html>

We now need to write the orders.php and details.php pages. As you can expect, the orders.php will simply display the list of record in table ORDERS where DATE_DELIVERY is null. The page details.php will be a bit more complexe : we need first to get the id of the order we wants to display, check if the id is a correct number, fetch data from tables ORDER_DETAIL and display the result.

Here come the power of Saoscope : we won't write any line of code to manage those tasks, but only describe what we want in the proper xml file and pass it to Saoscope.

Querying simple data - the pending orders page

This page is the simplest : we fetch data from database and display result.

Getting the data

Getting the data is pretty simple. We connect to the database with the following information:
  • engine : mysql
  • host : db.superstore.com
  • database : superstore
  • user : jdoe
  • password : azerty

And then run the following query :

SELECT id AS "Order number", customer AS "Customer name", date_order AS "Date of order"
FROM orders WHERE date_delivery IS NULL

Note that we use alias for column name to get pretty names for the user.

Displaying the result

Displaying the result is pretty simple, we just want to get a table with the name of the fields as header, and one pending order for each row.

Putting all together in Saoscope

We will now put all this information in a Saoscope XML file that we will call orders.saoscope.xml:

<page>
  <description>Display all the pending orders</description>
  <data type="sqlquery">
    <connection type="mysql">
      <param name="host">localhost</param>
      <param name="database">superstore</param>
      <param name="user">jdoe</param>
      <param name="password">azerty</param>
    </connection>
    <query><![CDATA[
      SELECT id AS "Order number", customer AS "Customer name", date_order AS "Date of order"
      FROM orders WHERE date_delivery IS NULL
    ]]></query>
  </data>
</page>
orders.saoscope.xml

Not that there is no mention of the display we want to use : a html table is the default.

We now just have to create the orders.php page by calling Saoscope API at the middle of our template page:

<html>
<head/>
<body>
  <div align="center">!! Superstore !!</div><hr>
  <div id="content">
    <?php
      $saoscope_dir="path/to/saoscope/dir"; // Put here the path to your Saoscope installation
      include_once($saoscope_dir.'/Saoscope.php');
      Saoscope::display_page("orders.saoscope.xml",null);
    ?>
  </div>
  <hr><div align="center">-~-~-~- a small footer -~-~-~-</div>
</body></html>
orders.php

That's all !

Note the second null parameter in Saoscope::display_page method. It allow to enter additionnal configuration that we don't need here. It will be explained further.

TODO : screenshoot

All ? A little ugly, isn't it ? Let's put some happiness in the page by coloring the table !

Look at the source code of the generated page : the table Saoscope write is included in a <div class="saoscope_data"> tag. You are free to add the style you want thanks to HTML styles. For example, put the following code into the header, and you will get red table headers:

<style type="text/css">
    div.saoscope_data th { background-color: #FFAAAA; }
</style>

TODO : screenshoot

Adding user input : the details.php page

Querying the data

Now let's write the details.php page which will display the detail of an order given its number. We will still use the html table output, so no need to bother with that. The parameters to get the data from database are the same that for the orders.php page. But what with the sql query ? We need to use a WHERE clause that will filter on the number the user has inputed.

Here come the notion of variables. In the query, we can refer to the variables by putting them between ${}.

So if we have the variable order_identifiant, our query will be :

    SELECT order_detail.product_id AS Reference,
           products.label AS Description,
           order_detail.quantity AS Quantity
	FROM order_detail, products
	WHERE order_detail.product_id = products.id
	  AND order_detail.order_id = ${order_identifiant}
query with variable

Defining the variable

What about our variable order_identifiant ? It should be a number, so we will ask Saoscope to present a pretty input form that allow the user to enter its number. We will also let him know that this number should respect maximum and minimum values, for example because our order identifiant are normalize to be between 10000 and 99999.

So our variable will be definied by :

  • name: order_identifiant
  • description: the identifiant of the order for which you want to see the detail
  • type: number
  • maximum value: 99999
  • minimum value: 10000

That's all. Saoscope will base on the type to display the proper form, and on the maximum and minimum values to validate the data.

The Saoscope XML file

As for the orders.php page, we will create the Saoscope XML file, and then fetch it to Saoscope in the detail.php page.

<page>
  <description>Display the detail of an order</description>
  <variable name='order_identifiant'>
    <description>the identifiant of the order for which you want to see the detail</description>
    <format type='integer'>
      <param name="min">10000</param>
      <param name="max">99999</param>
    </format>
  </variable>
  <data type="sqlquery">
    <connection type="mysql">
      <param name="host">db.superstore.com</param>
      <param name="database">superstore</param>
      <param name="user">jdoe</param>
      <param name="password">azerty</param>
    </connection>
    <query><![CDATA[
      SELECT order_detail.product_id AS Reference,
             products.label AS Description,
             order_detail.quantity As Quantity
      FROM order_detail, products
      WHERE order_detail.product_id = products.id
        AND order_detail.order_id = ${order_identifiant}
    ]]></query>
  </data>
</page>
details.saoscope.xml

Note here the variable element that describe our object_identifiant variable, and the ${object_identifiant} in the query.

And the details.php file is exactly the same as the orders.php file, except the name of the XML file to load :

<html>
<head/>
<body>
  <div align="center">!! Superstore !!</div><hr>
  <div id="content">
    <?php
      $saoscope_dir="path/to/saoscope/dir"; // Put here the path to your Saoscope installation
      include_once($saoscope_dir.'/Saoscope.php');
      Saoscope::display_page("details.saoscope.xml",null);
    ?>
  </div>
  <hr><div align="center">-~-~-~- a small footer -~-~-~-</div>
</body></html>
details.php

TODO: screenshoot

As for orders.php, you can customize the page thanks to HTML styles. The form is encapsulated into a <div class="saoscope_form"> tag.

Try to enter erronous data. Saoscope will gently unvalidate your data and ask you for a new one.

Centralizing data : using named objects

OK, we have created two page that use the same database. Fine, but the connection parameters are duplicated in the two files... not so fine. If the password change for example, we will have to report it on every file. And moreover, it force us to type two much characters, we lazy programmers...

Here the configuration feature comes in hand. Do you remember the null second parameter of Saoscope::display_page ? We will use it to pass a configuration file that contain what we don't want to type twice.

We will create a so called named object for the connection object. In details.saoscope.xml and in orders.saoscope.xml we will then refer to this object instead of redefine it every time.

So let's go, we start by creating a config.saoscope.xml file which will contain the named object :

<xml>
  <connection id='jdoe_superstore' type="mysql">
    <param name="host">db.superstore.com</param>
    <param name="database">superstore</param>
    <param name="user">jdoe</param>
    <param name="password">azerty</param>
  </connection>
</xml>
config.saoscope.xml

You can notice that except the id attribute, it is exactly the same as what we enter twice in the two files. In those two file, we will now replace the big <connection> element by this small one :

<connection object="jdoe_superstore"/>

For example, orders.saoscope.xml become:

<page>
  <description>Display all the pending orders</description>
  <data type="sqlquery">
    <connection object="jdoe_superstore"/>
    <query><![CDATA[
      SELECT id AS "Order number",
	         customer AS "Customer name",
            date_order AS "Date of order"
	  FROM orders
	  WHERE date_delivery IS NULL
    ]]></query>
  </data>
</page>
orders.saoscope.xml with named object

Securing data

The solution before have a big drawback : ask for the Saoscope XML file in your browser instead of the php, and you get the database credentials.

There are two easy solution to prevent this :

  1. Copy the xml files in a directory unavailable for browsing, and update the path in Saoscope::display_page method
  2. use a .htaccess to forbide access to certain files, for exemple *.saoscope.xml. Or easier, you can start the name of your files with a dot (like .ordres.saoscope.xml), those file are generally forbidden in standard configuration.

Architecture

Example 3
Adding a default value with 'exec' type or normal

Example 4
Changing access to data

Architecture of a page: a composition of polymorphic objects.

Definition of objects :
- variable
- format
- value
- data


Reference XML

Reference Formats
Reference Value
Reference Data

Get Saoscope at SourceForge.net. Fast, secure and Free Open Source software downloads