Actions

User

Chris Davenport/JData/How to use the JData classes

From Joomla! Documentation

< User:Chris Davenport‎ | JData

You will need to create a class which extends the JDataHandler base class. This extended handler class contains only methods that are required to process data specific to the data in question. Methods are named according to a convention that enables them to be automatically detected and used without the need to write any additional code or configuration. In many cases the data itself provides the configuration. Methods in the extended handler are called when specific events are generated by the input parser.

All methods that are part of this callback mechanism have the prefix "process". All process methods are optional and their absence will not generate any errors. The following process methods are supported:

  • processStart is called immediately before input of the first data takes place and is typically used to clear buffers and open output files, etc.
  • processEnd is called immediately after all data processing tasks have been completed and is typically used to allow the adapter to perform any one-off shutdown tasks, such as closing files, etc.
  • processRecordStart
  • processRecordEnd
  • processFieldStart<fieldname> is called before the input adapter fully processes the input data field called <fieldname>.
  • processFieldEnd<fieldname> is called after the input adapter has finished processing the input data field called <fieldname>.

It is important to realise that for each field in the input data there are two events that can be used: processFieldStart<fieldname> and processFieldEnd<fieldname>. In the case of simple, record-orientated data formats, such as CSV, you should use the processFieldlStart* methods. If you are using XML the processFieldStart* methods are called when the start tag of an element is encountered and the processFieldEnd methods are called when the end tag of an element is encountered. This makes it easy to break an XML file into a collection of records, for example.

For example, suppose you have a field called "price" in the input data. Then you will need to include a "processFieldStartPrice" method in your extended data handler class and it will probably look like this:

public function processFieldStartPrice( JDataField $field )
{
   $this->addField( $field );
   return true;
}

The argument $field that is passed to this method is a JDataField object and includes the following prooperties:

  • name is the name of the field.
  • value is the value of the field.
  • attribs is an array of attributes relating to the field.

The processField* routines should return true if processing of the current record is to continue and false if any remaining fields are to be ignored and the record is considered complete.

For example, suppose you have a CSV file which contains many fields but there are three fields/columns with names, "ID", "Name" and "Price" that you want to extract. Then you can set up a data handling class like:

class TestHandler extends JDataHandlerSimple
{
   public function processFieldStartID( JDataField $field )
   {
       $this->addField( $field );
       return true;
   }
 
   public function processFieldStartName( JDataField $field )
   {
       $this->addField( $field );
       return true;
   }
 
   public function processFieldStartPrice( JDataField $field )
   {
       $this->addField( $field );
       return false;
   }
 
}

You now need to create some code to instantiate this class and set it up to process the actual data. Here is some code to get you started:

jimport( 'joomla.data.dataadapter' );
jimport( 'joomla.data.dataconnector' );
jimport( 'joomla.data.datahandler' );
 
// Instantiate an input adapter that will read and parse an XML file.
$inputConfig = array(
   'mode'    => 'input',
   'filename'    => '/var/www/be2.xml',
);
$input = JDataAdapter::getInstance( 'xml', 'JDataAdapter', $inputConfig );
 
 // Instantiate an output adapter that will put the data into the Joomla database.
$outputConfig = array(
   'mode'    => 'output',
   'table'    => 'testtable',    // Database table name
   'truncate'    => true,    // Empty table on open
);
$output1 = JDataAdapter::getInstance( 'table', 'JDataAdapter', $outputConfig );
 
// Instantiate an output adapter that will put the data into XML.
$outputConfig = array(
   'mode'    => 'output',
   'root'    => 'RawData',    // Root XML element name
);
$output2 = JDataAdapter::getInstance( 'xml', 'JDataAdapter', $outputConfig );
 
// Instantiate a connector that will be used to output the XML to a file.
$outputConnectorConfig = array(
   'filename'    => '/var/www/test/testoutput.xml',
);
$outputConnector2 = JDataConnector::getInstance( 'file', 'JDataConnector', $outputConnectorConfig );
 
// Instantiate an output adapter that will translate the data into CSV.
$outputConfig = array(
   'mode'    => 'output',
);
$output3 = JDataAdapter::getInstance( 'csv', 'JDataAdapter', $outputConfig );
 
// Instantiate a connector that will be used to output the CSV to a file.
$outputConnector3 = JDataConnector::getInstance( 'echo', 'JDataConnector' );
 
 // Instantiate the extended data handler class, attach the adapter and connectors
// to it, then execute the handler.
JDataHandler::addIncludePath( JPATH_BASE.'/test' );
$handler = JDataHandler::getInstance( 'be', 'test' )
   ->attach( $input )
   ->attach( $output1 )
   ->attach( $output2, $outputConnector2 )
   ->attach( $output3, $outputConnector3 )
   ->execute()
   ;