About This Document
Firstly – thanks for choosing WebConnect! We’ve worked hard to create a solid, robust platform with powerful and diverse features, and we think you’re going to love it.
This document discusses the Netfira WebConnect Library.
It is intended for developers who are integrating WebConnect into new or existing e-commerce software.
Before reading this, we strongly recommend you familiarise yourself with the Netfira platform. You will also need an intermediate understanding of PHP.
This document has a reasonable amount of ground to cover, so don’t worry if some introductory concepts don’t make sense. Everything is explained in turn.
We expect this document to serve primarily as reference material; our case-study tutorials are the fastest, easiest ways to learn WebConnect.
Happy coding!
– The WebConnect Team.
WebConnect:About
Netfira is a family of software packages that connect many different kinds of buying and selling platforms together with their operators’ accounting systems.
WebConnect is the web component of our software family. It enables online shops to be managed directly from an accounting package such as QuickBooks, MYOB, SAP, Accpac or Ostendo.
Data Transfer
WebConnect has several distinct data transfer functions.
Products:About
WebConnect keeps the products in an online store up-to-date based on information in the accounting system, including prices, tax, stock levels, descriptions, pictures, attachments, and any other information available in that system.
WebConnect can also transfer catalogues and organise products into categories.
Buyers:About
WebConnect can maintain an online customer database using an accounting package’s client list. Details including names and companies, email addresses, phone numbers, billing and shipping information, login passwords, product restrictions and any other information available in that system.
Orders:About
WebConnect collects orders placed on an online store and inserts them into the connected accounting package as sales orders. The orders can be assigned to one of the customers WebConnect transferred to the store, and should consist of inventory items transferred by WebConnect.
WebConnect Library:About
The Netfira Seller desktop application, which runs on the merchant’s computer and integrates with their accounting package, communicates with web servers via the WebConnect PHP library.
The WebConnect PHP library is a single, obfuscated PHP file (webconnect.php). This is the file you will be working with. It has two primary functions:
End Point
Functions:End Point
Netfira’s desktop application communicates directly with the WebConnect PHP file on any PHP-enabled server via HTTP.
The WebConnect PHP file acts as a secure intermediary between Netfira’s desktop application and your web server’s local database. The file has an editable portion that allows you to configure database settings, as well as other configuration options we’ll explore a little later on.
Functions:Code Library
When you include the WebConnect PHP file in your application, it provides methods to:
Access inventory and customer data stored in WebConnect’s data tables.
Send orders back to the merchant.
Retrieve per-customer product information from the merchant.
The WebConnect PHP file also contains JavaScript libraries that provide interfaces for server administrators to:
Pair inventory and customer records from Netfira with records in existing e-commerce systems.
Copy inventory and customer records from Netfira into existing e-commerce systems.
Functions:Other
The WebConnect PHP file has several other functions that will be discussed in turn throughout this document. Briefly, some of those functions are:
Opening the WebConnect PHP file in a web browser displays a health-check of WebConnect’s configuration, and will tell you if your server is missing any features. It also displays a summary of the information in WebConnect’s data tables.
Opening the WebConnect PHP file in a web browser with a special query string displays the WebConnect TestCentre application (discussed later).
Running the WebConnect PHP file from a command-line displays WebConnect’s complete data table schema.
Development Strategies
The Netfira WebConnect architecture offers a few different layers of abstraction for software developers. It’s important to choose the right approach to your development to ensure your code stays effective and maintainable.
Your WebConnect project will most likely fall into one of two distinct categories.
Development Strategies:For Custom Websites
When you build an e-commerce site from scratch, the logical place to start is to design your database.
WebConnect saves you this step by automatically creating a database and tables when the Netfira desktop software first uploads its data. These data tables are simple, well-structured relational tables which can make a great foundation for your website.
Using the WebConnect tables to drive your website will ensure your product and customer information stay up to date with absolutely no coding. You can send orders back to the merchant simply by inserting them into WebConnect’s orders table.
Data in WebConnect’s tables can be accessed directly via SQL, or by using the data abstraction layer provided by the WebConnect library. WebConnect’s data abstraction layer provides easy methods to retrieve data records as lists or by IDs, or based on relations with other records, such as listing all products in a specific category.
Section 5 explains how to interact with WebConnect’s data tables directly.
Development Strategies:For Plug-ins
Building a plug-in for an existing e-commerce system will most often require you to merge the data you receive from Netfira into that system’s own data tables, and also detect when an order is placed (through code hooks, event handlers or similar devices) and pass that order’s details back to Netfira.
You will probably also want WebConnect to share the e-commerce system’s database connection, file storage area and other common resources.
The WebConnect library provides methods to achieve all of these functions with relative easy.
The WebConnect PHP file has an area that allows you to specify configuration options, or better yet, include your own configuration file. This file will allow you to:
Configure WebConnect’s database type, host, username, password, database and table name prefix.
Set the password the merchant’s desktop software will use to exchange data with WebConnect.
Register event handlers, which are PHP function you can write to handle specific events, such as receiving customer information, or adding a product to a category.
Register data providers, which are PHP functions you can write to give WebConnect’s user interfaces access to data in your e-commerce system.
Classes: Overview
WebConnect’s PHP library includes these classes:
| Class | Type | Description |
|---|---|---|
|
|
Static |
The namespace of most static WebConnect methods, constants and variables. Because WebConnect supports PHP 5.2, a static class is used instead of a namespace. |
|
|
Singleton |
Methods to retrieve (and update) data from
WebConnect’s data tables. Instantiated as |
|
|
Singleton |
Methods to retrieve data from Netfira
Seller’s API. Instantiated as |
|
|
Singleton |
Methods to provide WebConnect with
external customer and inventory data for pairing (aka mapping) purposes.
Instantiated as |
|
|
Instance |
Represents a record in one of WebConnect’s data tables. |
|
|
Instance |
Represents an order to be sent to Netfira Seller. |
|
|
Instance |
Represents custom product information for a specific buyer. |
|
|
Instance |
Represents a 16-byte globally unique identifier. Used by WebConnect for password hashes and file checksums. |
Configuration
You can configure WebConnect at runtime by assigning values to the following variables. The WebConnect PHP file is distributed with default values assigned to each variable, which you can override, either directly in the WebConnect PHP file, or using an include.
Classes:Netfira
| Variable | Description |
|---|---|
|
|
The password Netfira Seller will use to transfer data to and from WebConnect. |
|
|
The type of database WebConnect will use.
Currently the only valid value is |
|
|
Database host name. |
|
|
Database user name. User must have these
privileges: |
|
|
Database password. |
|
|
Name of database to use. WebConnect will attempt to create the database if it doesn’t exist. |
|
|
Prefix for names of tables created by WebConnect. Default value is |
|
|
Directory in which images and product attachments should be stored, relative to the WebConnect PHP file. Must be fully readable and writable by PHP. If it doesn’t exist, WebConnect will attempt to create it. Default value is |
|
|
If your WebConnect data tables are supporting multiple stores, set this variable to a non-null scalar value to tell WebConnect which store the current operation pertains to. It’s important to have this value set before you first run WebConnect, as a non-null value will cause your tables to be created with an extra column (“storeId”) in their primary keys. If you accidentally run WebConnect without setting this value, just delete your tables and they’ll be recreated on the next run. Default value is |
|
|
Setting this value to In single-store mode, columns will be
added to your data tables as In multi-store mode, custom field values
will be added to a separate When this value is Default value is |
|
|
The time zone in which WebConnect should
operate. If left as Default value is |
|
|
File to which WebConnect should write log information. If left as You should only set this variable in a testing environment. Logging in a production environment may degrade performance and/or consume excessive disk space. Default value is |
|
|
If set to an integer value, WebConnect’s log file will be truncated to this many bytes. A Default value is |
|
|
Netfira Seller uses long-polling to receive orders from WebConnect. This value determines how long PHP will wait before timing out HTTP requests for orders (in seconds). High values will generally yield greater efficiency, but may cause problems on some connections. Lower values will be more reliable, but will also increase HTTP traffic. Netfira Seller has its own internal timeout for this function, which defaults to 45 seconds. WebConnect’s timeout should always be greater than Seller’s. Default value is |
|
|
When Netfira Seller requests orders, if Default value is |
|
|
Memcached:Enabling for Order Polling If the PHP Setting this value to a unique string will disable database polling in favour of shared memory polling. This feature is included for performance
optimisation. If you don’t understand this concept, don’t worry; leave it as Default value is |
require_once()Invocation Order
If you intend to use the WebConnect library in your software (to place orders, query the Seller’s API for custom product info, etc.), you’ll need to ensure your configuration is performed properly without re-declaring anything.
Here’s an example of a typical PHP script structure layout that allows your software to invoke WebConnect, and also allows WebConnect to invoke your software when needed.
Unless you have a pressing reason not to, we strongly advise you follow this example.
| File | Purpose |
|---|---|
|
|
The WebConnect PHP library. This file acts as the main script for Netfira Seller’s sync operations, and also as an include for the main application. |
|
|
WebConnect’s configuration script. This
file is included by |
|
|
Your application’s initialisation script.
This file can include |
This file contains the WebConnect PHP library in an obfuscated form. It references webconnect.config.php, which contains vital configuration options.
You should not edit this file.
<?php Netfira(); // Version 1.5.412
require_once('webconnect.config.php');
function Netfira(){$Netfira=create_function(null,gzinflate(base64_decode("
1L0JeGRVlTj+he5mKXZEQBF8Karz6iWVSlV6oan0S7o6qe6UZDOpAG0qVF6qXiWPrlRV16ts3R1t
dhFcmFHQERRcwXHBDcG1B1QYFcUFxQFcwR0VZ1QcZ4b/PXd7922VNOLM768fnXp3Offcc88999xz
...This file can rely on data made available by
your application’s initialization script. Note that if we’d used require() or include() instead of
require_once(), we’d have an infinite
loop of inclusion. The use of require_once()
ensures clean invocation regardless of which script runs first.
<?php
require_once('bootstrap.php');
Netfira::$dbHost = $myDbServer;
Netfira::$dbUser = $myDbUserName;
Netfira::$dbPass = $myDbPassword;
...The purpose of these examples is only to demonstrate how each script should invoke the others. You will need to assign more configuration variables than shown in these examples.
This is the main initialisation script for
your application, so it will probably have a different name, and have a very
different layout. The important parts are that it references webconnect.php, and that it does so after exposing data needed by webconnect.config.php.
<?php // My Application
$myDbServer = 'localhost';
$myDbServer = 'localhost';
$myDbUserName = 'php';
$myDbPassword = 'abc123';
// Invoke or declare other variables
require_once('webconnect.php');
...
Data Access
The Netfira::$db
object provides methods for querying WebConnect’s data tables. Most queries
return either a single instance of NFRecord,
or an array of NFRecord instances.
Classes:NFRecord
NFRecord is a
subclass of PHP’s ArrayObject class.
An instance of NFRecord represents
a single record in WebConnect’s data tables.
NFRecord provides a
few distinct advantages over regular arrays:
Values can be accessed either as array offsets or object properties, depending on your taste as a developer. The following are therefore identical:
$myRecord['myKey']$myRecord->myKeyKeys are case-insensitive. The following are therefore identical:
$myRecord['myKey']$myRecord['MyKeY']Attempting to retrieve a non-existent key
returns null and does not
raise an error.
Casting an instance as a string returns its ID (primary key value).
NFRecord instances
also provide methods that supply additional information about a record:
Classes:NFRecord:Methods
| Method | Description |
|---|---|
|
|
Returns the type of record this instance
represents as a string, such as |
|
|
Returns the record’s primary key value.
For example, calling this method on an |
|
|
Returns |
|
|
Use this method to pair a record in WebConnect’s data tables with a record in an external data set, by passing an external ID as its only argument. You can also call this method with no arguments to un-pair the record. Pairing is discussed later in this document. |
|
|
Get the ID of the external record paired with this record. Returns WebConnect records can be paired with multiple external records. In such cases, this method returns the first paired external ID found in the database. |
|
Get the IDs of all external records paired with this record, in an array. Returns an empty array if the record is not paired. |
|
|
If this record is part of a tree structure
(for example, if it is a |
|
|
If this record is part of a tree structure
(for example, if it is a |
|
|
If this record represents a file in the
file system (such as an |
In addition to the methods above, some types of records provide additional methods for retrieving related records. See below for details.
Products:About
Information about inventory items is stored
in the Products table as Product records.
Product records include the following values:
| Key | Description |
|---|---|
|
|
The product’s unique ID and primary key in WebConnect’s data tables. This will usually be the same as the product’s part number, unless provided by a system that allows multiple products to share a single part number. |
|
|
The product’s part number. Often, but not always, unique. |
|
|
The product’s short description (or product name). |
|
|
The product’s long description, either as plain text or HTML (depending on the Seller’s accounting package). |
|
|
The product’s category. This value is
unrelated to the catalogue tree and |
|
|
A numeric boolean that defines whether
this product should be visible online. A value of |
|
|
Floating-point value of this item’s unit price, excluding tax. |
|
|
Floating-point value of this item’s tax, if applicable. |
|
|
Number of units currently held in stock by the Seller. May be positive, zero, or negative, and/or fractional for some types of inventory. |
|
|
Weight of a single unit in grams. |
|
|
Length of a single unit in millimetres. |
|
|
Width of a single unit in millimetres. |
|
|
Height of a single unit in millimetres. |
Product records also provide the following methods for retrieving related records:
| Method | Description |
|---|---|
|
|
Return an array of |
|
|
Return an array of |
|
|
Return an array of |
|
|
Return an array of |
Products:Retrieving
You can retrieve a single product record by
its ID using the Netfira::$db->getProduct()
method:
$myProduct = Netfira::$db->getProduct('peanut');
echo $myProduct->productId; // echoes 'peanut'The Netfira::$db->getProduct()
method will return null if no product
exists with the given ID.
Products:Retrieving:Multiple
You can retrieve an array of records of
every item in your inventory by calling the Netfira::$db->getProducts() method:
$myProducts = Netfira::$db->getProducts(); echo count($myProduct); // echoes number of products in your inventory
Such a call may be prohibitively inefficient
if you have an especially large inventory. The Netfira::$db->getProducts() method accepts an optional SQL
WHERE clause which you can use to narrow down your result set:
$myProducts = Netfira::$db->getProducts('unitPrice >= 100');The above example demonstrates retrieving all products of $100 and over. Be careful using this technique, as it may expose your application to SQL injection attacks.
Products:Retrieving:By Category
You can retrieve all products in a given
category by first retrieving that category’s record, then calling its getProducts() method:
$myCategory = Netfira::$db->getCategory('legumes');
$myProducts = $myCategory->getProducts();
var_dump($myProduct); // display a list of leguminous productsYou can also chain such calls together, as
long as you know the first call won’t return null:
$myProducts = Netfira::$db->getCategory('legumes')->getProducts();Categories:About
Some Netfira Seller systems upload a product
catalogue tree. Information about categories in these catalogues is storied in
the Categories table as Category records.
Category records include the following values:
| Key | Description |
|---|---|
|
|
The category’s unique ID and primary key in WebConnect’s data tables. |
|
|
The category’s friendly (display) name. |
|
|
The ID of the category’s parent category.
Will evaluate as |
Category records also provide a getProducts() method for retrieving related products.
Categories:Retrieving
You can retrieve a single category record by
its ID using theNetfira::$db->getCategory() method:
$myCategory = Netfira::$db->getCategory('legumes');
echo $myCategory->categoryId; // echoes 'legumes'The Netfira::$db->getCategory()
method will return null if no category
exists with the given ID.
Categories:Retrieving:Multiple
You can retrieve an array of records of
every category in your catalogue(s) by calling the Netfira::$db->getCategories() method:
$myCategories = Netfira::$db->getCategories(); echo count($myCategories); // echoes number of categories in your catalogue
Such a call may be prohibitively inefficient
if you have an especially large catalogue. The Netfira::$db->getCategories() method accepts an optional
SQL WHERE clause which you can use to narrow down your result set:
$myCategories = Netfira::$db->getCategories('not coalesce(parentId, 0)');The above example demonstrates retrieving all categories without parents. Be careful using this technique, as it may expose your application to SQL injection attacks.
Categories:Retrieving:Parents
Categories:Retrieving:Subcategories
Category records have a special method that allows you to get an array of its subcategories without using SQL:
$subCategories = $myCategory->children(); // subcategories of $myCategory
The complimentary method to children() is parent(), which returns a category’s parent category:
$myCategory = $subCategories[0]->parent(); // back where we started
You can also chain the children() method with the getCategory() method:
$subCategories = Netfira::$db->getCategory('legumes')->children();Finally, if you know the index of the sub-category you want, you can retrieve it by index:
$firstChild = $myCategory->children(0); // first subcategory of $myCategory $lastChild = $myCategory->children(-1); // last subcategory of $myCategory
Images:About
Information about product images is stored
in the Images table as Image records.
Image records include the following values:
| Key | Description |
|---|---|
|
|
The image’s unique file name and primary key in WebConnect’s data tables. |
|
|
A raw MD5 hash of the image, stored as a
16-byte binary field (or blob). This field returns an |
Product images are stored as files by their
original filenames, in a sub-directory of the directory specified in Netfira::$fileStore. Image records include a path() method that returns the image file’s path, relative to
the WebConnect PHP file.
Images:Retrieving
You can retrieve a single image record by
its file name using the Netfira::$db->getImage() method:
$myImage = Netfira::$db->getImage('peanuts.jpg');
echo $myImage->fileName; // echoes 'peanuts.jpg'The Netfira::$db->getImage()
method will return null if no image
exists with the given file name.
Images:Retrieving:Multiple
You can retrieve an array of records of
every image in your system by calling the Netfira::$db->getImages()
method:
$myImages = Netfira::$db->getImages(); echo count($myImages); // echoes number of images in your system
Such a call may be prohibitively inefficient
if you have a large number of images. The Netfira::$db->getImages()
method accepts an optional SQL WHERE clause which you can use to narrow down
your result set:
$myImages = Netfira::$db->getImages('fileName like "%.gif"');The above example demonstrates retrieving
all images with .gif extensions. Be
careful using this technique, as it may expose your application to SQL
injection attacks.
Images:Retrieving:For Specific Products
You can retrieve an array of records of
images linked to a specific product by calling the product record’s getImages() method:
$myProduct = Netfira::$db->getProduct('peanut');
$myImages = $myProduct->getImages(); // returns an array of Image recordsIf no images are linked to the product, an empty array will be returned.
Images:Working with Image Data
If you need direct access to image data (for
example, to generate thumbnails), use the image record’s path() method:
$myImage = Netfira::$db->getImage('peanuts.jpg'); // get the image record
$myImagePath = $myImage->path(); // get the image path
$myImageSize = getimagesize($myImagePath); // get the image dimensions
var_dump($myImageSize); // displays the image dimensionsBecause path() returns a relative path, you can safely use its return
value as a URI (for example, in an <img>
tag’s src attribute). The
exception is when you run WebConnect on Windows, in which case path() will contain backslashes rather than forward-slashes.
Attachments:About
Information about product file attachments
is stored in the Attachments table as
Attachment records.
Attachment records include the following values:
| Key | Description |
|---|---|
|
|
The attachment’s unique file name and primary key in WebConnect’s data tables. |
|
|
A raw MD5 hash of the file, stored as a
16-byte binary field (or blob). This field returns an |
Product file attachments are stored by their
original filenames, in a sub-directory of the directory specified in Netfira::$fileStore. Attachment records include a path() method that returns the attachment file’s path,
relative to the WebConnect PHP file.
Attachments:Retrieving
You can retrieve a single attachment record
by its file name using the Netfira::$db->getAttachment() method:
$myAttachment = Netfira::$db->getAttachment('nutrition.pdf');
echo $myAttachment->fileName; // echoes 'nutrition.pdf'The Netfira::$db->getAttachment()
method will return null if no
attachment exists with the given file name.
Attachments:Retrieving:Multiple
You can retrieve an array of records of
every attachment in your system by calling the Netfira::$db->getAttachments() method:
$myAttachments = Netfira::$db->getAttachments(); echo count($myAttachments); // echoes number of attachments in your system
Such a call may be prohibitively inefficient
if you have a large number of attachments in your system. The Netfira::$db->getAttachments() method
accepts an optional SQL WHERE clause which you can use to narrow down your
result set:
$myAttachments = Netfira::$db->getAttachments('fileName like "%.pdf"');The above example demonstrates retrieving
all attachments with .pdf extensions. Be
careful using this technique, as it may expose your application to SQL
injection attacks.
Attachments:Retrieving:For as Specific Product
You can retrieve an array of records of attachments
linked to a specific product by calling the product record’s getAttachments() method:
$myProduct = Netfira::$db->getProduct('peanut');
$myAttachments = $myProduct->getAttachments();
// returns an array of Attachment recordsIf no attachments are linked to the product, an empty array will be returned.
Attachments:Working With Attachment Data
If you need direct access to attachment data
(for example, to display file sizes), use the attachment record’s path() method:
$myAttachment = Netfira::$db->getAttachment('nutrition.pdf'); // the record
$myAttachmentPath = $myAttachment->path(); // the file path
$myAttachmentSize = filesize($myAttachmentPath); // the file size
echo $myAttachmentSize; // displays the file’s sizeBecause path() returns a relative path, you can safely use its return
value as a URI (for example, in an <a>
tag’s href attribute). The
exception is when you run WebConnect on Windows, in which case path() will contain backslashes rather than forward-slashes.
Buyers:About
Information about buyers is stored in the Buyers table as Buyer records.
Buyer records include the following values:
| Key | Description |
|---|---|
|
|
The buyer’s unique NF Code and primary key in WebConnect’s data tables. |
|
|
The buyer’s ID as it appears in the
seller’s accounting package. This field is almost always unique, but is not
part of the table’s primary key and shouldn’t be confused with |
|
|
A raw MD5 hash of the buyer’s PIN code (or
password), stored as a 16-byte binary field (or blob). This field returns an |
|
|
A boolean integer (0 or 1) of whether this buyer has website access. Buyers with this fields set to 0 should not be allowed to log in. |
|
|
A Boolean integer (0 or 1) of whether this
buyer should be restricted by buyer/product relations. If this field is set
to 1, this buyer is permitted only to search, view and order products
returned by its |
|
|
The buyer’s name. |
|
|
Name of the buyer’s contact person, if the buyer is a company. |
|
|
The buyer’s email address. This field may not be unique, and may be blank or invalid. |
|
|
The buyer’s phone number (if available). |
|
|
The buyer’s fax number (if available). |
|
|
Each of these fields stores a component of the buyer’s billing address as a string. |
|
|
The country component of the buyer’s
billing address, as a two-letter alpha2 country code (for example, |
|
|
Each of these fields stores a component of the buyer’s shipping address as a string. |
|
|
The country component of the buyer’s
shipping address, as a two-letter alpha2 country code (for example, |
Buyer records also include a getProducts() method for retrieving a list of products the buyer is explicitly allowed to buy.
Buyers:Retrieving
You can retrieve a single buyer record by their
NF code using theNetfira::$db->getBuyer() method:
$myBuyer = Netfira::$db->getBuyer('NF12345');
echo $myBuyer->nfCode; // echoes 'NF12345'The Netfira::$db->getBuyer()
method will return null if no buyer
exists with the given NF code.
Buyers:Retrieving:Multiple
You can retrieve an array of records of
every buyer in your client list by calling the Netfira::$db->getBuyers() method:
$myBuyers = Netfira::$db->getBuyers(); echo count($myBuyer); // echoes number of buyers in your client list
Such a call may be prohibitively inefficient
if you have an especially large client list. The Netfira::$db->getBuyers() method accepts an optional SQL
WHERE clause which you can use to narrow down your result set:
$myBuyers = Netfira::$db->getBuyers('email like "%.au"');The above example demonstrates retrieving all buyers with email addresses ending in “.au”. Be careful using this technique, as it may expose your application to SQL injection attacks.
Buyers:Authenticating
Authentication
Netfira Seller specifies that buyers should authenticate using an NF code and PIN number. A typically login form could be processed as follows:
// retrieve buyer record from login:
$buyer = Netfira::$db->getBuyer($_POST['username']);
// check that a buyer was found:
if($buyer)
{
// check the password matches:
if($buyer->pin->isHashOf($_POST['password']))
{
// login OK
}
else
{
// bad password
}
}
else
{
// buyer does not exist
}The methods above handle user input
sanitation, so it is safe to pass values from $_POST directly to these methods.
Orders:About
Orders are stored in the Orders table as Order records.
Line items are stored in the OrderLines table as OrderLine
records, and include an orderId field that
binds them to an order.
When you want to insert a new order into
WebConnect’s data tables for transport back to the seller’s machine, there is a
special NFOrder class you
can use instead of the regular NFRecord class.
Order records include the following values:
| Key | Description |
|---|---|
|
|
The order’s unique ID and primary key in WebConnect’s data tables. |
|
|
A globally unique identifier for this
order, randomly generated when Seller downloads the order, and used by Seller
to ensure orders are not accidentally duplicated in the event of connection
drop-outs. Stored as a 16-byte binary string (or blob). This field returns an
|
|
|
The NF code of the buyer who placed this order. May be blank if the order was placed anonymously. |
|
|
The client ID of the buyer who placed this order. May be blank if the order was placed anonymously. |
|
|
The buyer’s name. |
|
|
Name of the buyer’s contact person, if the buyer is a company. |
|
|
The buyer’s email address. This field may not be unique, and may be blank or invalid. |
|
|
The buyer’s phone number (if available). |
|
|
The buyer’s fax number (if available). |
|
|
Each of these fields stores a component of the buyer’s billing address as a string. |
|
|
The country component of the buyer’s
billing address, as a two-letter alpha2 country code (for example, |
|
|
Each of these fields stores a component of the buyer’s shipping address as a string. |
|
|
The country component of the buyer’s
shipping address, as a two-letter alpha2 country code (for example, |
|
|
Used internally by WebConnect to track which orders are ready to send to seller, and which have already been sent. |
|
|
The buyer’s reference for this order (i.e. their purchase order number). |
|
|
The three-letter ISO 4217 code of the
currency represented by the figures in this order (for example, |
|
|
Shipping method (as a string). May be |
|
|
Shipping charge (if any) as a floating-point number, excluding tax. |
|
|
Tax on shipping (if any) as a floating-point number. |
|
|
Shipping account name as a string. May be |
|
|
Shipping account password as a string. May
be |
|
|
Chosen method of payment for the order.
May be |
|
|
A boolean integer (1 or 0) indicating whether payment for this order was received at the time it was placed. |
|
|
Reference from the organisation (bank, gateway, PayPal etc) who processed the payment. |
|
|
Error code (if available) from the payment processor. |
|
|
Error message (if available) from the payment processor. |
|
|
An optional comment attached to the order during checkout. |
Order records also have a special lines() method which returns an array of OrderLine records bound to that order.
Orders:Retrieving
You can retrieve a single order record by
its ID using the Netfira::$db->getOrder()
method:
$myOrder = Netfira::$db->getOrder(80085); echo $myOrder->orderId; // echoes '80085'
The Netfira::$db->getOrder()
method will return null if no order
exists with the given ID.
Orders:Retrieving:Multiple
You can retrieve an array of records of
every order ever placed by calling the Netfira::$db->getOrders()
method:
$myOrders = Netfira::$db->getOrders(); echo count($myOrder); // echoes number of orders placed
Such a call may be prohibitively inefficient
if you have an especially long order history. The Netfira::$db->getOrders() method accepts an optional SQL
WHERE clause which you can use to narrow down your result set:
$myOrders = Netfira::$db->getOrders('nfCode = "NF12345"');The above example demonstrates retrieving all orders placed by buyer “NF12345”. Be careful using this technique, as it may expose your application to SQL injection attacks.
Orders:Retrieving:Line Items
Line Items:Retrieving
Order records have a special method lines() which returns an array of OrderLine records bound to that order.
$myOrder = Netfira::$db->getOrder(80085); $myOrderLines = $myOrder->lines(); // an array of OrderLine records
The lines()
method will return an empty array if no lines are bound to the order.
OrderLine records
include the following values::
Line Items:About
| Key | Description |
|---|---|
|
|
The line item’s unique ID and primary key in WebConnect’s data tables. |
|
|
The ID of the order to which the line item is bound. |
|
|
ID of the product on the line. |
|
|
Part number of the product on the line.
May be the same as |
|
|
Description of the item on the line as a string. |
|
|
Unit price of the item on the line as a floating-point number, excluding tax. |
|
|
Unit tax on the item on the line as a floating-point number. |
|
|
The line’s quantity as a floating-point number. May be fractional, zero or negative on some systems. |
|
|
An optional comment that may be attached to the line at check-out. |
Orders:Placing:Using the PHP Library
To place an order that WebConnect will send
back to the seller’s accounting system, create a new NFOrder instance:
Classes:NFOrder
$myOrder = new NFOrder();
You can also pass an array to the NFOrder constructor to initialize it:
$orderDetails = array(
'nfCode' => 'NF12345',
'comment' => 'Authority to leave'
);
$myOrder = new NFOrder($orderDetails);NFOrder instances
implement the ArrayAccess
interface, so you can assign order fields just as you would populate an array:
$myOrder['nfCode'] = 'NF12345'; $myOrder['comment'] = 'Authority to leave';
Unlike NFRecord
instances, NFOrder instance
values have case-sensitive keying, and cannot be accessed using object property
-> syntax.
Next, add line items to your order by
calling the order’s addLine() method,
which takes the following arguments:
Line Items:Adding to Orders:Using the PHP Library
| Argument | Required | Description |
|---|---|---|
|
|
Yes |
Either an |
|
|
No |
The line’s quantity. If omitted, the
default value is |
|
|
No |
Use this field to override the product’s
unit price. Default is |
|
|
No |
Use this field to override the product’s
unit tax. Default is |
|
|
No |
A string containing a comment to attach to the line. Default is an empty string. |
|
|
No |
Use this field to override the product’s
part number. Default is |
|
|
No |
Use this field to override the product’s
description. Default is |
For example:
// order for one peanut:
$myOrder->addLine('peanut');
// order for 50 roasted almonds with their regular price and tax:
$myOrder->addLine('almond', 50, null, null, 'roasted please');You can add information to your NFOrder instance in any order you like. Once all lines have
been added and fields have been set, call the place() method to send the order back to the seller’s
accounting system:
$myOrder->place();
The place()
method will populate the WebConnect data tables with the order information, and
if you are using the Memcache feature, set the Memcache key that informs the seller
an order is ready to download.
If you are writing a plug-in for an existing online store or e-commerce platform, you will probably need to maintain an external set of data tables by merging information from WebConnect’s data tables.
WebConnect has an in-built mechanism for “pairing” its internal records with your external records.
The examples below demonstrate pairing and un-pairing product records. However, the methods used are PHP magic methods, so the same method signatures can be used for any type of record, including products, categories, buyers and orders:
Netfira::$db->getExternalProducts($productId)
Netfira::$db->getExternalCategories($categoryId)
Netfira::$db->getExternalBuyers($nfCode)
Netfira::$db->getExternalOrders($orderId)
And:
Netfira::$db->getInternalProduct($externalProductId)
Netfira::$db->getInternalCategory($externalCategoryId)
Netfira::$db->getInternalBuyer($externalBuyerId)
Netfira::$db->getInternalOrder($externalOrderId)
Any WebConnect record can be paired with one
or more external IDs using the pairWith() method:
$myProduct = Netfira::$db->getProduct('peanut');
$myProduct->pairWith('nut65');You can pair with additional external IDs by
calling pairWith() repeatedly.
You can un-pair WebConnect records from
external records by calling pairWith() with no
arguments.
Once paired, you can look up pairings with either an internal or external ID.
$myProduct = Netfira::$db->getProduct('peanut');
echo $myProduct->externalId(); // echoes 'nut65';Or, if you think your record may be paired with multiple external records:
$externalIDs = Netfira::$db->getExternalProducts('peanut');
// returns an array of external IDsThe externalId()
method returns null if no external
ID has been paired with the record.
The getExternalProducts()
method returns an empty array if no external IDs have been paired with
the record.
$myProduct = Netfira::$db->getInternalProduct('nut65');
echo $myProduct->productId; // echoes 'peanut'The getInternalProduct()
method will return null if the given external
ID is not paired with any internal products.
WebConnect includes a number of lower-level data access methods. While the methods above provide all the functionality necessary to read from, and write to, WebConnect’s data tables, some routines can benefit from lower-level methods by saving on unnecessary database queries and memory allocation.
The standard method to retrieve all records
of one type associated with a record of another type is to call a method of an NFRecord instance, for example:
$myProducts = Netfira::$db->getCategory('legumes')->getProducts();This involves a potentially unnecessary query to the Categories table, which can be avoided by using the alternate method:
$myProductIDs = Netfira::$db->getProductsForCategory('legumes');This method returns an array of product IDs, instead of an array of product records.
The advantage of this method is that it only
employs a single SQL query, so it will execute much faster than the NFRecord::getProducts() method. You can use the results to
determine how many products are in the category, display just the first (or
last) product of the category, or combine it with methods like array_map() to perform custom batches of operations.
The Netfira::$db->getProductsForCategory()
method is one of many methods for retrieving IDs of related records. Others
include:
Netfira::$db->getImagesForProduct($productId)
Netfira::$db->getProductsForBuyer($nfCode)
Netfira::$db->getCategoriesForProduct($productId)
In fact, Netfira::$db->get[Plural]For[Single]() is a PHP magic
method, so you can use it for any set of related types.
Seller API
The Netfira Seller desktop application includes an API that allows WebConnect to request information from it directly. You can use the Seller API to access information not stored in WebConnect’s data tables, provided the seller’s computer is online.
Custom Product Info
Seller API:Custom Product Info
WebConnect can query the seller’s computer with a buyer’s NF code, and a list of product IDs and quantities, to retrieve custom product info for a specific buyer, including price, tax and stock level.
To retrieve custom product info, pass and NF
code and an associate array, containing product IDs as keys and quantities as
values, to theNetfira::$sellerApi->customProductInfo()
method.
$nfCode = 'NF12345'; // get price and stock info for this buyer
$products = array(
'peanut' => 60, // 60 peanuts
'walnut' => 1 // 1 walnut
);
$info = Netfira::$sellerApi->customProductInfo($nfCode, $products);If the query is successful in the example
above, $info will be an associative
array, containing product IDs as keys, and instances of NFProductInfo as values.
Each NFProductInfo
instance will have the following properties:
Classes:NFProductInfo
| Property | Type | Description |
|---|---|---|
|
|
Float |
Price of a single unit, excluding tax. |
|
|
Float |
Tax on a single unit. |
|
|
Float |
Number of units available for purchase. |
|
|
Float |
Quantity that must be purchased for this price to be valid. |
If WebConnect cannot connect to the seller’s
machine, $info will be an
empty array. If any product IDs are invalid or unavailable, those products will
be omitted.
Events
Sync Events > Events
When the seller makes changes to the data in their accounting software, Netfira Seller sends those changes to the WebConnect PHP file. WebConnect updates its data tables with the new information, and also raises an event to notify the connected software that something has changed. If you need to keep another database in sync with the WebConnect data tables, you can register handlers for WebConnect’s event, which can take data from WebConnect and use it however you like.
This section discusses how to register events, the various events WebConnect raises, and what information is passed to event handlers.
Most WebConnect events are concerned with
keeping a host application’s database in sync with WebConnect’s data. In our examples,
we’ll use members of a fictional class MyApp
to denote interaction with the host system.
Events:Event Handlers
An event handler is simply a function that WebConnect will call when an event occurs. It can be a regular (global) function, an instance method, static method or anything callable, such as PHP 5.3’s new lambda functions.
You can register an event handler by passing
it to the Netfira::addEventHandler()
method, along with one of the WebConnect event constants.
The following code demonstrates registering different types of methods as event handlers.
class MyClass {
public function myInstanceMethod()
{
// an instance method
}
public static function myStaticMethod()
{
// a static method
}
}
function myFunction()
{
// a global function
}
$myClassInstance = new MyClass();
// register a global function:
$handlerId = Netfira::addEventHandler(NF_RECEIVE_BUYER, 'myFunction');
// register an instance method:
$handlerId = Netfira::addEventHandler(
NF_PAIR_BUYER,
array($myClassInstance, 'myInstanceMethod')
);
// register a static method:
$handlerId = Netfira::addEventHandler(
NF_DELETE_BUYER,
array('MyClass', 'myStaticMethod')
);The Netfira::addEventHandler()
method accepts the same types of function descriptions for its second argument
as call_user_func() for
class methods (see PHP documentation for details).
You can only register event handlers after
they are declared; otherwise, WebConnect will throw an InvalidArgumentException.
To deregister an event handler, pass the ID
returned by Netfira::addEventHandler()
to Netfira::removeEventHandler():
Netfira::removeEventHandler($handlerId);
Events:General
NF_WILL_MAKE_CHANGESNone
Occurs when WebConnect is about to start making changes. You can use this event to temporarily alter the state of your store if necessary, such as locking certain features.
This will always be the first event to be raised during a sync request.
NF_DID_MAKE_CHANGESNone
Occurs when WebConnect has finished making
changes. You can use this event to restore the state of your store, such as
unlocking features locked by the NF_WILL_MAKE_CHANGES
event.
This will always be the last event to be raised
during a sync request, unless the request is unable to complete in the time
allowed, in which case another request will follow, including another NF_WILL_MAKE_CHANGES event.
Events:Products
Products:Events
NF_RECEIVE_PRODUCT| Type | Description |
|---|---|
|
|
The product being updated, with new values. |
Occurs when a product is inserted or updated.
function update_product($productId, NFRecord $newData)
{
// update my app’s data with the new data from WebConnect
$myProduct = MyApp::get_product($productId);
$myProduct->set_price($newData->unitPrice);
$myProduct->set_stock_level($newData->stock);
$myProduct->save();
}
function onReceiveProduct(NFRecord $product)
{
// if the product is paired with an external product, merge some data
if($externalId = $product->externalId())
{
update_product($externalId, $product);
}
}
Netfira::addEventHandler(NF_RECEIVE_PRODUCT, 'onReceiveProduct');NF_DELETE_PRODUCT| Type | Description |
|---|---|
|
|
The product being deleted. |
Occurs when a product is deleted.
function onDeleteProduct(NFRecord $product)
{
// if the product is paired with an external product, delete it
if($externalId = $product->externalId())
{
MyApp::delete_product($externalId);
}
}
Netfira::addEventHandler(NF_DELETE_PRODUCT, 'onDeleteProduct');NF_PURGE_PRODUCTSNone
Occurs when all products are deleted.
During a purge, if you have registered a
handler for NF_DELETE_PRODUCT,
each product will be deleted individually, with its own NF_DELETE_PRODUCT event.
NF_ADD_PRODUCT_TO_CATEGORY| Type | Description |
|---|---|
|
|
The product being added to the category. |
|
|
The category to which the product is being added. |
Occurs when a product is added to a category.
function onAddProductToCategory(NFRecord $product, NFRecord $category)
{
$productId = $product->externalId();
$categoryId = $category->externalId();
if($productId && $categoryId)
{
// add the product to the category in the linked system
MyApp::add_product_to_category($productId, $categoryId);
}
}
Netfira::addEventHandler(NF_ADD_PRODUCT_TO_CATEGORY,
'onAddProductToCategory');NF_REMOVE_PRODUCT_FROM_CATEGORY| Type | Description |
|---|---|
|
|
The product being removed from the category. |
|
|
The category from which the product is being removed. |
Occurs when a product is removed from a category.
function onRemoveProductFromCategory(NFRecord $product, NFRecord $category)
{
$productId = $product->externalId();
$categoryId = $category->externalId();
if($productId && $categoryId)
{
// remove the product from the category in the linked system
MyApp::remove_product_from_category($productId, $categoryId);
}
}
Netfira::addEventHandler(NF_REMOVE_PRODUCT_FROM_CATEGORY,
'onRemoveProductFromCategory');NF_PAIR_PRODUCT| Type | Description |
|---|---|
|
|
The internal product being paired with the external record. |
|
|
ID of the external product record being paired with the internal record. |
Occurs when a product is paired with an external record.
This event is not raised as a result of interactions with Netfira Seller. It is raised when an administrator manually pairs an internal and external record using the WebConnect Pairing Interface. See “WebConnect User Interfaces” for more information.
function onPairProduct(NFRecord $product, $externalId)
{
// update the product (see NF_RECEIVE_PRODUCT example)
update_product($externalId, $product);
// this would also be a good time to make sure this product is linked up
// with categories, images etc.
foreach($product->getImages() as $image)
{
MyApp::add_image_to_product($image->path(), $externalId);
}
foreach($product->getCategories() as $category)
{
if($cId = $category->externalId())
{
MyApp::add_product_to_category($externalId, $cId);
}
}
}
Netfira::addEventHandler(NF_PAIR_PRODUCT, 'onPairProduct');NF_UNPAIR_PRODUCT| Type | Description |
|---|---|
|
|
The internal product being unpaired from the external record. |
|
|
ID of the external product record being unpaired from the internal record. |
Occurs when a product is unpaired from an external record.
This event is not raised as a result of interactions with Netfira Seller. It is raised when an administrator manually pairs an internal and external record using the WebConnect Pairing Interface. See “WebConnect User Interfaces” for more information.
In practice, users will seldom unpair a record, unless it has been incorrectly paired.
function onUnpairProduct(NFRecord $product, $externalId)
{
// Responses to this event vary greatly between applications. One
// possible response is to disable the external product until it’s
// paired with a new internal record.
MyApp::disable_product($externalId);
}
Netfira::addEventHandler(NF_UNPAIR_PRODUCT, 'onUnpairProduct');NF_CREATE_PRODUCTProduct Replication:Events
| Type | Description |
|---|---|
|
|
The product to be replicated. |
Occurs when an administrator uses a WebConnect User Interface to copy an internal product record into the host application’s database.
This event is not raised as a result of interactions with Netfira Seller. It is raised when an administrator manually pairs an internal and external record using the WebConnect Pairing Interface. See “WebConnect User Interfaces” for more information.
This event is slightly different from other events, in that it requires action to be taken by the host application.
The event handler must create a new product
record in the host system, using the information provided, and pair it with the
internal record using the pairWith() method.
function onCreateProduct(NFRecord $product)
{
// create a new product in the host application
$externalProduct = MyApp::new_product();
$externalId = $externalProduct->id;
// populate it with information from WebConnect
update_product($externalId, $product);
// pair it with the internal record
$product->pairWith($externalId);
}
Netfira::addEventHandler(NF_CREATE_PRODUCT, 'onCreateProduct');Categories:Events
Events:Categories
NF_RECEIVE_CATEGORY| Type | Description |
|---|---|
|
|
The record being updated, with new values. |
Occurs when a category is inserted or updated.
function onReceiveCategory(NFRecord $category)
{
if($externalId = $category->externalId())
{
// update the category’s parent
$parent = $category->parent();
$parentId = $parent ? $parent->externalId() : 0;
MyApp::set_category_parent($externalId, $parentId);
// update the category’s name
MyApp::rename_category($externalId, $category->name);
}
else
{
// Category isn’t paired yet. We could try to match it to an
// existing one, but for this example we’ll assume a new one needs
// to be created.
if($parent = $category->parent())
{
// create a child of an existing category
$newCategory = MyApp::create_category($category->name,
$parent->externalId());
}
else
{
// this is a top-level category
$newCategoryId = MyApp::create_category($category->name, 0);
}
// pair the new category with the internal record
$category->pairWith($newCategoryId);
}
}
Netfira::addEventHandler(NF_RECEIVE_CATEGORY, 'onReceiveCategory');NF_DELETE_CATEGORY| Type | Description |
|---|---|
|
|
The category being deleted. |
Occurs when a category is deleted.
function onDeleteCategory(NFRecord $category)
{
// if the category is paired with an external category, delete it
if($externalId = $category->externalId())
{
MyApp::delete_category($externalId);
}
}
Netfira::addEventHandler(NF_DELETE_CATEGORY, 'onDeleteCategory');NF_PURGE_CATEGORIESNone
Occurs when all categories are deleted.
During a purge, if you have registered a
handler for NF_DELETE_CATEGORY,
each category will be deleted individually, with its own NF_DELETE_CATEGORY event.
Events:Images
Images:Events
NF_RECEIVE_IMAGE| Type | Description |
|---|---|
|
|
Details of the new image. |
|
|
The new image data (passed by reference). |
Occurs when an image is received (or replaced). You can use this event to generate thumbnails or watermark your images.
Note the ampersand prefixing the second argument. This allows you access to the original point in memory where the image is first stored, and minimises interaction with the file system.
function onReceiveImage(NFRecord $image, &$data)
{
// Image filenames are unique in Netfira, but may conflict with existing
// files. If in doubt, use a prefix, or a separate directory.
$imageId = 'nf_' . $image->fileName;
// create a thumbnail from the image data
MyApp::create_thumb_from_blob($imageId, $data);
// or, create a thumbnail from the stored file
MyApp::create_thumb_from_file($imageId, $image->path());
}
Netfira::addEventHandler(NF_RECEIVE_IMAGE, 'onReceiveImage');NF_DELETE_IMAGE| Type | Description |
|---|---|
|
|
The image to be deleted. |
Occurs when an image is deleted.
function onDeleteImage(NFRecord $image)
{
// delete the image thumbnail
MyApp::delete_thumb('nf_' . $image->fileName);
}
Netfira::addEventHandler(NF_DELETE_IMAGE, 'onDeleteImage');NF_PURGE_IMAGESNone
Occurs when all images are deleted.
During a purge, if you have registered a
handler for NF_DELETE_IMAGE,
each image will be deleted individually, with its own NF_DELETE_IMAGE event.
NF_ADD_IMAGE_TO_PRODUCT| Type | Description |
|---|---|
|
|
Details of the image being added to the product. |
|
|
The product to which the image is being added. |
Occurs when an image is added to a product.
function onAddImageToProduct(NFRecord $image, NFRecord $product)
{
if($productId = $product->externalId())
{
// add the image to the product in the linked system
MyApp::add_image_to_product('nf_' . $image->fileName, $productId);
}
}
Netfira::addEventHandler(NF_ADD_IMAGE_TO_PRODUCT, 'onAddImageToProduct');NF_REMOVE_IMAGE_FROM_PRODUCT| Type | Description |
|---|---|
|
|
Details of the image being removed from the product. |
|
|
The product from which the image is being removed. |
Occurs when an image is removed from a product.
function onRemoveImageFromProduct(NFRecord $image, NFRecord $product)
{
if($productId = $product->externalId())
{
// remove the image from the product in the linked system
MyApp::remove_image_from_product('nf_' . $image->fileName,
$productId);
}
}
Netfira::addEventHandler(NF_REMOVE_IMAGE_FROM_PRODUCT,
'onRemoveImageFromProduct');
Attachments:Events
Events:Attachments
NF_RECEIVE_ATTACHMENT| Type | Description |
|---|---|
|
|
Details of the new image. |
|
|
The new image data (passed by reference). |
Occurs when an image is received (or replaced). You can use this event to generate thumbnails or watermark your images.
Note the ampersand prefixing the second argument. This allows you access to the original point in memory where the image is first stored, and minimises interaction with the file system.
function onReceiveImage(NFRecord $image, &$data)
{
// Image filenames are unique in Netfira, but may conflict with existing
// files. If in doubt, use a prefix, or a separate directory.
$imageId = 'nf_' . $image->fileName;
// create a thumbnail from the image data
MyApp::create_thumb_from_blob($imageId, $data);
// or, create a thumbnail from the stored file
MyApp::create_thumb_from_file($imageId, $image->path());
}
Netfira::addEventHandler(NF_RECEIVE_IMAGE, 'onReceiveImage');NF_DELETE_ATTACHMENT| Type | Description |
|---|---|
|
|
The image to be deleted. |
Occurs when an image is deleted.
function onDeleteImage(NFRecord $image)
{
// delete the image thumbnail
MyApp::delete_thumb('nf_' . $image->fileName);
}
Netfira::addEventHandler(NF_DELETE_IMAGE, 'onDeleteImage');NF_PURGE_ATTACHMENTSNone
Occurs when all images are deleted.
During a purge, if you have registered a
handler for NF_DELETE_IMAGE,
each image will be deleted individually, with its own NF_DELETE_IMAGE event.
NF_ADD_ATTACHMENT_TO_PRODUCT| Type | Description |
|---|---|
|
|
Details of the image being added to the product. |
|
|
The product to which the image is being added. |
Occurs when an image is added to a product.
function onAddImageToProduct(NFRecord $image, NFRecord $product)
{
if($productId = $product->externalId())
{
// add the image to the product in the linked system
MyApp::add_image_to_product('nf_' . $image->fileName, $productId);
}
}
Netfira::addEventHandler(NF_ADD_IMAGE_TO_PRODUCT, 'onAddImageToProduct');NF_REMOVE_ATTACHMENT_FROM_PRODUCT| Type | Description |
|---|---|
|
|
Details of the image being removed from the product. |
|
|
The product from which the image is being removed. |
Occurs when an image is removed from a product.
function onRemoveImageFromProduct(NFRecord $image, NFRecord $product)
{
if($productId = $product->externalId())
{
// remove the image from the product in the linked system
MyApp::remove_image_from_product('nf_' . $image->fileName,
$productId);
}
}
Netfira::addEventHandler(NF_REMOVE_IMAGE_FROM_PRODUCT,
'onRemoveImageFromProduct');Buyers:Events
Events:Buyers
NF_RECEIVE_BUYER| Type | Description |
|---|---|
|
|
The buyer being updated, with new values. |
Occurs when a buyer is inserted or updated.
function update_customer($customerId, NFRecord $newData)
{
// update my app’s data with the new data from WebConnect
$myCustomer = MyApp::get_customer($customerId);
$myCustomer->set_name($newData->name);
$myCustomer->set_email($newData->email);
$myCustomer->save();
}
function onReceiveBuyer(NFRecord $buyer)
{
// if the buyer is paired with an external customer, merge some data
if($externalId = $buyer->externalId())
{
update_customer($externalId, $buyer);
}
}
Netfira::addEventHandler(NF_RECEIVE_BUYER, 'onReceiveBuyer');NF_DELETE_BUYER| Type | Description |
|---|---|
|
|
The buyer being deleted. |
Occurs when a buyer is deleted.
function onDeleteBuyer(NFRecord $buyer)
{
// if the buyer is paired with an external customer, disable it
if($externalId = $buyer->externalId())
{
MyApp::disable_customer($externalId);
}
}
Netfira::addEventHandler(NF_DELETE_BUYER, 'onDeleteBuyer');NF_PURGE_BUYERSNone
Occurs when all buyers are deleted.
During a purge, if you have registered a
handler for NF_DELETE_BUYER,
each buyer will be deleted individually, with its own NF_DELETE_BUYER event.
NF_ADD_PRODUCT_TO_BUYER| Type | Description |
|---|---|
|
|
The product to which the buyer will be granted access. |
|
|
The buyer being granted access to the product. |
Occurs when a buyer is granted access to a
product. Such restrictions should only be enforced when the buyer’s restrictProducts flag is set.
function onAddProductToBuyer(NFRecord $product, NFRecord $buyer)
{
$productId = $product->externalId();
$customerId = $buyer->externalId();
if($productId && $customerId)
{
// allow the buyer to access the product
MyApp::grant_access_to_product($productId, $customerId);
}
}
Netfira::addEventHandler(NF_ADD_PRODUCT_TO_BUYER, 'onAddProductToBuyer');NF_REMOVE_PRODUCT_FROM_BUYER| Type | Description |
|---|---|
|
|
The product from which the buyer’s access will be revoked. |
|
|
The buyer losing access to the product. |
Occurs when a buyer’s access to a product is
revoked. Such restrictions should only be enforced when the buyer’s restrictProducts flag is set.
function onRemoveProductFromBuyer(NFRecord $product, NFRecord $buyer)
{
$productId = $product->externalId();
$customerId = $buyer->externalId();
if($productId && $customerId)
{
// remove the buyer’s access to the product
MyApp::revoke_access_to_product($productId, $customerId);
}
}
Netfira::addEventHandler(NF_REMOVE_PRODUCT_FROM_BUYER,
'onRemoveProductFromBuyer');NF_PAIR_BUYER| Type | Description |
|---|---|
|
|
The internal buyer being paired with the external record. |
|
|
ID of the external customer record being paired with the internal record. |
Occurs when a buyer is paired with an external record.
This event is not raised as a result of interactions with Netfira Seller. It is raised when an administrator manually pairs an internal and external record using the WebConnect Pairing Interface. See “WebConnect User Interfaces” for more information.
function onPairBuyer(NFRecord $buyer, $externalId)
{
// update the customer (see NF_RECEIVE_BUYER example)
update_customer($externalId, $buyer);
// this would also be a good time to make sure the buyer has access
// to their products.
foreach($buyer->getProducts() as $product)
{
if($productId = $product->externalId())
{
MyApp::grant_access_to_product($externalId, $productId);
}
}
}
Netfira::addEventHandler(NF_PAIR_BUYER, 'onPairBuyer');NF_UNPAIR_BUYER| Type | Description |
|---|---|
|
|
The internal buyer being unpaired from the external record. |
|
|
ID of the external customer record being unpaired from the internal record. |
Occurs when a buyer is unpaired from an external record.
This event is not raised as a result of interactions with Netfira Seller. It is raised when an administrator manually pairs an internal and external record using the WebConnect Pairing Interface. See “WebConnect User Interfaces” for more information.
In practice, users will seldom unpair a record, unless it has been incorrectly paired.
function onUnpairBuyer(NFRecord $buyer, $externalId)
{
// Responses to this event vary greatly between applications. One
// possible response is to disable the external customer until they’re
// paired with a new internal record.
MyApp::disable_customer($externalId);
}
Netfira::addEventHandler(NF_UNPAIR_BUYER, 'onUnpairBuyer');NF_CREATE_BUYERBuyer Replication:Events
| Type | Description |
|---|---|
|
|
The buyer to be replicated. |
Occurs when an administrator uses a WebConnect User Interface to copy an internal buyer record into the host application’s database.
This event is not raised as a result of interactions with Netfira Seller. It is raised when an administrator manually pairs an internal and external record using the WebConnect Pairing Interface. See “WebConnect User Interfaces” for more information.
This event is slightly different from other events, in that it requires action to be taken by the host application.
The event handler must create a new customer
record in the host system, using the information provided, and pair it with the
internal record using the pairWith() method.
function onCreateBuyer(NFRecord $buyer)
{
// create a new customer in the host application
$customer = MyApp::new_customer();
// populate it with information from WebConnect
update_customer($customer->id, $product);
// generate a password and send a welcome email
$customer->randomize_password();
MyApp::send_welcome_email($customer->id);
// pair it with the internal record
$buyer->pairWith($customer->id);
}
Netfira::addEventHandler(NF_CREATE_BUYER, 'onCreateBuyer');Events:Advanced
Events:Advanced:Pre and Post Update
It’s often beneficial to selectively handle an event before or after WebConnect makes changes to its data tables.
For example, if you handle an event before the database is updated, you can compare the old information with the new information.
On the other hand, if you handle the event after the database is updated, you can utilise reusable code that may rely on the data in the database, rather than the data passed to the event handler.
To facilitate distinct pre- and post-update
handling, WebConnect provides two additional constants for most events,
containing the WILL and DID keywords immediately following the NF_ prefix.
For example, NF_WILL_RECEIVE_BUYER is raised before buyer information is
written to the data tables, and NF_DID_RECEIVE_BUYER
is raised after data is written.
The event constants listed in previous
sections, which do not contain WILL or DID keywords, occur after data is written. NF_RECEIVE_BUYER is an alias of NF_DID_RECEIVE_BUYER.
Another use for pre- and post-update
constants is to help a DELETE event
determine if a record is being removed individually, or as part of a purge. You
could set a flag in your NF_WILL_PURGE_BUYERS
handler, which can then be detected in your NF_DELETE_BUYER handler and un-set in your NF_DID_PURGE_BUYERS handler.
The only events that do not have pre- and
post-update constants are CREATE events (NF_CREATE_BUYER and NF_CREATE_PRODUCT),
because these events rely on the host system to do the work, and do no make
changes to the WebConnect data tables (although they do require the handler to
make changes).
Events:Advanced:Delayed Linkage
Not all events occur in their ideal orders.
For example, after Netfira Seller uploads
its products, it adds them to the relevant categories. If your software
requires products to be manually paired or replicated into the host system,
that event may not occur until hours afterwards. If your NF_ADD_PRODUCT_TO_CATEGORY handler requires the product to be
paired, you may find your host system’s products never find their way into the
proper categories.
In some older versions of Netfira Seller, images and attachments may not be received until after they have been paired with products. This is because large amounts of data are buffered and uploaded during periods of inactivity.
It’s important to bare this in mind when designing code that relies on pairing and relations between records of different types.
A couple of tips:
If you receive a record for the first time,
check for existing relations and process them. You can tell a record is
arriving for the first time using an NFRecord
instance’s exists() method in a
pre-update handler.
When you handle a PAIR event, treat the record as if you’re receiving it for
the first time.
If you’re building a store from scratch, it’s much simpler to use the WebConnect data tables as a foundation than have to synchronise them with a different set of tables. This section explains the layout of WebConnect data tables, so you can start working with them straight away.
WebConnect stores information in simple relational databases. At the time of writing, WebConnect only supports MySQL via the PHP MySQL extension.
WebConnect uses the database configured in the WebConnect runtime configuration (see section “Configuration”). WebConnect attempts to create the database and tables as needed.
WebConnect will maintain the information in
these tables for you. Except for Orders and OrderLines, you should not write to the WebConnect data
tables. Any changes you make are likely to be overwritten by WebConnect.
WebConnect uses two main forms of tables – tables of records, and tables of relations.
Tables of records are named as Netfira::$dbPrefix followed by the plural form of the record
type (for example, nf_Products).
Tables of records have a single primary key column.
Tables of relations are named as Netfira::$dbPrefix followed by the singular forms of the
types involved, joined by an ampersand (for example, nf_Category&Product). The types always appear in
alphabetical order.
Tables of records have two columns, which are both part of the table’s primary key.
On Windows systems, table names are lower-case.
If you run WebConnect in multi-store mode
(ie if Netfira::$storeId is
not null), every table
(for both records and relations) will have an extra varchar field called @storeId,
which will also be part of the table’s primary key.
The presence or absence of this field is
determined by Netfira::$storeId’s
value at the time they are created, which is usually the first time the
WebConnect PHP file is run. Remember if you make a mistake, you can simply drop
all tables (or the whole database) and WebConnect will re-create them for you.
Tables of records include three common fields, known as meta fields:
| Name | Type | Description |
|---|---|---|
|
|
|
When the record was first created. |
|
|
|
When the record was last modified. |
|
|
|
An MD5 hash (checksum) of all non-meta fields for the record. |
Generally you will not need to use these fields. They are used internally by WebConnect to track changes. Their values are not accessible through the WebConnect Library.
If you want to read them directly via SQL, you’ll need to quote the field names in backticks:
SELECT `@created`, nfCode FROM nf_Buyers WHERE `@created` >= '2011-07-01';
If you are running WebConnect in multi-store
mode, a @storeId field will
also be present.
Fields which have not been populated by
Netfira Seller are stored as null. Bear this in
mind when filtering content, as for example, a buyer’s phone number may be null or an empty string.
Products:Table Definition
Stores information about products (inventory items).
Primary key: productId
| Name | Type | Description |
|---|---|---|
|
|
|
The product’s unique identifier. For most systems, this will be the same as the product’s part number. For systems that allow non-unique part numbers, this will be another unique string value. |
|
|
|
The product’s category. This field is not
related to the catalogue tree stored in the |
|
|
|
The short description, or name, of the product. |
|
|
|
Height of a single unit in millimetres. This information is supplied to help calculate shipping charges. |
|
|
|
Length of a single unit in millimetres. This information is supplied to help calculate shipping charges. |
|
|
|
The long description, or detailed description, of the product. |
|
|
|
The product’s part number. Depending on the attached accounting system, this field may not be unique. |
|
|
|
Numeric boolean indicating whether this product should be available on the website. |
|
|
|
Current stock level. May be fractional, zero or negative on some systems. |
|
|
|
Price of a single unit in the seller’s currency, excluding tax. |
|
|
|
Tax on a single unit in the seller’s currency. |
|
|
|
Weight of a single unit in grams. This information is supplied to help calculate shipping charges. |
|
|
|
Width of a single unit in millimetres. This information is supplied to help calculate shipping charges. |
Categories:Table Definition
Stores information about categories in the
product catalogue. The categories table is a hierarchical data table, with
children relating to parents using the parentId
field.
Primary key: categoryId
| Name | Type | Description |
|---|---|---|
|
|
|
The category’s unique identifier. |
|
|
|
The human-readable name (or description) of the category. |
|
|
|
ID of the parent category. If the category
is a top-level (root) category, this value will be |
Images:Table Definition
Stores information about product images. The
images themselves are stored in the Netfira::$fileStore
directory. This table simply keeps track of them.
Primary key: fileName
| Name | Type | Description |
|---|---|---|
|
|
|
The file’s unique file name. |
|
|
|
A raw MD5 hash (checksum) of the file. |
Attachments:Table Definition
Stores information about product
attachments. The files themselves are stored in the Netfira::$fileStore directory. This table simply keeps track
of them.
Primary key: fileName
| Name | Type | Description |
|---|---|---|
|
|
|
The file’s unique file name. |
|
|
|
A raw MD5 hash (checksum) of the file. |
Buyers:Table Definition
Stores information about buyers (customers, clients etc), including information they can use to authenticate before placing orders on your website.
Primary key: nfCode
| Name | Type | Description |
|---|---|---|
|
|
|
The buyer’s unique NF code. This value is
randomly generated and assigned to the buyer by Netfira Seller. Because it’s
the only buyer field guaranteed to be unique, you should use this field
(along with |
|
|
|
Line 1 of the buyer’s billing address. |
|
|
|
Line 2 of the buyer’s billing address. |
|
|
|
The city, town or suburb of the buyer’s billing address. |
|
|
|
The two-letter ISO 3166-1 (alpha2) code of the country of the buyer’s billing address. |
|
|
|
The postal (or zip) code of the buyer’s billing address. |
|
|
|
The state or province of the buyer’s billing address. |
|
|
|
The buyer’s identifier in the seller’s accounting system. These values are typically unique, but may be harder for buyers to remember than an NF code. |
|
|
|
The name of the buyer’s contact person, if the buyer is a company. |
|
|
|
The buyer’s email address. This value may not be unique and should not be used for logins. |
|
|
|
The buyer’s fax number. |
|
|
|
The buyer’s name, or company name if they are a company. |
|
|
|
The buyer’s phone number. |
|
|
|
A raw MD5 hash of the buyer’s pin number (or password). You can use this field, along with nfCode, to authenticate customer logins. See below for examples. |
|
|
|
A numeric boolean that indicates whether a
buyer should be restricted to a specific set of products, stored in the |
|
|
|
Line 1 of the buyer’s shipping address. |
|
|
|
Line 2 of the buyer’s shipping address. |
|
|
|
The city, town or suburb of the buyer’s shipping address. |
|
|
|
The two-letter ISO 3166-1 (alpha2) code of the country of the buyer’s shipping address. |
|
|
|
The postal (or zip) code of the buyer’s shipping address. |
|
|
|
The state or province of the buyer’s shipping address. |
|
|
|
A numeric boolean that indicates whether a buyer is allowed to use the website. |
Orders:Table Definition
Stores information about orders placed by customers.
To send order information back to Netfira Seller, you need to store it in this table (as well as the OrderLines table).
Primary key: orderId
| Name | Type | Description |
|---|---|---|
|
|
|
The unique, auto-increment ID of the order. |
|
|
|
Line 1 of the buyer’s billing address. |
|
|
|
Line 2 of the buyer’s billing address. |
|
|
|
The city, town or suburb of the buyer’s billing address. |
|
|
|
The two-letter ISO 3166-1 (alpha2) code of the country of the buyer’s billing address. |
|
|
|
The postal (or zip) code of the buyer’s billing address. |
|
|
|
The state or province of the buyer’s billing address. |
|
|
|
The buyer’s reference (ie their purchase order number/ID) for the order. Optional. |
|
|
|
The buyer’s identifier in the seller’s accounting system. |
|
|
|
A comment the buyer may attach to the order at check-out. |
|
|
|
The name of the buyer’s contact person, if the buyer is a company. |
|
|
|
The three-letter ISO 4217 currency code of the amounts in the order. |
|
|
|
The buyer’s email address. This value may not be unique and should not be used for logins. |
|
|
|
The buyer’s fax number. |
|
|
|
The status of the order in respect of its delivery to Netfira Seller.
|
|
|
|
The buyer’s name, or company name if they are a company. |
|
|
|
A globally unique identifier for this order, used by Netfira Seller to ensure orders are not accidentally inserted more than once. This value is generated randomly by WebConnect when the order is sent to the seller, and can be ignored. |
|
|
|
Error code (if available) from the payment processor. |
|
|
|
Error message (if available) from the payment processor. |
|
|
|
Chosen method of payment for the order.
May be |
|
|
|
A numeric boolean indicating whether payment for this order was received at the time it was placed. |
|
|
|
Reference from the organisation (bank, gateway, PayPal etc) who processed the payment. |
|
|
|
The buyer’s phone number. |
|
|
|
Buyer’s shipping account username (if required). |
|
|
|
Line 1 of the buyer’s shipping address. |
|
|
|
Line 2 of the buyer’s shipping address. |
|
|
|
The city, town or suburb of the buyer’s shipping address. |
|
|
|
The two-letter ISO 3166-1 (alpha2) code of the country of the buyer’s shipping address. |
|
|
|
Shipping method. May be |
|
|
|
Buyer’s shipping account password (if required). |
|
|
|
The postal (or zip) code of the buyer’s shipping address. |
|
|
|
Shipping charge (if applicable), excluding tax. |
|
|
|
The state or province of the buyer’s shipping address. |
|
|
|
Shipping tax (if applicable). |
Orders:Placing:Into Data Tables
To successfully prepare an order for deliver to Netfira Seller, there are three distinct database operations that must occur:
Line Items:Adding to Orders:Into Data Tables
Insert a new record in the Orders table. All fields are optional, although many will be
required for an order to make sense.
Use the auto-insert value of the new record’s orderId field (commonly accessible in PHP as mysql_insert_id()) as the orderId in each line you insert into the OrderLines table (see next section for details about the OrderLines table).
Update the finalised
field of the record in the Orders table with a
value of 1.
If you’ve set the Netfira::$memcachedKey value, set the key to notify the order
polling thread that the order is ready:
Memcached:Flagging Pending Orders
Netfira::$memcachedKey = 'deliverMyOrder';
// ...
$cache = new Memcache();
$cache->connect('localhost', 11211);
$cache->set('deliverMyOrder', 1);The order will be sent to Netfira Seller as
a response to its current/next request for orders. Once Netfira Seller has
received the order, it will send a message to WebConnect that changes the value
of the order’s finalised field to 2.
Orders:Table Definition:Line Items
Line Items:Table Definition
Stores line items of orders, linked to
records in the Orders table by the orderId
field.
Primary Key: orderLineId
| Name | Type | Description |
|---|---|---|
|
|
|
The unique, auto-increment ID of the line item. |
|
|
|
Optional comment attached to the line by the buyer at checkout |
|
|
|
Short description (or name) of the product on the line. |
|
|
|
ID of the order to which the line item belongs. Note that WebConnect doesn’t enforce foreign keys; this is a regular column. |
|
|
|
Part number of the product on the line. |
|
|
|
Unique ID of the product on the line. |
|
|
|
Number of units for the line. |
|
|
|
Unit price of the item on the line, excluding tax. |
|
|
|
Tax for the item on the line. |
Tables of relations have only two columns. They are identical in both name and type to the primary keys of the two tables between which they form relations.
If WebConnect is running in multi-store
mode, tables of relations have a third column; @storeId (varchar), which
identifies the store that owns the relation.
Tables of relations are named for the
singular forms of the types involved; for example, Image&Product or Category&Product.
Types are always in alphabetical order, and table names will include the prefix
assigned to Netfira::$dbPrefix.
The following example demonstrates using a table of relations to list all products in a given category:
$cmd = "
SELECT *
FROM nf_Products
NATURAL JOIN `nf_Category&Product`
WHERE categoryId = 'legumes'
";
$rlt = mysql_query($cmd);
while($row = mysql_fetch_assoc($rlt))
{
print_r($row); // show all information available about all legumes
}Note the use of the backticks (``) around the table name, made necessary by the presence of
the ampersand in the name.
You can use similar queries to list:
Images belonging to a given product (Image&Product)
Attachments belonging to a given product (Attachment&Product)
Buyers allowed to buy a given product (Buyer&Product)
Products accessible by a given buyer (Buyer&Product)
Categories to which a given product belongs (Category&Product)
The WebConnect PHP file includes JavaScript applications for rendering user interfaces that allow site administrators to pair existing products and buyers, and replicate WebConnect product and buyer records into their host systems.
These interfaces are designed to integrate with a host system’s existing administration interface. The JavaScript applications produce structured DOM elements with class name that allow you to style the applications to match the appearance of virtually any existing UI.
This section explains:
How to supply WebConnect’s JavaScript interfaces with the information they need from the host application
How to embed the applications in your existing administration interface
How to style WebConnect’s applications to fit your existing appearance
WebConnect includes two JavaScript apps you can embed in your admin interface.
The Replication app lists records from WebConnect’s data tables that have not been paired with host system records, and allows administrators to “replicate” them into the host system, either one at a time, or as a batch. This means administrators can easily migrate an entire inventory into the host system, or create a large number of user accounts, and send welcome emails, with a single click.
The Pairing app lists records from the host system that have not been paired with WebConnect records, and allows administrators to pair them up. It also provides suggestions, so that new customers connecting to existing stores for the first time can automatically pair their entire inventories.
The Pairing app needs access to the host system’s data, which is achieved through “data providers”. Data providers are simple PHP functions you can write, which return the information WebConnect needs.
The apps are embedded in your application
with a single <script> tag
and activated with as little as one line of JavaScript. They use ajax calls to
load and display data, and make changes to the WebConnect data tables.
WebConnect includes simple CSS style sheets that make the apps look neat and presentable in any environment. You can use these style sheets as they are, or as foundations for your own, or you can use them as guides to design your own from scratch. WebConnect provides the freedom to use as much, or as little, of its assistance as you like.
Data Providers
Data providers are functions you can write to supply data from your host system to WebConnect. They can be global functions, instance methods, static methods or anything callable. They take no arguments.
Data provider functions return an associate array, in which the keys are the IDs with which WebConnect will pair its own records, and the values are associative arrays representing the key/value pairs of the records. Only the fields required by WebConnect should be included; other information can be omitted. Where no records exist in the host system, an empty array should be returned.
Like event handlers, data providers need to
be registered
with WebConnect. Provider registration is managed by the Netfira::$pairing singleton with the following methods:
Classes:NFPairing
| Method | Description |
|---|---|
|
|
Set the product provider. |
|
|
Set the buyer provider. |
Product Pairing:Creating a Data Provider
Data Providers:For Products
The product provider returns names (or descriptions), part numbers (or SKUs) and IDs of the host system’s inventory.
| Name | Type | Description |
|---|---|---|
|
|
|
The part number, or SKU, of the product. This may often, but not always, be the product’s unique identifier. |
|
|
|
Short description, or name, of the product. |
function get_products()
{
$ret = array();
$rlt = mysql_query("SELECT * FROM products");
while($row = mysql_fetch_assoc($rlt))
{
$ret[$row['product_id']] = array(
'part' => $row['part_number'],
'description' => $row['product_name']
);
}
return $ret;
}
// register the provider:
Netfira::$pairing->setProductProvider('get_products');print_r(get_products()); /* echoes:
Array
(
[243] => Array
(
[part] => pnt
[description] => Peanut
)
[982] => Array
(
[part] => csh
[description] => Cashew
)
)
*/
Buyer Pairing:Creating a Data Provider
Data Providers:For Buyers
The buyer provider returns names and email addresses of the host system’s customer list.
| Name | Type | Description |
|---|---|---|
|
|
|
The customer’s full name, or company name if they are a company. |
|
|
|
The customer’s email address. This field does not need to be unique. |
function get_customers()
{
$ret = array();
$rlt = mysql_query("SELECT * FROM customers");
while($row = mysql_fetch_assoc($rlt))
{
$ret[$row['customer_id']] = array(
'name' => $row['first_name'] . ' ' . $row['last_name'],
'email' => $row['email_address']
);
}
return $ret;
}
// register the provider:
Netfira::$pairing->setBuyerProvider('get_customers');print_r(get_products()); /* echoes:
Array
(
[68] => Array
(
[name] => Neil Pearson
[email] => neil.pearson@netfira.com
)
[24] => Array
(
[name] => Earl White
[email] => earl.white@netfira.com
)
)
*/JavaScript Libraries
The WebConnect PHP file includes a number of static resources that are accessible by calling it with a query string. For example:
webconnect.php?pw=Passw0rd&res=productPairing.js
Requesting the URI above will respond with the product pairing JavaScript library.
Clients must authenticate before WebConnect
will send any resources via HTTP. Including the password in HTML tags is
undesirable, so WebConnect provides an alternate mechanism for authentication
that uses a session cookie. To start a WebConnect session, call the Netfira::authoriseSession() method before any content has
been sent. Then you can use resource URIs without the pw= component:
webconnect.php?res=productPairing.js
To de-authorize a session (ie when an
administrator logs out), call Netfira::authoriseSession(false).
Product Pairing:User Interface:Embedding
JavaScript Libraries:Product Pairing
Include the following tag in your <head></head> block to load the product pairing
library:
<script type="text/javascript" src="webconnect.php?res=productPairing.js"> </script>
Next, create an empty <div></div> as a placeholder for the pairing
interface, and give it a unique ID:
<div id="pairingAppContainer"></div>
Finally, create a new pairing app controller and initialise it:
<script type="text/javascript">
nf.productPairing('pairingAppContainer').init();
</script>Your original <div></div> will be populated with elements of
the product pairing user interface.
Buyer Pairing:User Interface:Embedding
JavaScript Libraries:Buyer Pairing
Include the following tag in your <head></head> block to load the buyer pairing
library:
<script type="text/javascript" src="webconnect.php?res=buyerPairing.js"> </script>
Next, create an empty <div></div> as a placeholder for the pairing
interface, and give it a unique ID:
<div id="pairingAppContainer"></div>
Finally, create a new pairing app controller and initialise it:
<script type="text/javascript">
nf.buyerPairing('pairingAppContainer').init();
</script>Your original <div></div> will be populated with elements of
the buyer pairing user interface.
Product Replication:User Interface:Embedding
JavaScript Libraries:Product Replication
Include the following tag in your <head></head> block to load the product
replication library:
<script type="text/javascript"
src="webconnect.php?res=productReplication.js">
</script>Next, create an empty <div></div> as a placeholder for the replication
interface, and give it a unique ID:
<div id="replicationAppContainer"></div>
Finally, create a new replication app controller and initialise it:
<script type="text/javascript">
nf.productReplication('replicationAppContainer').init();
</script>Your original <div></div> will be populated with elements of
the product replication user interface.
Be sure to implement a handler for the NF_CREATE_PRODUCT event (see section “Sync Events –
Product Events”).
Buyer Replication:User Interface:Embedding
JavaScript Libraries:Buyer Replication
Include the following tag in your <head></head> block to load the buyer replication
library:
<script type="text/javascript"
src="webconnect.php?res=buyerReplication.js">
</script>Next, create an empty <div></div> as a placeholder for the replication
interface, and give it a unique ID:
<div id="replicationAppContainer"></div>
Finally, create a new replication app controller and initialise it:
<script type="text/javascript">
nf.buyerReplication('replicationAppContainer').init();
</script>Your original <div></div> will be populated with elements of
the buyer replication user interface.
Be sure to implement a handler for the NF_CREATE_BUYER event (see section “Sync Events – Buyer
Events”).
JavaScript Libraries:Interface Customisation
Before calling the init() method, you can tweak some aspects of the apps’
behaviour by assigning values to DOM properties in JavaScript.
These settings apply to all WebConnect JavaScript apps.
Number of items (records) displayed per page.
nf.PairingUI.ITEMS_PER_PAGE = 12;
Number of items (records) displayed in the auto-complete suggestions dropdown.
nf.PairingUI.ITEMS_PER_SUGGESTION_LIST = 15;
These settings apply to the product pairing and buyer pairing apps.
Determines whether the auto-complete suggestions list will be automatically positioned underneath the active text box at run-time. If disabled, the auto-complete list retains its default positioning properties.
var pairingApp = nf.productPairing('pairingAppContainer');
pairingApp.autoCompletePositioning = true;
Determines whether the width of the auto-complete suggestions list will be automatically matched to the active text box at run-time. If disabled, the auto-complete list retains its default sizing properties.
pairingApp.autoCompleteSizing = true;
Determines whether the search field appears in the actions area of the application.
pairingApp.searchable = true;
These settings apply to the product replication and buyer replication apps.
Determines whether the search field appears in the actions area of the application.
var replicationApp = nf.productReplication('replicationAppContainer');
replicationApp.searchable = true;
replicationApp.init();This example demonstrates a simple PHP document that displays the WebConnect product pairing app.
<?php
// invoke the WebConnect library
require_once('webconnect.php');
// authorise the session so WebConnect resources are accessible
Netfira::authoriseSession();
?>
<!doctype html>
<html lang="en">
<head>
<title>Pairing Test</title>
<link rel="stylesheet"
href="webconnect.php?res=productPairing.css" />
<script src="webconnect.php?res=productPairing.js"
type="text/javascript"></script>
</head>
<body>
<div id="pairingAppContainer"></div>
<script type="text/javascript">
nf.PairingUI.ITEMS_PER_PAGE = 2;
nf.PairingUI.ITEMS_PER_SUGGESTION_LIST = 12;
var pairingApp = nf.productPairing('pairingAppContainer');
pairingApp.autoCompletePositioning = true;
pairingApp.autoCompleteSizing = true;
pairingApp.searchable = true;
pairingApp.init();
</script>
</body>
</html>Note the use of the productPairing.css style sheet, discussed in the following
section.
Product Replication:User Interface:Styling
Buyer Replication:User Interface:Styling
Product Pairing:User Interface:Styling
Buyer Pairing:User Interface:Styling
The DOM structures produced by WebConnect pairing and replication apps vary considerably. This section will outline the low-level elements of the apps, but is not an exhaustive reference to the complete range of classes and element combinations.
An effective technique to style the WebConnect pairing and replication apps is to use a tool like , Opera Dragonfly or Safari’s Web Inspector to examine the DOM produced by the apps, and write CSS that forms the result you desire.
Each UI consists of three main elements – actions, records and a pager.
The root element of every WebConnect app is
added to the nf and ui classes.
Pairing apps are added to the pairing class. Replication apps are added to the replication class.
Each app is also added to the class of its name. For example, the product pairing app’s root element may look like this:
<div id="pairingAppContainer" class="nf ui pairing productPairing">...</div>
The root element need not be div element, but it is recommended.
<ul class="actions">...</ul>
The first element in any app is an actions list, which can typically be formatted as a “toolbar” and contains options that apply to all records, as well as the search field if it’s enabled.
Like most lists in WebConnect apps, the
first and last list items belong to the first
and last classes
respectively.
Some items in the actions list contain <a></a> tags which perform functions like
processing the entire list. Such items will belong to a class that reflects
their purpose; for example:
<li class="first acceptAll"><a href="javascript:">Accept All</a></li>
If you’ve enabled the search field, it will be the last item in the actions list. The item will be in the search class.
<li class="last search">
<label for="productPairingSearch">Search</label>
<input id="productPairingSearch"
type="text"
placeholder="Search"
title="Search">
</li>In pairing apps, records are displayed in an unordered list:
<ul class="records">...</ul>
In replication apps, records are displayed in a table:
<table class="records" cellspacing="0">...</table>
As with other lists in WebConnect apps, the
first and last items or table rows belong to the first and last classes
respectively.
Pairing list items belong to the record class, and may also belong to one of the following
classes:
| Class | Description |
|---|---|
|
|
This record is paired. |
|
|
This record is unpaired, but WebConnect has a suggestion and is ready to pair it. |
If the record is not in one of the two classes above, it is not paired and not ready to be paired.
Each item will contain the following elements:
An h4
tag in the externalId class
that shows the record’s ID in the host system.
<h4 class="externalId">746</h4>
A <div>
tag in the details and external classes, which contains a <dl> definition list of the record’s details in the
host system.
<div class="details external">
<dl>
<dt class="part first">Part No.</dt>
<dd class="part first">pnt</dd>
<dt class="description last">Description</dt>
<dd class="description last">Peanut</dd>
</dl>
</div>A <div>
tag in the details and internal classes, which contains a <dl> definition list of the details of the paired
record.
<div class="details internal">
<dl>
<dt class="productId first">
<label for="2_productId">ID</label>
</dt>
<dd class="productId first">
<input type="text" id="2_productId"
title="ID" placeholder="ID">
</dd>
<dt class="part">
<label for="2_part">Part No.</label>
</dt>
<dd class="part">
<input type="text" id="2_part"
title="Part No." placeholder="Part No.">
</dd>
<dt class="description last">
<label for="2_description">Description</label>
</dt>
<dd class="description last">
<input type="text" id="2_description"
title="Description" placeholder="Description">
</dd>
</dl>
</div>Similar to the main actions list, this <ul> unordered list may contain one or more <a> links that perform actions relating to the record,
including:
Accepting the suggested pairing
Un-pairing the record
Cancelling changes
As well as the first and last rows in a
replication table belonging to the first
and last classes
respectively, each row belongs to either the odd or even class, allowing
you to create alternating row colour effects.
The first and second-last <td> table cell of each row will also belong to the first and last classes
respectively. Each cell will belong to either the left or right class,
depending on how its content should be justified.
Table cells simply display the data in
WebConnect’s data tables that will be replicated into the host system. The last
cell will belong to the action class, and
will contain an <a> link that
replicates just that record.
<td class="action"><a href="javascript:">Create</a></td>
Testing
The WebConnect PHP library includes a full-featured unit testing application that makes testing your WebConnect implementation easy and painless.
TestCentre has a very simple scripting language that automates testing by simulating a Netfira Seller machine connecting to your server. Using simple commands, you can add, update and delete records, purge entire tables, link and unlink records in relation tables, and download orders.
TestCentre allows you to save an unlimited list of tests to your WebConnect data tables, and import and export sets of tests from text files.
TestCentre:Accessing TestCentre
TestCentre is one of WebConnect’s built-in resource files. To access it, go to the following URI in your browser (substituting the correct path and password):
http://localhost/MyApp/webconnect.php?pw=Passw0rd&res=test.html
If you prefer, you can write a PHP script to create a session so that you don’t have to use your sync password in your URI, for example:
<?php // testcentre.php
require_once('webconnect.php');
Netfira::authoriseSession();
header('Location: webconnect.php?res=test.html');TestCentre:Script Syntax
WebConnect comes with plenty of example test scripts to get you started. If you prefer to write your own, here are the commands TestCentre recognises.
Except for names of fields in data tables, all commands and keywords in TestCentre are case-insensitive.
Comments:In Test Scripts
Any line starting with a # will be ignored by TestCentre.
# this is a comment.
White space, including blank lines, is also ignored.
To update a record, first specify which
record you want to update with the UPDATE
command:
UPDATE Product peanut
If the record doesn’t exist, it will be created. If creating the record is your only objective, this is all you have to do.
Otherwise, if you want to change other
fields, assign one per line immediately following the UPDATE command:
UPDATE Product peanut unitPrice = 4 description = Peanut showOnWebsite = 1
Note that whitespace is included only for clarity, and is not required.
If you’re updating an Image or Attachment,
include its data as a base64 blob immediately after the UPDATE command, and terminate the data with a semicolon.
UPDATE Image nuts.jpg ST8HVSZc2K9PTGlfSP6Y2SGBzZs4aa4Mwm8dTC6XovoQiFGnApxYr8ocxFVf010LnjjyIlXr1LNB y2atZNBs16VMtYUiMOGoAa1rxSooWxSvX753lQ78uigs3bFHR6FswzYc372QTVl965VwnpdcJHhI vNimSQhJgYqOjExyPkKVWbFZzdmia9BGEzf+65g25doZeVhOs6eXMTatPdOiPdv0bcpCeXryrYn5 59d+4xHHTbo6Lt28m3fTDsvLuFHRbaOOdV1dK1Av0b8z1jzc8PfhrcsHrKzlNqYeMe/cXw+p9OIA HqcRdkf0lt9T4NDEHf9F/80G32i1kTegcs1soJ6FaB24Hn8xVNSgcPFFSB0uu6Vg2FA+;
To delete a record, use the DELETE command:
DELETE Buyer NF12345
To create a relation between two records,
use the ADD command:
ADD Product peanut TO Category legumes
To remote a relationship between two
records, use the REMOVE command:
REMOVE Image nuts.jpg FROM Product peanut
Changes made with the UPDATE, DELETE, ADD and REMOVE commands are
placed in a queue, and sent only when the COMMIT
command is reached.
COMMIT
The COMMIT
command allows you to optionally specify a time limit. If the commit takes
longer than the given time limit, it will be re-submitted with the changes that
were not made. This is the same behaviour as Netfira Seller.
COMMIT 15
The example above imposes a 15 second time limit upon the commit request.
You can purge an entire table using the PURGE command:
PURGE Products
The PURGE
command allows you to optionally specify a time limit. If the purge takes
longer than the given time limit, it will be re-submitted to resume purging.
This is the same behaviour as Netfira Seller.
PURGE Products 10
The example above imposes a 10 second time limit upon the purge request.
Purges are independent requests, and do not
require an additional COMMIT command.
Orders:Testing
You can download pending orders using the ORDERS command:
ORDERS
By default, the ORDERS command will wait 60 seconds for an order to be
placed. You can change the request’s timeout by specifying a time limit in
seconds:
ORDERS 20
The example above imposes a 20 second time limit upon the orders request.
You can pause execution of a test script for a fixed duration using the WAIT command:
WAIT 0.5
The example above will pause execution for half a second.
For best results, run TestCentre in an HTML 5 compatible browser.
TestCentre:Running Tests
To run the current test script, click Run on the TestCentre toolbar. Test results will appear in the right-most column.
You can inspect various requests and responses by clicking the links in the test results that have triangles next to them.
TestCentre:Managing Tests:Creating
TestCentre:Managing Tests:Renaming
TestCentre:Managing Tests:Deleting
Use the New, Rename and Delete buttons on the TestCentre toolbar to manage tests.
You can also double-click an item in the test list to rename it.
Click the buttons in the test list (the leftmost column) to switch between tests.
If you only have one test in your list, you will not be able to delete it.
TestCentre:Managing Tests:Saving
TestCentre can save your current test scripts to the WebConnect data tables, and will automatically reload them at start-up.
To save your scripts to the WebConnect data tables, click Save on the TestCentre toolbar.
TestCentre:Managing Tests:Importing
TestCentre:Managing Tests:Exporting
You can import and export your current test scripts to and from text files.
To export your test set, click Export on the TestCentre toolbar. A text area will pop up with your test set in plain text. Copy the contents of the text area to a file on your local system and save it.
To import a different test set, click Import on the TestCentre toolbar. Paste the new test set into the pop-up text area and click OK. Your current test set will be overwritten.
Logging
WebConnect has a logging mechanism that allows you to monitor internal activity, such as events being raised and resources being requested.
To enable logging in WebConnect, set the Netfira::$logFile variable to the name of the file you want
to use for logging. The file path should be relative to the WebConnect PHP
file.
Netfira::$logFile = 'WebConnect.log';
By default, the log file is truncated to
64Kb. You can specify a different limit by setting Netifra::$logLimit to a number of bytes, or zero to impose no
limit.
Netfira::$logLimit = 0x1000; // limit log file size to 4Kb Netfira::$logLimit = 0; // no limit to log file size
You can write your own data to the
WebConnect log file by passing a single argument to the Netfira::log() method. If the argument is non-scalar, it will
be passed to var_export() before
being written to the log.
Netfira::log('Hello World!');
Inventory > Products
Customers > Buyers
WebConnect Library:Classes > Classes
Catalogue > Categories
Product Images > Images
File Attachments > Attachments
Product File Attachments > Attachments
Customers > Buyers
Orders:Line Items > Line Items
Replication:Products > Product Replication
Replication:Buyers > Buyer Replication
Testing:TestCentre > TestCentre
Testing:Logging > Logging
Strategies > Development Strategies