the cpaint handbook edited

45
8/14/2019 The CPAINT Handbook Edited http://slidepdf.com/reader/full/the-cpaint-handbook-edited 1/45 The CPAINT Handbook  Paul Sullivan  Dominique Stender  First Draft 

Upload: paige-julianne-sullivan

Post on 30-May-2018

232 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 1/45

The CPAINT Handbook

 Paul Sullivan

 Dominique Stender 

 First Draft 

Page 2: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 2/45

Page 3: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 3/45

 Acknowledgements

•  all the users who have contributed code, ideas, defect reports, and made the CPAINT project a success

•  Paul would like to thank his loving wife Michelle for all the support she’s given throughout the

development of CPAINT and this book

Page 4: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 4/45

 

Page 5: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 5/45

Table of Contents

AJAX Fundamentals  ...................................................................................................................................................................... 2

What is AJAX? ....................................................................................................................................................................... 2 Is AJAX a new concept? ....................................................................................................................................................... 3 Who’s using AJAX? .............................................................................................................................................................. 3 Is AJAX cross-browser compliant? ..................................................................................................................................... 3 The Beginning (a good place to start) ................................................................................................................................. 4 What about POST? ................................................................................................................................................................ 5 Callbacks and Asynchronicity ............................................................................................................................................. 6 Calling the Backend .............................................................................................................................................................. 8 Finally, Some Data ................................................................................................................................................................ 9 Backend Implementation ..................................................................................................................................................... 9 Backend Security ................................................................................................................................................................. 10

 Getting Frontend Data ........................................................................................................................................................ 10 Function Execution ............................................................................................................................................................. 11 Usability Considerations .................................................................................................................................................... 11 Further Reading .................................................................................................................................................................. 12 

Introduction to CPAINT ............................................................................................................................................................. 13 What is CPAINT? ................................................................................................................................................................ 13 CPAINT Classes and Utilities ............................................................................................................................................ 14 

Frontend Classes ............................................................................................................................................................. 14 Backend Classes .............................................................................................................................................................. 14

 Proxy Utility .................................................................................................................................................................... 15 Debugging Utility ........................................................................................................................................................... 15 

Obtaining CPAINT and Other Information .................................................................................................................... 15 Frontend Implementation ........................................................................................................................................................... 16 

Import and Setup ................................................................................................................................................................ 16 Object Properties ................................................................................................................................................................. 17 

set_debug ......................................................................................................................................................................... 17 set_proxy_url ................................................................................................................................................................... 18 set_transfer_mode .......................................................................................................................................................... 18 set_async .......................................................................................................................................................................... 18 set_use_cpaint_api .......................................................................................................................................................... 18 set_persistent_connection .............................................................................................................................................. 19 set_response_type ........................................................................................................................................................... 19 set_auth_user................................................................................................................................................................... 20 set_auth_pass .................................................................................................................................................................. 20 

Page 6: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 6/45

Creating a Callback Function ............................................................................................................................................ 21 Gathering Data .................................................................................................................................................................... 21 Calling Backend Functionality .......................................................................................................................................... 22 Accessing Non-CPAINT Data Sources ............................................................................................................................. 23 

Traditional Web Scripts ................................................................................................................................................. 24 XML Based Scripts .......................................................................................................................................................... 24 

Working With Data in the Callback .................................................................................................................................. 25 Working with CPAINT Result Objects ............................................................................................................................. 26 Using the Proxy Utility ....................................................................................................................................................... 28 

Backend Implementation ............................................................................................................................................................ 29 Including the Backend ........................................................................................................................................................ 29 Stubbing the Backend Functions ....................................................................................................................................... 29 Registering Functions ......................................................................................................................................................... 30 Executing the Code ............................................................................................................................................................. 30 Accepting Data .................................................................................................................................................................... 31 Building Simple Responses ................................................................................................................................................ 31 Building Complex Responses ............................................................................................................................................ 32 cpaint_node Methods ......................................................................................................................................................... 32 

add_node ......................................................................................................................................................................... 33 set_data ............................................................................................................................................................................ 33 get_data ............................................................................................................................................................................ 34 set_attribute ..................................................................................................................................................................... 34 get_attribute .................................................................................................................................................................... 34 set_name .......................................................................................................................................................................... 34 get_name .......................................................................................................................................................................... 35 

Complex Response Example ............................................................................................................................................. 35 Appendix ...................................................................................................................................................................................... 37 

Arbitrary Character Sets ..................................................................................................................................................... 37 Frontend ........................................................................................................................................................................... 37 Backend ............................................................................................................................................................................ 37 Backend Framework Encodings ................................................................................................................................... 38 

CPAINT Backend Protocol ................................................................................................................................................ 38 api_query ......................................................................................................................................................................... 38 cpaint_function ............................................................................................................................................................... 39 cpaint_response_type ..................................................................................................................................................... 39 cpaint_argument[] .......................................................................................................................................................... 39 

API Reference ...................................................................................................................................................................... 40 

Page 7: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 7/45

The CPAINT Handbook

2

 AJAX Fundamentals

As this book is titled The CPAINT Handbook, we will only cover the fundamentals of AJAX for newcomers to the

technology in this section. This section is not intended to be a complete reference or implementation guide on AJAX.

There are wealth of books available that go into much greater detail.

 What is AJAX?

AJAX, in terms of web development, is an acronym for   Asynchronous JavaScript and XML. It is a development

technique that allows more responsive web applications by updating only parts of a web page. Unlike traditional

web forms, where a complete round-trip to the server is required to update a page (including sending all of its data),

AJAX allows developers to break a page into multiple sections and can ‘react’ to changes in data (based on user-

driven or predefined timed events) and update the page without requiring a complete round-trip and page refresh.

In this diagram, we see a traditional web application. The user enters data into one or more form fields and the

browser submits the form (typically based on a user-driven ‘submit’ event). All of the data on the form is sent to the

server. If the data needs to remain on the page, typically the server will have to send that data back the browser

(unless some other method is used, such as saving form data in a cookie before the form is submitted).

Page 8: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 8/45

The CPAINT Handbook

3

In this diagram, we see an AJAX-based web application. In this case, as the user works with the data on the page,

only the applicable data is sent to the server and the page is updated. Because the page never refreshes, any new (or

unchanged) data remains on the page throughout the multiple server transactions.

Typically, AJAX applications are based on a Browser Push model (the browser pushes data to the server). However,

a new concept called ‘Reverse AJAX’ is being utilized in some very specialized applications where the model is

reversed – Server Push (the server pushes data to the browser). This model is appropriate for situations where pages

need to be updated in response to something on the server-side, not something that is happening on the browser

side.

Is AJAX a new concept?

While most newcomers to the ‘AJAX revolution’ say that this is a new concept – it is a heated debate. Our ownresearch shows that the concepts of AJAX were being utilized long before 2005. Microsoft’s Outlook Web Client,

released with Microsoft Exchange Server 97, had the capability of updating the mail folder view and some properties

of the mail view window automatically. However, this capability was only available if the user was utilizing Internet

Explorer 4.0. Later that year, Microsoft released the Remote Scripting Toolkit to the public, but again, it only

supported IE and the ASP scripting language.

In addition, in August 2000, Brent Ashley released his JavaScript Remote Scripting toolkit which supported IE and

Netscape and ran entirely client side. We believe it is a combination of ideas from Ashley and Microsoft that gave

rise to the AJAX we all know and love today.

 Who’s using AJAX?

If you’ve ever used Google Maps, Flickr, Netflix, or Wordpress – you’ve used AJAX and didn’t even know it (that’s

actually part of the idea). There are literally thousands of websites and applications that utilize AJAX to give its users

an interactive experience on the web. In fact, Tim O’Reilly (love him or hate him) coined the term ‘Web2.0’ to

describe these highly interactive websites (although the term also applies to today’s ‘social networking’ sites such as

MySpace, although they make sparse, if any, use of AJAX concepts).

Is AJAX cross-browser compliant?

Any web browser released since 2005 is ‘AJAX compliant’. Prior to that date, alternative methods must be utilized

(such as hidden IFRAMEs) to make the retrieval of backend data transparent to the user. However, we have found

Page 9: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 9/45

The CPAINT Handbook

4

other problems in older browsers (such as incompatible JavaScript and DOM implementations) that make the need

for including alternate access methods in AJAX applications a colossal waste of time.

Since Internet Explorer 4.0 (actually MS-XML 1.0 library), an object called ‘XMLHTTP’ has been available to create

the transparent connection to the server. However, it wasn’t until the developers behind Firefox, Opera, and Safari

each built their own 100% compatible version of the object (called XMLHTTPRequest) until things got cooking.

The Beginning (a good place to start)

The fundamentals of AJAX are actually quite simple when broken down. Here we’ll go through a simple

implementation on the frontend side of things. Later, we’ll go through the backend.

To start, we need a reference to our connection object.

var A;

try {

A = new ActiveXObject('Msxml2.XMLHTTP');

} catch (e) {

try {

A = new ActiveXObject('Microsoft.XMLHTTP');

} catch (oc) {

A = null;

}

}

if (!A && typeof XMLHttpRequest != 'undefined')

A = new XMLHttpRequest();

if (!A) alert('Could not create connection object');

As stated earlier, IE calls the connection object ‘XMLHTTP’ and the other browsers call it ‘XMLHTTPRequest’. This

code simply tests for the presence of those objects and assigns a reference to it.

Next, we need to get the data we are going to pass to the backend. For example, I want to pass an email address back

to the server to see if it’s already in a database. In my HTML code, I have an input box with the ID attribute set to

‘email_address’. On the server side, my script (checkemail.php) expects this information to be in a form variable of

the same name (‘email_address’) and it expects a GET request.

So, I’m going to create a few local JavaScript variables containing this information.

var emailAddress = document.getElementById(‘email_address’).value;

var serverURL = ‘checkemail.php’;

var formMethod = ‘GET’;

var queryString = ‘?email_address=’ + emailAddress;

Did you notice the ‘queryString’ variable? Yes, I’m building a querystring just like I would pass it manually in the

browser’s address bar. In fact, those connection objects an be seen as HTTP socket – it can be used to send and

Page 10: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 10/45

The CPAINT Handbook

5

retrieve data over the web, but we have to set its properties and actions programmatically. And since I’m performing

a ‘GET’ request, I have to include the ‘?’ in order for it to be properly formed.

But, did you notice something missing? If it’s a ‘GET’ request, the querystring must be appended to the URL. So,

one more temporary JavaScript variable:

var URLtoCall = serverURL + queryString;

Yes, I could have built the entire URL in one fatal swoop, but I wanted to show you all the pieces you need for the

request:

1.  The URL of the script to call;

2.  A properly formed querystring;

3.  and, the actual data to pass to the script.

[edit: I don’t get the difference between 2. and 3. – GET vs. POST?]

Now, unlike images which can come across different servers, this is a script and JavaScript security doesn’t allow you

to import (run) scripts across domains (unless your script is signed with a trusted certificate). The same applies to

the XMLHTTP (Request) object – you can’t call a backend script from a different server.

If this script was served up by a page from the www.cpaint.net server, you’ll only be able to access backend scripts

on the www.cpaint.net server (and not any other server, even if it’s on the same domain – for example,

dev.cpaint.net). (However, if you use CPAINT and the backend proxy, you can access scripts across multiple servers

and domains – the data is passed to the local proxy script which in turn makes another request to the remote server

and passes the data back up to the browser.)

Note: Because the values of the URL and querystring are passed by value (and not reference) to the object, if either

piece of data changes, you’re going to run all this code again. That’s why it’s best to put all the ‘setup’ code in one (or

more) functions.

[edit: I find it a little irritating that the sending of the GET request and the response is missing here. Either integrating

it or a reference to the corresponding chapter would be good.]

 What about POST?

If you’re script or page is expected a POST request, as opposed to a GET request (or you want to do both), you’re

going to need to do a bit more work. Normally, when you submit a form via the web browser, it handles setting the

HTTP request headers for you. Because the connection objects are more generic, you’re going to have to set the

Page 11: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 11/45

The CPAINT Handbook

6

headers yourself. It helps to be familiar with the HTTP protocol specification and MIME content-types when it

comes to this, but in most cases, you only need to add these two lines to your JavaScript code:

A.setRequestHeader("Method",

"POST " + URLtoCall + " HTTP/1.1");

A.setRequestHeader("Content-Type",

"application/x-www-form-urlencoded");

And yes, I did say above you can do both a GET and a POST at the same time, if your script has the ability to parse

the querystring and the formdata. Most web scripting languages will support both, although you might have to call

two different methods or data structures to get the data you want.

You’ll notice that there’s no place for the POST in the above example. However, similar to the GET querystring, the

POST formdata must be in a URL-encoded string. However, unlike GET, we don’t need to append a question mark

(‘?’) to the beginning of that string. For example:

var postData = ‘email_address=’ + emailAddress

+ ‘&name=’ + username;

Callbacks and Asynchronicity

If you’re familiar with ActiveX components, you already know that they are event driven, not procedural. The same

is true for the XMLHTTP(Request) connection objects. You do not simply call the object and get data back from it.

Inside these objects, after creating a connection to the server, they wait until data is received back from the server.

When that happens, an event is fired where the state of the connection can be checked and we can retrieve our data.

Event are natively supported in many JavaScript objects, among them the XMLHTTPRequest object that AJAX is

built on. For this object it can call JavaScript code when there is a change to its connection state. This JavaScript code

is most commonly referred to as a ‘callback’ function (because it exists outside of the context of the object’s memory

space, thus ‘called back’ from the connection object).

The ‘A’ in AJAX stands for ‘asynchronous’, meaning that these transparent connections to the server can occur while

the user is performing other operations on the same web page (and these connections can occur simultaneously

without interfering with each other, if multiple instances of the object are created).

Note: It is entirely possible to have SJAX (Synchronous JavaScript and XML) where the user is blocked from using

the page until the call to the server is completed. CPAINT is the only toolkit that natively supports ‘SJAX’, although

it is rarely utilized, nor suggested.

The user will experience a “hangup” of the browser until the response has been retrieved

Page 12: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 12/45

The CPAINT Handbook

7

So, our callback function can be called multiple times as the connection object is performing the request – and the

user is interacting with the page. Because of this, callback functions have to check the connection state of the

XMLHTTP (Request) object each time it is fired. This is achieved by calling the readyState property of the object.

Possible states include:

1: Loading – object has been created, but it has not made a call to the server

2: Loaded – object sent request to the server, no response or data

3: Interactive – object is receiving data from the server

4: Completed – object has received data from the server and ready for retrieval

Unless you need a status of the object, the only state you are really going to care about is ‘4 – Completed’. This

means the object got something back from the server. That doesn’t necessarily mean that you’ve got the correct data.

For example, if you pointed the object to a script that didn’t exist, your data might probably contain the HTML for a

‘404 Page Not Found’ page sent from the server.

So, in addition to the callback function checking the state of the object, it’s a good idea to check the HTTP connection

status (e.g., 200, 401, 404, et cetera). This data is available in the status property of the object. If you get back 404,

which means your server couldn’t find the script you wanted to call. If you get 401, the server expects some user

credentials. But, if you get back 200, you’ve got data – and hopefully, it’s what you wanted! The data will be in two

places (simultaneously) – responseText and responseXML).

responseText is the raw, unparsed data that you can use if you’re using to retrieve a simple value from a backend

function or plain-text. However, if you’re retrieving HTML or XML and want to continue to work with it in

 JavaScript as a DOMDocument, use responseXML. The choice is yours to make, the data is identical. Keep in mind

that if you do use responseXML, it must be proper markup otherwise you’ll get errors when trying to work with it.

As I said above, the connection object will call the JavaScript callback function for you. But, you need to write it first.

Here is a simple function you can use.

var data;

A.onreadystatechange = function() {

if (A.readyState != 4)

return;

if (A.status == 200) {data = A.responseText;

}

}

In addition, you can assign the onreadystatechange property to point to another function that you’ve written

somewhere else (whereas this example is more of an ‘inline’ function). Your callback function can also call any other

  JavaScript function. However, it’s best to do it once the thereadyState is 4 and the status is 200, otherwise that

function might be hit many times when you don’t necessarily want it to. It’s also highly advisable to pass any data

Page 13: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 13/45

The CPAINT Handbook

8

received from the object directly to the other function and not in a global variable, as it might be overwritten on your

next call to the server.

Calling the Backend

Once you’ve got your object created, strings properly formatted, and callback function ready – it’s time to make the

call to the server.

The first thing you’ll want to do is open the object and pass a few basic parameters. Those parameters are:

1: Method – whether this is a GET or a POST call

2: URL – what page or script are we going to retrieve

3: Asynchronous – if you’re using AJAX, set this to true and your callback will be utilized. If you’re usingSJAX, set this to false. The object will block further execution of the page until the data is returned from the

server. (Note: for the XMLHTTPRequest object, this parameter is optional and defaults to true. However,

we recommend setting it to ‘true’ in all instances for compatibility.)

4: HTTP Username (optional) – if your script utilizes HTTP basic authentication, set the username here

5: HTTP Password (optional) – if your script utilizes HTTP basic authentication, set the password here

Here’s an example, in all its glory:

A.open(‘GET’, URLtoCall, true);

But, there’s one more thing missing. Remember earlier when I said you could do a HTTP POST, but we didn’t set the

data just yet. Regardless whether or not you are using HTTP GET or POST, you have to make a call to the send 

method of the object. If you’re doing a POST request, you will pass it your formdata as the only parameter.

However, on a GET request, anything you put here will be ignored, but we recommend you just pass NULL for

compatibility.

// HTTP POST

A.send(formData);

// HTTP GET

A.send(null);

The data has now been sent to the server and the object will await a response.

Page 14: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 14/45

The CPAINT Handbook

9

Finally, Some Data

Once you’ve made the call to the server, it’s time to see what you’ve got. Depending on what format the server

returned the data in, as we mentioned above, there’s two ways to get it out of the object and work with it in JavaScript.

If the data is properly formatted markup, such as HTML or XML and you want to work with it as a DOMDocument

(so you can traverse it, pulling out tag names, attributes, and tag data), you would use responseXML. However, if

it’s in any other format or you don’t need to traverse it (say, you’re just going to display it to the user), use

responseText to get the data. See the sample callback function which uses responseText to assign it to a global

variable. (You could also say, use responseXML for complex data or responseText for simple data.)

What you do with the data once you’ve got it is up to you and your imagination. Simple AJAX applications simplyreturn HTML from the frontend and replace the contents of an HTML DIV with the results. See

http://cpaint.net/examples.html  for a few simple (and complex) examples of what you can do (read about the

CPAINT API later on – the source code to the examples is distributed with CPAINT).

Backend Implementation

Now that you know how to get data from the backend, it’s time to take a closer look at generating that data. Just like

the frontend code, the backend can be as simple or as complex as you make it (but generally, the backend is easier to

implement than the frontend, since you won’t have to deal with cross-browser issues).

Simple backend implementations simply generate HTML data which is retrieved by the frontend and replaces parts

of an existing web page. This can be achieved in PHP by simply using print statements intermingled with HTML

code. You can simply pass parameters into your script like you would a normal form, either on the querystring (for

GET requests) or in the form data (for POST requests).

However, we feel that AJAX is best utilized when performing shared tasks on the backend. This is done by setting

up a simple API that allows the frontend to pass data to backend functions (or class methods). Using this approachnot only lets you share functions across both the frontend and backend, but allows for easier management by having

multiple functions in a single file. (Of course, you can also use include files to break up functionality into multiple

files if you have a large number of them.) And there’s no rule that says that backend functions for the frontend have

to be different.

[edit: not clear what’s the message here]

Page 15: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 15/45

The CPAINT Handbook

10

Backend Security

In fact, there are a few principles that you need to keep in mind when developing backend functions and an API to

access them:

1.  Since a single file (or URL) could expose multiple functions, within your API, you need to include a

parameter to specify the backend function you want to execute.

2.  You also need to provide some way in your API for passing multiple parameters to your backend functions,

like an array.

3.  While your frontend JavaScript might validate the data, it’s very easy for an advanced user to completely

bypass any sanity checking on the frontend, so you need to perform another level of sanity checking on the

backend (in fact, it’s a good idea to follow this even when using standard HTML forms in a non-AJAX

application).

4.  On that note, you need to make sure that your script will only access the functions that you want exposed

AND that any data passed in isn’t directly evaluated or executed.

5.  Finally, you’ll want a way to pass errors up to the frontend, in the event the data was invalid or the

operation couldn’t be completed.

Getting Frontend Data

So, based on the principles mentioned earlier, we can start building our API. The first thing we need to do is put the

data we get from the frontend into some local variables (while optional, I’ve found it easier to work with in the long

run, should the API change, I don’t have to change the code in multiple places).

$functionToExecute = $_REQUEST[‘function’];

$parameters = $_REQUEST[‘color’];

I thought we agreed that we would pass in multiple parameters to the backend? Yes, the code above is correct,

provided it was passed in properly. In PHP, multiple parameters can be passed from an HTML form (or in the GET

querystring or POST formdata) by appending an opening and closing bracket to the form variable’s name. For

example:

<input name=”color[]” type=”checkbox” value=”green”>

<input name=”color[]” type=”checkbox” value=”red”>

If this was a normal HTML form, when it was submitted (and if both checkboxes were checked), PHP would create

$_REQUEST[‘color’] as an array containing two members, green and red.

Page 16: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 16/45

The CPAINT Handbook

11

However, since you’re not using an HTML form, you have to set up the querystring/formdata string yourself. You

may have the desire to pass both values as a single parameter, separating them with commas, but you would end up

with a string reading ‘green,red’. Again, use brackets to specify repeating value names. For example:

color[]=green&color[]=red

Note: Other languages may not use brackets to build the array on the backend – you’ll have to adapt your script to

use whatever conventions it needs.

Function Execution

As mentioned above, you want to limit what can be executed on the backend. In PHP, this is relatively simple to do.

One way is to use simple if statements and check the function name that was passed in. You could also manually

write an array of functions that are allowed to execute and check against that list.

Once you’ve verified the function name, you can now execute the function and pass it the data received from the

frontend. In PHP this is actually very simple, as you’ll see below. However, for other languages, this may be much

more complex (as you need to make sure no arbitrary code was passed in that might get executed server-side).

if ($functionToExecute == ‘check_user’) {

$result = check_user($_REQUEST[‘name’],

$_REQUEST[‘password’]);

print($result);

}

Of course, depending on what the frontend is expecting, your function can return HTML, XML, plain-text, or someother formatted text (even binary data for the brave). This is also not the only way to call your backend functions.

The CPAINT backend API actually sends all the parameters from the frontend in one string, parses it back out on the

backend, and passes it to user functions in an array using call_user_func_array.

Usability Considerations

Because AJAX changes the way that users interact with the web page, there are a few important usability

considerations to take into account.

1.  Users typically expect the entire page to refresh when performing an action. Based on your target audience,

it may be beneficial to use some sort of effect to show that the content has been updated.

2.  Users will also know that the browser is retrieving data from the server based on a progress bar or spinning

icon (depending on the browser). When using AJAX, the user won’t know what’s going on, so it might be a

Page 17: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 17/45

The CPAINT Handbook

12

good idea to display a ‘loading’ message or progress bar while new data is being retrieved from the

backend. Alternatively, change the appearance of the mouse cursor while a request is underway.

3.  Typically the user will expect that clicking the browser’s back button will return them to a previous state.

However, the browser button only works for different pages – not new or different parts of the same page.

For this reason, it’s not advisable to use AJAX to update the entire contents of the page unless you can build

your own ‘back’ functionality (you could use cookies to store previous states of the dynamic content).

4.  In the event that the user is using an older browser or a non AJAX capable browser, it might be wise to

provide an alternate set of pages and forms for core functionality.

For additional considerations, see Michael Mahemoff’s AjaxPatterns website at http://www.ajaxpatterns.org/ or the

infamous “Ajax Mistakes” article by Alex Bosworth at

http://sourcelabs.com/ajb/archives/2005/05/ajax_mistakes.html  

Further Reading 

Because the previous section was only intended as an introduction to AJAX fundamentals, it may be beneficial to

refer to other books if you’re going to implement your own frontend and backend.

See http://www.ajaxpatterns.org/Books  for some excellent books on AJAX (many of which list CPAINT in the

appendix).

Page 18: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 18/45

The CPAINT Handbook

13

 Introduction to CPAINT 

If you just finished reading the first section or you already have some knowledge of or experience with AJAX, this

section will introduce you to CPAINT (the Cross-Platform Asynchronous Interface Toolkit), the open-source toolkit that

is the focus of this book.

 What is CPAINT?

CPAINT (Cross-Platform Asynchronous Interface Toolkit) is an open-source project started by Paul Sullivan (the author

of this book) in May 2005 after his disappointment with early AJAX toolkits. His work originally started when he

ported another AJAX toolkit from PHP to ASP. He was disappointed with the inefficiencies and inflexibility of that

toolkit and wrote CPAINT from the ground up.

One month later, Dominique Stender joined the project, bringing time and ideas to the project, including the OOP

design and improved documentation layout. Currently, Paul and Dominique are the lead developers and co-leaders

of the project.

Most AJAX toolkits available on the market, both open-source and commercial, have a strong focus on sexy widgets.

This approach attracts many novice developers who want to build copy-cat web apps and don’t care about flexibility,

compatibility, and creativity.

CPAINT focuses primarily on communications and the ability to access remote data, which is what makes or breaks

AJAX applications. Thanks in part to our OOP design, it is extremely flexible and easy to implement in new and

existing web applications and can interface with any other frontend or backend toolkits or libraries.

CPAINT has separated frontend JavaScript code from server-side code (only PHP is actively supported on the

backend), which allows the CPAINT frontend to access any other AJAX toolkit or server (including SOAP and other

XML servers or those just serving HTML or plain text). In addition, via a server-side proxy script, data can be sent to

remote servers, including those in the backoffice which may not be available for public access.

Additionally, we have one or more independent security teams audit CPAINT during our exhaustive testing andrelease process. Coupled with our unmatched flexibility, it has risen to become the toolkit of choice for enterprises

that need solid, secure code that runs efficiently both client- and server-side for high volume web applications.

[edit: sorry to say this but is this going to be a handbook or a marketing-speech? ;)]

Page 19: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 19/45

The CPAINT Handbook

14

•  The frontend and backend classes are licensed under the terms of the LGPL v2; the proxy script and

debugger are licensed under the terms of the GPL v2; and the documentation are licensed under the terms

of the Creative Commons Attribution 1.0 license.

•  Project started in late May 2005 and still going

•  First AJAX toolkit with 100% OOP approach

•  First toolkit that doesn’t focus on GUI components but building a flexible, enterprise-strength AJAX toolkit

•  Only toolkit that can communicate with other toolkits, web services, and backoffice/cross-domain servers

(via a server-side proxy)

•  First toolkit to generate XML on the server side and interpret XML on the client side.

•  First toolkit to support E4X

•  Only toolkit to support multi-byte characters

•  First toolkit to natively support JSON (JavaScript Object Notation)

•  Only toolkit to with the ability to reuse the connection object, therefore keeping browser memory usage to a

minimum

•  Only toolkit to support SJAX (Synchronous JavaScript and XML)

•  Low churn with a common API across major releases

•  Referenced in multiple books on AJAX

•  Quick reference “cheat sheet” provided for convenience

[edit: you’re claiming many “firsts” and “onlys” here. I hope they’re verified. I wouldn’t like to unleash the

wrath of all other AJAX toolkit developers here… really baaaaad reputation ;) ]

CPAINT Classes and Utilities

The frontend classes are cross-browser compliant JavaScript classes that setup and manage the XMLHTTP (Request)

component for communications, provide translation functions for converting data to and from the backend,

debugging code execution and data responses, and accessing data returned from the backend.

Frontend Classes

The backend classes complement the frontend classes and are responsible for code execution, data conversion, and

data return. Currently, CPAINT only supports PHP on the backend.

Backend Classes

If you’re developing in a backend language other than PHP and would like to port the CPAINT backend to that

language, let us know!

Page 20: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 20/45

The CPAINT Handbook

15

Since the XMLHTTP (Request) component can only access data on the same server for unsigned JavaScript code, this

script acts as a HTTP proxy to access data across multiple servers and domains. Currently, the proxy is only

supported in PHP.

Proxy Utility

This is an experimental script that can be dropped into any backend code that implements CPAINT. It facilitates the

debugging of backend code without the need for a complete frontend implementation.

Debugging Utility

Obtaining CPAINT and Other Information

All releases of CPAINT are available via SourceForge at http://sourceforge.net/projects/cpaint 

Complete API documentation is included with the source archive and consistently updated at http://cpaint.net/doc 

with each new release.

Examples and other information can be obtained at http://cpaint.net 

See the latest CPAINT documentation at http://cpaint.net/doc for support options and submitting defect reports.

Page 21: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 21/45

The CPAINT Handbook

16

Frontend Implementation

Import and Setup

The CPAINT frontend classes are available in two different files – a standard JavaScript file (complete with code

comments) – and a compressed version (which has comments and whitespace removed). Both versions are identical

in operation, as we provided the compressed version to save our users some bandwidth when serving their users.

If for any reason you modify the non-compressed code and want to recompress the code, we used an OSS utility

called jsmin by Douglas Crockford, available at http://crockford.com/javascript/jsmin.html  

Importing the CPAINT frontend classes into your code is as simple as one line of code to every page you want to use

it on:

<script type=”text/javascript” src=”cpaint2.inc.js”>

(substitute cpaint2.inc.compressed.js for the compressed version)

Why ‘cpaint2’ and not just ‘cpaint’? We appended the ‘2’ to all the CPAINT filenames because there was such a

difference in the code base between CPAINT v1.x and v2.x. As new versions of CPAINT are developed, this postfix

may change if warranted.

Note: When importing the script, make sure to usetype=”text/javascript”

in the <script>

tag and notlanguage=”javascript”. This will prevent older browsers (that don’t understand JavaScript classes) from

loading the files.

When using E4X as response type, you have to use type=”text/javascript; e4x=1”> for your javascript

libraries including CPAINT!

After importing the frontend classes, you’ll also want to add another <script> section where you’ll work with the

classes. Like above, make sure to use the type=”text/javascript” attribute to prevent older browsers from

loading the code.

In most cases, you’ll only need to create one instance of the cpaint object, even if you are updating multiple parts of

the page simultaneously. If you need make a request to the backend and the object properties need to change, you

can create multiple instances of cpaint and run them simultaneously (or you can destroy one instance and create a

new instance with the same name and change the object’s properties).

Page 22: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 22/45

The CPAINT Handbook

17

Since the need for multiple instances of the cpaint object is rare, in this example, I’m going to show the creation of one

instance:

<script type=”text/javascript” src=”cpaint2.inc.js”>

<script type=”text/javascript”>

var objCpaint = new cpaint();

</script>

Object Properties

The frontend cpaint object exposes a number of properties that are used to control how the frontend and backend

operate.

[edit: that’s not true!]

Note: The CPAINT properties are accessible through setter methods.

Within the frontend code, we have implemented a stack handler which manages the creation and use of multiple

XMLHTTP (Request) objects, which give CPAINT the ability to handle multiple simultaneous requests. Because the

number of objects can vary at any given moment, using JavaScript properties in the traditional style will make this

next to impossible. So we use methods to set the properties of a primary cpaint object and pass those properties to

the newly created objects.

Since there are no real destructors in JavaScript, the cpaint object instance can be destroyed by setting it to null, for

example objCpaint = null;

This sets the debugging level of the object. Debug messages are returned to the browser in the form of JavaScript

alert boxes. This is useful during the development process, however we don’t recommend setting any debug options

on production applications, as there is currently no way to capture and handle errors.

set_debug 

Possible values for set_debug include:

-1 : no debug or errors (this is the default)

0 or false : no debug messages returned, only errors

1 or true : debugging of commonly used information, such as object creation and connection status

2 : full debugging, adding information about the stack handler and server responses. Use with care.

Example:

objCpaint.set_debug(2);

Page 23: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 23/45

The CPAINT Handbook

18

This sets the URL for the proxy utility in the event you are accessing from a different server or domain. Since the

proxy must be on the same server as what the frontend code was served from, there is no need to include the method

and server name in this property. A valid absolute or relative (to the page that is calling the proxy utility) must be

given in order for the call to succeed.

set_proxy_url

By default, this value is set to an empty string. If it is not set and you attempt a call to a remote server, an error will

occur.

Example:

objCpaint.set_proxy_url(‘/cpaint2.proxy.php’);

This sets the transfer mode for the backend call. Currently, only GET (the default) and POST are supported.

set_transfer_mode

If you are sending a large amount of data, it is recommended that you use POST, as there are limitations on the

amount of data that can be passed in a GET request. This limit ranges from 2000 to 8192 characters and varies from

browser to browser.

Example:

objCpaint.set_transfer_mode(‘POST’);

The ‘A’ in AJAX stands for ‘asynchronous’, meaning that the user can continue to work with the web page as

CPAINT interacts with the backend server. However, in some occasions, it may be necessary to receive the data from

the backend server before continuing. In this case, set this property to false which will make the page wait until

data is received from the server to continue. Obviously, the default is for this property is true.

set_async

Example:

objCpaint.set_async(false);

Note that with synchronous calls users will experience a temporary “hangup” of their browser!

It is entirely possible to use the cpaint frontend object to call both local and remote scripts which don’t implement

CPAINT on the backend. When this applies, you need to set this property to false to let the cpaint object know that

it doesn’t need to worry about building the GET querystring or POST formdata string, as you will have to supply it.

The default for this property is true.

set_use_cpaint_api

Page 24: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 24/45

The CPAINT Handbook

19

Example:

objCpaint.set_use_cpaint_api(false);

[edit: reference to an example maybe]

Normally, when the cpaint request object goes to retrieve data from the backend, it will use the stack handler to

control the creation of new and reuse of existing connection objects. This is what gives CPAINT the ability to handle

multiple simultaneous requests.

set_persistent_connection

However, if requests are being made infrequently, it is possible to save memory on the frontend by reusing the same

connection object across multiple requests - a la connection persistence. However, this doesn’t mean the connection

to the server remains open or the backend URL needs to remain the same. Only the connection object is kept alive.

The default for this property is false.

Example:

objCpaint.set_persistent_connection(true);

If you don’t pay attention to any other property, you’ll need to pay attention to this one. This tells not only the cpaint

frontend, but the cpaint backend, in what format the data will be in and helps control how it is generated (in the case

of the backend) and how it is interpreted (on the frontend).

set_response_type

There are five possible values for this property:

•  OBJECT (default)

The frontend will expect the results to be in XML (or any SGML-based markup language) and use its

internal methods to convert the data into a native JavaScript object structure.

•  TEXT

The frontend will not perform any conversion on the data that is received for the backend. If you are

returning simple values from the backend that you will use in JavaScript, you are returning HTML to

replace part of a web page, or you want to parse the data yourself – use this value.

•   JSON

The frontend will expect a properly formatted JSON string. JSON gives developers the ability to pass object

structures between the frontend and backend. The cpaint frontend object will automatically parse the JSON

string and return a JavaScript object structure to the frontend application.

Page 25: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 25/45

The CPAINT Handbook

20

 

More information on JSON can be found at http://www.json.org/ 

•  XML

The frontend will expect properly generated XML (or other SGML-based markup) and the connection object

converts the returned data into a DOMDocument object that can be traversed as a native JavaScript object.

•  E4X (ECMAScript for XML)

This is almost identical to the ‘XML’ property value, as it returns an object that can be traversed as a native

 JavaScript object. However, currently it is only supported by Mozilla Firefox 1.5 and above.

[we need a better explanation here, maybe with some small example – I’ll think of something]

More information on E4X can be found at  http://www.ecma-international.org/publications/standards/Ecma-

357.htm 

Example:

objCpaint.set_response_type(‘XML’);

If the backend script (or the proxy utility) you are accessing is protected with HTTP Basic Authentication, use this

property to set the user name to use for authentication.

set_auth_user

Note: This information is not passed to remote scripts via the proxy utility – see information about the proxy utility

to learn how to set the remote username.

Example:

objCpaint.set_auth_user(‘username’);

This is a companion function for set_auth_user to set the password for HTTP Basic Authentication.

set_auth_pass

Page 26: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 26/45

The CPAINT Handbook

21

Creating a Callback Function

As with other AJAX implementations, you will need to write a JavaScript callback function which will receive the

data when it comes back from the backend script. This is true even when using synchronous requests.

Your JavaScript function needs to include at least one input parameter, which can named anything you would like.

Depending on what response type you previously selected, this parameter could contain textual data or an object of

some sort.

Note: The cpaint object will return two parameters to the callback function. The first parameter will be the

‘interpreted’ object (if the response type is anything other than ‘TEXT’) and the second (optional) parameter will

contain the same data, but in plain-text format.

At minimum, it is a good idea to prototype your callback function before making the actual call to the backend. You

may use the same callback function for multiple backend functions (although you may need to return some sort of

identifier if the data is to be handled differently).

Gathering Data

Of course, you’re going to need to gather data to be sent before you can make the backend call. The easiest way to do

this is to use id attributes in your HTML code for easily retrieving values from <input> elements. Here is a verysimple example:

<input type=”text” name=”username” id=”username” />

Retrieve in JavaScript with:

var uName = document.getElementById(‘username’).value;

However, if you need to pass multiple elements of the same name, for example, a group of checkboxes or a multiple

selection box, getting the data and preparing it for the backend requires a bit more code.

If you aren’t using CPAINT on the backend, it all depends on how that implementation is used to handling arrays.

Keep reading to learn how to handle this special situation.

However, if you are using CPAINT on the backend, you simply need to get all the values into a JavaScript array. The

cpaint frontend object class will handle converting this into something the backend can understand (JSON, to be

exact).

Page 27: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 27/45

The CPAINT Handbook

22

For example, this code simply loops through a multiple select box and puts the selected values into an array:

var selectedArray = new Array();

var selObj = document.getElementById(‘multiSelect’);

var i, count;

for (i=0; i<selObj.options.length; i++) {

if (selObj.options[i].selected) {

selectedArray[count] = selObj.options[i].value;

count++;

}

}

While this example concentrates on rather simple data being sent to the backend, CPAINT allows you to create your

own anonymous objects and object structures in JavaScript and send them to the backend.

[edit: I’ll think of an example here]

Calling Backend Functionality

Once you have either prepared or found the appropriate data and at the very least written a stub for your JavaScript

callback function, it’s now time to send it to the backend using the call method of the cpaint frontend object.

The call method takes a variable length of arguments:

1.  URL of backend script (string)

If the backend function is on the same server as the serving page, this can be an absolute or relative

reference to the script you want to access.

However, if the data or script is on a different server or domain (and you set a correct path to the local proxy

utility), supply the full URL path in this argument. We’ll talk about special considerations for remote data

in another section.

If the backend resides on the same server or domain, but uses an alternate port, you can provide a full URI

path – for example:

http://cpaint.net:8080/scripts/ajax.php

2.  Backend method name (string)

If the backend method you’re going to call isn’t using CPAINT, you can simply set this to NULL or an

empty string. Otherwise, provide the name of the method (which is case-sensitive) here.

3.  Callback function (object)

Page 28: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 28/45

The CPAINT Handbook

23

This should be set to the JavaScript callback function that will be handling the data that is returned by the

backend.

Be careful not to pass the JavaScipt callback function as string. CPAINT expects the parameter value to be an

object!

4.  Arguments (mixed)

The cpaint object does not have a hard limit on the amount of data (or number of parameters) you can send

to the backend. However, if you are using the HTTP GET method, there is a soft limit of around 1000 bytes

(it varies wildly between multiple browsers, but this seems to be the floor).

The backend method will receive arguments in the same order that you specify here and there is no need to

create name-value pairs if the backend script is using CPAINT. If the backend script doesn’t use CPAINT,

read the next section to setup the arguments.

This short example shows us calling a local script named ‘ajax-functions.php’, calling the remote function

‘check_user’, passing a user name from an HTML input tag with the id ‘username’, and using a callback function

named ‘check_user_result’:

cpaintObj.call(‘ajax-functions’, ‘check_user’, check_user_result,

document.getElementById(‘username’).value);

Accessing Non-CPAINT Data Sources

Accessing data from non-CPAINT data sources requires only a small amount of more work, depending exactly what

they expect.

If you are using a non-CPAINT data source, make sure you set the set_use_cpaint_api property to false.

If you’re not sure if the backend script was implemented with CPAINT, there’s one easy way to tell. Simply the call

the script in a web browser with ‘?api_query’ appended. Example:

http://cpaint.net/examples/ping/ping.php?api_query

If the backend uses CPAINT it will reply with a message, for example:

CPAINT v2.0.3/PHP v5.1.2

See the API reference in the appendix for the format of this string.

Page 29: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 29/45

The CPAINT Handbook

24

CPAINT was built with an API that is compatible with the same major revision number. [edit: meaning?] In other

words, if the backend is v2.0.2 and the frontend is v2.0.1, or vice versa, you won’t have any problems. It is possible to

use a v2.x frontend with the v1.x backend, but not the other way around.

This group of scripts encompasses all scripts that take input from some source, for example an HTML form. To

utilize these scripts, you simply need to create name-value pairs and pass each pair as a separate argument to the

cpaint call method. You do not need to worry about separating them with ampersands (‘&’) or encoding the data,

as the cpaint object will take care of that for you.

Traditional Web Scripts

In addition, you do not need to specify the backend method name as it will be ignored. However, if the backend

script provides multiple methods, you may need to refer to its API definition.

Example:

objCpaint.call(“non-cpaint.php”, ‘’, callback_func,

‘user=’ + strUser, ‘pass=’ + strPass);

Note: If the backend script will be accessed via a GET request, do not put the name-value pairs in the script URL

argument. If you do so, the cpaint object will not be aware of that data, which means the data will not be encoded

nor will any additional parameters you pass to call be properly passed to the backend.

[edit: I had to read it twice to know what you mean. Maybe an example makes things clearer here.]

The frontend will not parse a JavaScript array for use with a non-CPAINT data source at this time. Instead, you will

need to parse the data and build independent name-value pairs on your own.

For PHP-based scripts, you will need to append each name with brackets. For example, if the array had three

members (“red”, “yellow”, & “green”) and you wanted to pass them in as the name “colors”, your parameters to

call would be:

“colors[]=red”, “colors[]=yellow”, “colors[]=green”

This group includes any script which expects XML as its input, including SOAP-based Webservice scripts andapplications. While CPAINT can call the script, you will need to build the XML yourself on the frontend.

XML Based Scripts

CPAINT improvements regarding the XML-creation problem are planned already bot no release date is set as of

now.

In the likely event that the script needs XML in the POST body of the request and additional parameters in the GET

querystring, you may add those parameters to the script URL when invoking the call method. However, the cpaint

Page 30: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 30/45

The CPAINT Handbook

25

object will not be aware of those parameters, so you will need to ensure the strings are properly encoded (using the

 JavaScript encodeURIComponentmethod).

Once you generate the XML, pass it as a single argument to the call method. You also want to make sure that your

transfer mode is set properly (usually the set_transfer_mode should be ‘POST’).

Example:

var XMLRequest = ‘<request><action>getUser</action>

<parameter>paul</parameter></request>’;

objCpaint.set_transfer_mode(‘POST’);

objCpaint.set_use_cpaint_api(false);

objCpaint.call(‘xmlserver.php’, ‘’, return_handler, XMLRequest);

 Working With Data in the Callback

If the backend call completed successfully, the data will be available to your JavaScript callback function. As

previously stated, your callback function needs to take at least one parameter.

The contents of the first parameter will depend on what the response type was set to before you made the backend

call. Unless you set the response type to ‘TEXT’, this will be an object of some sort that you can traverse in a tree-like

manner to retrieve the data.

The second, optional parameter for your callback will always be plain-text, regardless of the response type. In the

case of ‘TEXT’, the contents will be identical. Otherwise, this will be the raw contents that were parsed to generate

the object you received via the first parameter. If the response data is ‘TEXT’, you can start working with the data

directly in your callback script, such as updating the webpage, form values, or use it in other parts of the script.

Keep in mind that the data received by the callback is not global or persistent. Once the function completes

execution, the local data will be lost if you don’t copy it to a global variable. Also keep in mind that if you make

multiple, simultaneous calls to the backend using the same callback function, that you may have multiple instances

of that function executing (“threading”), which (depending on what it does) could overwrite the result of another

instance of the callback.

While CPAINT handles the threading of multiple simultaneous calls to the backend, it is up to you to handle

threading in the frontend applications.

For all other response types other than ‘OBJECT’, you can find many books and references for accessing data in the

object.

Page 31: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 31/45

The CPAINT Handbook

26

Here is a simple example:

function callback (resultData, resultText) {

alert(‘I received ‘ + resultText);

}

 Working with CPAINT Result Objects

If you specified ‘OBJECT’ as the return type, the cpaint frontend will interpret the data and return a

cpaint_result_object object. While this is most commonly used with backend code that has been implemented

with CPAINT, it could be used for any data source that returns XML.

The cpaint_result_object is similar to the DOMDocument object class, as it contains both the data and a few

simple methods to access the data. However, each XML tag is a new named instance of the class, making it easier to

access. Because XML is in a tree-like hierarchy, you get to the data by accessing the data from working your way

down from the top.

Here is a sample response sent from the backend:

<encoding>

<charset id="alphanumeric">

This is a test

</charset>

</encoding>

Assuming our object is named ‘result’, you would access the first level of data (everything that encompasses the

<encoding> tag) simply by referencing it directly, by name:

result.encoding

If there were multiple <encoding> tags in the response, you can access them like you would an object, using a

counter. This example shows a loop where each tag can be accessed:

for (var i = 0; i< result.encoding.length; i++) {

// access the data with result.encoding[i]

}

You should not be using the syntax for (var i in result.encoding) when using CPAINT – the JSON

implementation it is shipped with tends to cause some problems if data is not properly checked via typeof 

statements.

If there were multiple tags, each with a unique id attribute, the object provides a quick method for getting a

reference on the data that it contains without having to traverse the entire tree.

Page 32: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 32/45

The CPAINT Handbook

27

 

Using the find_item_by_type method takes two parameters, the tag name (using the above example, it would be

‘charset’) and the value of the id attribute (in this example, ‘alphanumeric’). For example, this would get us closer to

the data:

result.find_item_by_type(‘charset’,’alphanumeric’)

In addition, if you are traversing the tree and want to get the value of an attribute, simply use the get_attribute 

method:

result.encoding[0].get_attribute(‘id’)

If for any reason you want to dynamically change the value of an attribute (perhaps to ‘mark’ it as being read), you

can use set_attribute in the same manner:

result.encoding[0].set_attribute(‘id’,’1’)

Of course, you can also create and set a new attribute this way.

Finally, to get the actual data within tags, use the data property. For example, a reference to the data in the above

example would be:

result.encoding[0].charset[0].data

Here is a more complex result with references:

<encoding>

// result.encoding[0]

<charset id=”test”>

// result.encoding[0].charset[0]

this is the first test

// result.encoding[0].charset[0].data

</charset>

<charset id=”another_test”>

// result.encoding[0].charset[1]

this is the second test

// result.encoding[0].charset[1].data

</charset>

</encoding>

<encoding>

// result.encoding[1]

<charset id=”test3”>

// result.encoding[1].charset[0]this is the final test

// result.encoding[1].charset[0].data

</charset>

</encoding>

Page 33: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 33/45

The CPAINT Handbook

28

Using the Proxy Utility

The backend proxy is a separate entity from the frontend and can be utilized transparently by the frontend. If the

set_proxy_url is not empty, the frontend will attempt to send the backend request via this script that we haveprovided for your use.

The proxy utility must have a proper URL in order for the request to work properly, including port number and user

authentication credentials, if necessary. The proper format for URLs is as follows:

http://[userid:password@]server.domain.tld[:port]

/path/filename.ext

You will specify this URL as the first parameter in calls to the cpaint frontend call method. Example:

objCpaint.call(‘http://paul:[email protected]:8080/scripts/ajax.php’, ‘auth_user’,

authHandler, username, ‘password’);

[edit: its quite irritating not to have a CPAINT call here – took me a while to realize that]

Because the proxy utility should only be utilized by your users and not become a gateway for the entire world, we

have implemented a whitelist for the proxy. Simply edit the cpaint2.config.php file that is included with the

CPAINT distribution to set the servers, paths, or scripts that the proxy is allowed to access.

In addition, you can set a few other options (such as error reporting and timeouts) for the proxy utility in the

cpaint2.config.php file.

[edit: a small run-through on the config file itself is missing in the book]

Page 34: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 34/45

The CPAINT Handbook

29

Backend Implementation

Including the Backend

Like the CPAINT frontend code, the backend implementation is self-contained in a single file. Only external helpers

like the PHP implementation of JSON and the proxy utility reside in their own files. Unlike other AJAX toolkits, we

implemented the backend with the philosophy of separating display from logic, meaning that while it is entirely

possible to include backend functionality within the same source file as the frontend, the CPAINT backend must be

included before any data is sent to the browser (including print statements or even blank lines, as they are sent to the

browser before any code executes).

The CPAINT backend can be included with one simple statement:

include_once(‘cpaint2.inc.php’);

 Just as the frontend was implemented using an object-oriented approach, the CPAINT backend includes an object

called cpaint that controls the execution of the backend code. However, there is no reason to create multiple

instances of the cpaint object, otherwise your backend code will be executed twice every single time the script is

called.

Creation of the CPAINT backend object is simple:

$cp = new cpaint();

Stubbing the Backend Functions

If you haven’t already written your backend functions, now is a good time to at the very minimum write stubs for

them, as you will need to at least know what they are called. A little later, we’ll show you how to make your new (or

existing) function work with the CPAINT backend.

Your backend functions don’t need to be standalone. You can implement them as methods within a class. However

at this time, the CPAINT backend can only execute one method for every call to the backend, so the object that

contains the method must be created before it can be used by CPAINT. Class methods that are called statically by the

CPAINT backend do not have this dependency.

In addition, if your functions are implemented across multiple files, as long as they are included in your page where

the cpaint object was created, the backend object will be able to execute those functions.

Page 35: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 35/45

The CPAINT Handbook

30

Registering Functions

Obviously, you don’t want to expose all of your backend functionality to the world for “free use”, either for security

purposes or the fact that not all of them have been adapted for use by CPAINT. For those reasons, we haveimplemented function registration.

You can register a static function or a class method, but you cannot register a built-in function of the scripting

language (if you wanted to do so, you will need to build a wrapper). Because it is possible that functions can be

reused throughout your code, you can have the option of defining an alias name that is used for AJAX calls.

Use the register method of the cpaint backend object to specify which functions can be utilized by the frontend.

At this time, you must specify each function on a separate line.

$cp->register(‘authenticate_user’);

// same function, with an alias

$cp->register(‘authenticate_user’, ‘r2d2);

If you are registering a class method, you must use an array to pass the class name (or the instance name) and the

method name

// this assumes the class has already been instantiated

$cp->register(array(&$new_object, ‘object_method’));

// or for a static method with an alias

$cp->register(array(‘user_class’, ‘authenticate’),

‘authuser’)

Executing the Code

To tell the cpaint frontend object to parse the incoming data and hand it off to the appropriate function, simply call

the start method.

$cp->start();

[edit: notifications for users that need to use charsets other than UTF-8 should be here]The cpaint backend object will execute the function and store its returned data in memory. At this point, no data has

been sent back to the frontend. To complete execution, simply call thereturn_data method.

$cp->return_data();

Page 36: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 36/45

The CPAINT Handbook

31

The script does not stop executing at this point. This is to give you the ability to perform any cleanup, shutdown,

logging, or any other tasks your script may need to perform. You could send further data to the frontend at this

point using print statements (or anything outside the code block), but this really isn’t advised for a proper response.

Note: Custom HTTP headers must be sent before $cp->return_data() is called.

Accepting Data

In order for the cpaint backend object to properly pass the data back to the frontend, you will need to make simple

changes to your function.

For starters, the function will need to have access to the cpaint object. This is achieved by adding the global keyword

and the object’s name to the first line of your function.

function validate_user($username, $password) {

// import the cpaint object

global $cp;

}

At this point, you can write your function like you normally would. The data from the frontend is passed is available

to your function as local variables (based on this example). You can also use your function to accept variable length

arguments, either using defaults or argc/argv[] calls.

Note: If you are using the CPAINT frontend and have passed an array or multibyte character data, the CPAINT

backend will automatically convert the data into the proper format for your function. There is nothing else you needto do.

Note: It is extremely wise to sanitize your data when you receive it, especially if you’re inserting data into a

database. Since every application is different, CPAINT does not manipulate the data beyond converting it into the

proper format for your function.

Building Simple Responses

Normally, you would be able to return data from a function with a simple return call. However, since yourfunction could be used outside of the scope of CPAINT, we have implemented methods that can be used to return

both simple and complex (such as XML or JSON) data to the frontend with ease.

To return a simple response, such as plain-text, pre-formatted HTML, or even binary data to the frontend, you simply

need to replace your return call with a call to the set_data method of the cpaint object.

Page 37: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 37/45

The CPAINT Handbook

32

function validate_user($username, $password) {

// import the cpaint object

global $cp;

// validation code here

$validated = ‘good’;

$cp->set_data($validated);

// optional, if returning to another function

return($validated);

}

We meant it when we said simple! Once this function sets the data and completes, the data (in this case, the string

‘good’) is returned to the frontend and execution stops.

In the majority of cases, this is all you really need to do. But, if you’re going to be returning multiple pieces of data,

rather than coming up with your own scheme and separating the data back out on the frontend, you can use a more

complex method that will adapt to what the frontend has requested.

Building Complex Responses

Simple is good in most cases. But when it comes to returning multiple values to the frontend, it could be difficult.

The cpaint backend object implements another object on the backend called cpaint_node. Instances of this object

can be used to build more complex results.

The major advantage to using the cpaint_node object over building your own string, whether it is a simple string,

XML, or JSON, is the fact that when the cpaint return_data method is called, this object is automatically converted

into the format the frontend has requested (either plain-text, XML, or JSON). By default, the cpaint backend object

creates a single instance of the cpaint_node object, called the basenode. Essentially, the basenode is a top-level tag

(in the case of XML responses) or the object name (in the case of JSON responses). The basenode can be accessed

directly through the object instance.

[edit: the paragraph above is not very clear in some way, I can’t exactly name it]

The basenode is also used when the frontend requests plain-text, however no node names or attributes are sent to the

frontend.

Note: If you don’t change the name of the basenode, it will be called ‘ajaxResponse’.

cpaint_node Methods

The cpaint_node object method implements a number of methods for easily building complex results.

Page 38: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 38/45

The CPAINT Handbook

33

This method is used to add a subnode to an existing node, including the basenode. The name of the basenode is

required as the first parameter and an optional parameter for setting an id attribute. Nodenames can repeat, with or

without specifying the id attribute.

add_node

Note: If using PHP4, make sure when you perform the assignment to the existing node that you do so by reference,

otherwise the new node instance will be ‘disconnected’ from it’s parent node.

Example:

$new_node = &$cp->add_node(‘new’);

/* the XML now looks like:

<ajaxResponse>

<new>

</new>

</ajaxResponse>

*/

$new_node2 = &$cp->add_node(‘new’);

/* the XML now looks like:

<ajaxResponse>

<new>

</new>

<new>

</new>

</ajaxResponse>

*/

$new_child = &$new_node->add_node(‘child’, 1);

/*

<ajaxResponse>

<new>

<child id=”1”>

</child>

</new>

<new>

</new>

</ajaxResponse>

*/

This method sets the character data contained within the node.

set_data

Example:

$cp->set_data(“hello”);

/* XML:

<ajaxResponse>

hello

</ajaxResponse>

*/

Page 39: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 39/45

Page 40: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 40/45

The CPAINT Handbook

35

This will return the name of the node.

get_name

Example:

$cp->set_name(“response-data”);

// prints “response-data”

print($cp->get_name());

Complex Response Example

This example shows how to build a complex result, using multiple nodes.

function search_users($searchCriteria) {

// import the cpaint object

global $cp;

// change the basenode name

$cp->set_name(“users”);

// sanitize the data

// perform a database query

// loop through the results

for ($i = 0; $i < $resultCount; $i++) {

$newUserResult[$i] =

&$cp->add_node(“user”, $i+1);

$newUserResult[$i]->set_data($username);}

return;

}

/* Sample XML data for the above code:

<users>

<user id=”1”>

Paul

</user>

<user id=”2”>

Dominique

</user>

<user id=”3”>

Michelle

</user><user id=”4”>

Britta

</user>

</users>

*/

Page 41: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 41/45

The CPAINT Handbook

36

 

Page 42: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 42/45

The CPAINT Handbook

37

 Appendix

Arbitrary Character Sets

CPAINT is fully UTF-8 compliant. Whether you use ISO-8859-1 or more complex character sets like hebrew, arabic,

russian or japanese, CPAINT will support them. This means you don't have to worry about character conversion.

However, you should make sure that the page uses the correct Content-type meta tag in order for characters to

appear properly.

The frontend works in UTF-8 data wherever possible and will obey the Content-type everywhere else. This means

that:

Frontend

•  data sent to the CPAINT backend will be submitted as UTF-8.

•  data from the CPAINT backend will be converted into UTF-8.

The CPAINT backend works slightly different in every implementation due to language specifics.

Backend

For PHP this means that:

•  By default it assumes the character set to be UTF-8.

•  If another character set is used CPAINT must be told so in the start method.

•  CPAINT will make use of the iconv library to convert backend data to UTF-8 before sending it to the

frontend wherever possible.

If iconv is not installed:

• If the character set is ISO-8859-1, utf8_encode() will be utilized.

•  If neither is the case, data will be sent as-is.

•  The same logic is applied to incoming frontend data (iconv, utf8_decode(), as-is).

•  In any case the correct Content-type will be sent.

Page 43: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 43/45

The CPAINT Handbook

38

All backend implementations convert non-printable characters 0x00 - 0x20 as well as XML-sensitive characters & < >

to representations safe for transmission as XML or plaintext and processing by the XMLHTTP (Request) connection

object.

In the CPAINT frontend these representations are converted back to their original characters before the data is

handed to the frontend application.

It is your responsibility as developer to determine the correct character encoding used by your backend applications

and databases and feed that information to the CPAINT backend. Faulty encodings will in most cases lead to

incorrect incoming / outgoing data, even to crashes of the XMLHTTP object in MSIE sometimes the reasons to which

are both quite hard to debug and eliminate.

Backend Framework Encodings

CPAINT Backend Protocol

All v2.x releases of CPAINT implement a simple, common backend protocol. We are documenting it here if you

want to access backend scripts that utilize CPAINT with a non-CPAINT frontend. All API parameters can be passed

in via HTTP GET or POST.

This is a special parameter that takes no additional data and must be called independently of all other API

parameters. It simply returns a formatted string that specifies the version of CPAINT being utilized on the backend,

which backend scripting language is being utilized and its version number.

api_query

Example:

http://cpaint.net/examples/ping/ping.php?api_query

Returns: CPAINT v2.0.3/PHP v5.1.2

Format of the string and meanings:

CPAINT v[major].[minor].[revision]/[language] v[version]

•  major = the major version number (ie: 2)

•  minor = the minor version number (ie: 0)

•  revision = the revision or release number (ie: 0)

•  language = the scripting language used (ie: ASP-VBscript)

Page 44: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 44/45

The CPAINT Handbook

39

•  version = the version information of the language in use

This parameter specifies which function or method to execute on the backend. There can only be one function

specified per request at this time. The function must be ‘registered’ with the backend otherwise the request will be

ignored (see the section on backend implementation for details). The function name is case-sensitive.

cpaint_function

Example:

/ping/ping.php?cpaint_function=ping

This parameter tells the backend the format of the response. Only one response type can be sent per request.

Possible values are:

cpaint_response_type

•  TEXT

The backend will send a plain-text response. Used best for returning HTML, non-complex values, or other

data formats not natively supported by CPAINT.

•   JSON

The backend will return a JSON formatted string that will be evaluated to create a native JavaScript object

within the CPAINT frontend.

•  OBJECT, E4X, XML

All of these values will return identical XML from the backend. If you aren’t using the CPAINT frontend, it

will not matter which one of these you use at this time – the data and format is identical.

Example:

/ping/ping.php?cpaint_response_type=XML

This parameter can be used multiple times to pass data to the backend function. Although brackets appended to a

variable name are typically only used by PHP scripts, all scripts implemented with the CPAINT backend expect them

(and the brackets will be handled appropriately). The values passed in must be in the same order that the backend

function expects.

cpaint_argument[]

Example:

Page 45: The CPAINT Handbook Edited

8/14/2019 The CPAINT Handbook Edited

http://slidepdf.com/reader/full/the-cpaint-handbook-edited 45/45

The CPAINT Handbook

/ping/ping.php?cpaint_argument[]=param1

&cpaint_argument[]=param2

In the above example the backend function will receive the data ‘param1’ in the first parameter and ‘param2’ in the

second parameter.

There is no hard limit on the number of arguments that can be passed in at one time, however there are theoretical

limits that vary depending on the backend scripting language and what method is used to call the backend script

(GET vs. POST).

API Reference

The latest copy of the CPAINT API reference for both frontend and backend objects can be found at

http://cpaint.net/doc/ .