View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFPROP:Proposal Zone Template}

{zone-data:component-name}
Zend_Dojo_Data - dojo.data Envelope
{zone-data}

{zone-data:proposer-list}
[~matthew]
{zone-data}

{zone-data:liaison}
TBD
{zone-data}

{zone-data:revision}
1.0 - 19 June 2008: Initial Draft.
{zone-data}

{zone-data:overview}
Dojo and other Javascript toolkits are often choosing to abstract data access for their widgets in order to allow switching data sources. Dojo does this via a variety of data stores, which consume data in the dojo.data format. dojo.data is a simple format for wrapping data sets and providing basic metadata about them:

{code:javascript}
{
identifier: <identifier attribute name>,
[ label: <label attribute name>, ]
items: [
{
<identifier attribute>: <identier>,
[<label attribute>: <label>,]
<attribute1>: <value1>,
<attribute2>: <value2>,
...
},
...
]
}
{code}

To dissect this in PHP terms, we have a structure like the following:

{code:php}
array(
'identifier' => <identifier attribute name>,
[ 'label' => <label attribute name>,]
'items' => array(
array(
'<identifier attribute>' => <identifier>,
['<label attribute>' => <label>,]
'<attribute1> => <value1>,
'<attribute2> => <value2>,
...
),
...
)
)
{code}

When using Zend Framework, however, you will rarely have a data construct that matches this. This proposal would provide a component that could consume a variety of data constructs to utilize as dojo.data items, and mutators for specifying the identifier and optional label attributes of the records in the data store. Additionally, accessors would allow for retrieving the information.

This component could then be used as a backend data store for use with Dojo's QueryReadStore. This would require serialization of the data and metadata stored in the object to JSON (which is consumed natively by QueryReadStore). While dojo supports other data stores, these data stores utilize special formats already and will not require usage of this component. As examples, the CsvStore, OpmlStore, and AtomStore all leverage the self-documenting capabilities of those formats in order to provide introspection of the returned data. The only other format of much interest to ZF developers might be the XmlStore. This store allows parsing of arbitrary XML collections. However, it's a read-write store, and would be best used with public, editable XML documents.
{zone-data}

{zone-data:references}
* [Dojo's dojo.data manual|http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/data-retrieval-dojo-data-0]
* [Mastering Dojo (book)|http://www.pragprog.com/titles/rgdojo/mastering-dojo]
{zone-data}

{zone-data:requirements}
* MUST allow attaching arbitrary data sets:
** Zend_Db_Table_Rowset_Abstract
** Arrays
** Service results
* MUST require specifying identifier attribute name
* MUST require specifying label attribute name
* MUST provide accessors and mutators to data items
* MUST serialize to JSON
** SHOULD implement string serialization proxying to JSON serialization
* MUST allow access to metadata and data within PHP
{zone-data}

{zone-data:dependencies}
* HARD depedencies
** Zend_Exception
* SOFT dependencies
** Zend_Db_Table_Rowset_Abstract
** Potentially Zend_Service consumables
{zone-data}

{zone-data:operation}
A developer will attach a data set and specify an identifier when instantiating Zend_Dojo_Data; alternately, these can be specified via mutators. Serialization will happen on demand via a toJson() method.
{zone-data}

{zone-data:milestones}
* Milestone 1: \[DONE\] Prepare this proposal
* Milestone 2: Prepare test suite and API
* Milestone 3: Complete initial implementation
* Milestone 4: Write documentation
{zone-data}

{zone-data:class-list}
* Zend_Dojo_Data
* Zend_Dojo_Data_Exception
{zone-data}

{zone-data:use-cases}
||UC-01||
h3. Specifying a Zend_Db_Table_Rowset
{code:php}
$rows = $table->fetchAll($query);

$data = new Zend_Dojo_Data($rows, 'id');
echo $data;
{code}

||UC-02||
h3. Specifying a service consumable
{code:php}
$feed = $gdata->getFeed($query);

$data = new Zend_Dojo_Data($feed, 'eventId');
echo $data;
{code}

||UC-03||
h3. Specifying an array and using accessors
{code:php}
$rows = $db->fetchAll($query);

$data = new Zend_Dojo_Data();
$data->setItems($rows)
->setIdentifier('id')
->setLabel('title');

echo $data;
{code}
{zone-data}

{zone-data:skeletons}
{code:php}
class Zend_Dojo_Data implements ArrayAccess,Iterator,Countable
{
public function __construct($items = null, $identifier = null, $label = null)
{
if (null !== $items) {
$this->setItems($items);
}
if (null !== $identifier) {
$this->setIdentifier($identifier);
}
if (null !== $label) {
$this->setLabel($label);
}
}

public function setItems($items);
public function setItem($item, $identifier = null);
public function addItem($item, $identifier = null);
public function addItems($items);
public function getItems();
public function getItem($identifier);
public function removeItem($identifier);
public function clearItems();

public function setIdentifier($identifier);
public function getIdentifier();

public function setLabel($label);
public function getLabel();

public function toJson();
public function __toString();

// interfaces
public function offsetExists($offset);
public function offsetGet($offset);
public function offsetSet($offset, $value);
public function offsetUnset($offset);

public function current();
public function key();
public function next();
public function rewind();
public function valid();

public function count();
}
{code}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>