$graph = '{"Civility":{},"Sector":{},"Country":{},"ContactSpoken":{"Lang":{}},"ContactFields":{"Field":{}}}';$x_objs = $xpdo->getCollectionGraph( $db_class, $graph, $query );
$graph = '{"Civility":{},"Sector":{},"Country":{},"ContactSpoken":{},"ContactFields":{}}';<?xml version="1.0" encoding="UTF-8"?> <model package="whoswho" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" tablePrefix="" phpdoc-package="whoswho" phpdoc-subpackage="model"> <!-- MAIN CONTACT TABLE --> <!-- main contacts --> <object class="wwContact" table="ww_contacts" extends="xPDOSimpleObject"> <field key="uuid" dbtype="varchar" precision="36" phptype="string" null="false" default="" index="unique" /> <field key="temp_id" dbtype="varchar" precision="10" phptype="string" null="false" default="" index="unique" /> <field key="confirmed" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" /> <field key="active" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" /> <field key="blocked" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" /> <field key="username" dbtype="varchar" precision="50" phptype="string" null="false" default="" index="unique" /> <field key="pseudohash" dbtype="varchar" precision="32" phptype="string" null="false" default="" /> <field key="civility_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="firstname" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> <field key="lastname" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> <field key="dob" dbtype="int" precision="8" attributes="unsigned" phptype="integer" null="false" default="0" /> <field key="image" dbtype="varchar" precision="255" phptype="string" null="true" /> <field key="sector_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="company" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> <field key="department" dbtype="varchar" precision="50" phptype="string" null="true" /> <field key="address" dbtype="varchar" precision="200" phptype="string" null="true" /> <field key="zip" dbtype="varchar" precision="20" phptype="string" null="true" /> <field key="city" dbtype="varchar" precision="50" phptype="string" null="true" /> <field key="country_i3166_1" dbtype="varchar" precision="2" phptype="string" null="false" default="" index="fk" /> <field key="email" dbtype="varchar" precision="150" phptype="string" null="false" default="" /> <field key="website" dbtype="varchar" precision="255" phptype="string" null="true" /> <field key="mobile" dbtype="varchar" precision="20" phptype="string" null="true" /> <field key="phone" dbtype="varchar" precision="20" phptype="string" null="false" default="" /> <field key="fax" dbtype="varchar" precision="20" phptype="string" null="true" /> <field key="reg_datetime" dbtype="datetime" phptype="string" null="false" default="0000-00-00 00:00:00" /> <field key="log_datetime" dbtype="datetime" phptype="string" null="false" default="0000-00-00 00:00:00" /> <!-- table relationships --> <!-- one to one --> <aggregate alias="Civility" class="civility" local="civility_id" foreign="id" cardinality="one" owner="foreign" /> <aggregate alias="Sector" class="wwSector" local="sector_id" foreign="id" cardinality="one" owner="foreign" /> <aggregate alias="Country" class="isoCountry" local="country_i3166_1" foreign="i3166_1" cardinality="one" owner="foreign" /> <!-- one to many composites --> <composite alias="ContactSpoken" class="wwSpoken" local="id" foreign="contact_id" cardinality="many" owner="local" /> <composite alias="ContactFields" class="wwContactHaswwFields" local="id" foreign="contact_id" cardinality="many" owner="local" /> <composite alias="ContactGroups" class="wwContactGroup" local="id" foreign="owner_id" cardinality="many" owner="local" /> <composite alias="ContactMessages" class="wwMessage" local="id" foreign="sender_id" cardinality="many" owner="local" /> </object> <!-- CONTACT GROUPS AND MEMBERS --> <!-- contact groups --> <object class="wwContactGroup" table="ww_contact_groups" extends="xPDOSimpleObject"> <field key="name" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> <field key="owner_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="is_global" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" /> <!-- table relationships --> <!-- one to many aggregates --> <aggregate alias="Owner" class="wwContact" local="owner_id" foreign="id" cardinality="one" owner="foreign" /> <!-- one to many composites --> <composite alias="GroupMembers" class="wwContactGroupMember" local="id" foreign="group_id" cardinality="many" owner="local" /> </object> <!-- contact group members --> <object class="wwContactGroupMember" table="ww_group_members" extends="xPDOObject"> <field key="contact_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="group_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <!-- table relationships --> <!-- one to one --> <aggregate alias="Contact" class="wwContact" local="contact_id" foreign="id" cardinality="one" owner="foreign" /> <!-- one to many aggregates --> <aggregate alias="OwnerGroup" class="wwContactGroup" local="group_id" foreign="id" cardinality="one" owner="foreign" /> </object> <!-- MESSAGES AND ATTACHMENTS --> <!-- messages --> <object class="wwMessage" table="ww_messages" extends="xPDOSimpleObject"> <field key="sender_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="timestamp" dbtype="timestamp" phptype="integer" null="false" default="0" /> <field key="subject" dbtype="varchar" precision="255" phptype="string" null="false" default="" /> <field key="content" dbtype="mediumtext" phptype="string" null="false" default="" /> <!-- table relationships --> <!-- one to many composites --> <composite alias="Recipients" class="wwRecipient" local="id" foreign="message_id" cardinality="many" owner="local" /> <composite alias="Attachments" class="wwAttachment" local="id" foreign="message_id" cardinality="many" owner="local" /> <!-- one to many aggregates --> <aggregate alias="Sender" class="wwContact" local="sender_id" foreign="id" cardinality="one" owner="foreign" /> </object> <!-- message recipients --> <object class="wwRecipient" table="ww_message_recipients" extends="xPDOObject"> <field key="message_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="recipient_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <!-- table relationships --> <!-- one to one --> <aggregate alias="Recipient" class="wwContact" local="recipient_id" foreign="id" cardinality="one" owner="foreign" /> <!-- one to many aggregates --> <aggregate alias="Message" class="wwMessage" local="message_id" foreign="id" cardinality="one" owner="foreign" /> </object> <!-- message attachments --> <object class="wwAttachment" table="ww_message_attachments" extends="xPDOSimpleObject"> <field key="file_ref" dbtype="varchar" precision="255" phptype="string" null="false" default="" /> <field key="message_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <!-- table relationships --> <!-- one to many aggregates --> <aggregate alias="Message" class="wwMessage" local="message_id" foreign="id" cardinality="one" owner="foreign" /> </object> <!-- STANDALONE REFERENCES TABLES --> <!-- activity sectors --> <object class="wwSector" table="ww_sectors" extends="xPDOSimpleObject"> <field key="active" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="1" /> <field key="en" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <field key="fr" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> </object> <!-- activity fields --> <object class="wwField" table="ww_fields" extends="xPDOSimpleObject"> <field key="active" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="1" /> <field key="group_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" index="fk" /> <field key="en" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <field key="fr" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <!-- table relationships --> <!-- one to many aggregates --> <aggregate alias="FieldGroup" class="wwFieldGroup" local="group_id" foreign="id" cardinality="one" owner="foreign" /> <!-- many to many --> <composite alias="ContactFields" class="wwField" local="id" foreign="field_id" cardinality="many" owner="local" /> </object> <!-- field groups --> <object class="wwFieldGroup" table="ww_field_groups" extends="xPDOSimpleObject"> <field key="en" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <field key="fr" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <!-- table relationships --> <!-- one to many composites --> <composite alias="GroupFields" class="wwField" local="id" foreign="group_id" cardinality="many" owner="local" /> </object> <!-- many to many ww_contacts to ww_fields relationship --> <object class="wwContactHaswwFields" table="ww_contacts_has_ww_fields" extends="xPDOObject"> <field key="contact_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="" index="pk" /> <field key="field_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="" index="pk" /> <!-- table relationships --> <!-- many to many --> <aggregate alias="Contact" class="wwContact" local="contact_id" foreign="id" cardinality="one" owner="foreign" /> <aggregate alias="Field" class="wwField" local="field_id" foreign="id" cardinality="one" owner="foreign" /> </object> <!-- civilities translations --> <object class="civility" table="civilities" extends="xPDOSimpleObject"> <field key="en_short" dbtype="varchar" precision="50" phptype="string" null="false" default=""/> <field key="en_long" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> <field key="fr_short" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> <field key="fr_long" dbtype="varchar" precision="50" phptype="string" null="false" default="" /> </object> <!-- iso-3166-1 country codes --> <object class="isoCountry" table="iso_countries" extends="xPDOObject"> <field key="i3166_1" dbtype="varchar" precision="2" phptype="string" null="false" default="" index="pk" /> <field key="active" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="1" /> <field key="en" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <field key="fr" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> </object> <!-- iso-639-1/2 language codes --> <object class="isoLang" table="iso_langs" extends="xPDOObject"> <field key="i639_1" dbtype="varchar" precision="2" phptype="string" null="false" default="" index="pk" /> <field key="i639_2" dbtype="varchar" precision="7" phptype="string" null="false" default="" index="index" /> <field key="active" dbtype="int" precision="1" attributes="unsigned" phptype="integer" null="false" default="1" /> <field key="utf_8" dbtype="varchar" precision="255" phptype="string" null="false" default="" /> <field key="en" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <field key="fr" dbtype="varchar" precision="200" phptype="string" null="false" default="" /> <!-- one to many composites --> <composite alias="SpokenLangs" class="isoLang" local="i639_1" foreign="lang_i639_1" cardinality="many" owner="local" /> </object> <!-- many to many ww_contacts to iso_langs --> <object class="wwSpoken" table="ww_spoken" extends="xPDOObject"> <field key="contact_id" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="" index="pk" /> <field key="lang_i639_1" dbtype="varchar" precision="2" phptype="string" null="false" default="" index="pk" /> <!-- table relationships --> <!-- many to many --> <aggregate alias="Contact" class="wwContact" local="contact_id" foreign="id" cardinality="one" owner="foreign" /> <aggregate alias="Lang" class="isoLang" local="lang_i639_1" foreign="i639_1" cardinality="one" owner="foreign" /> </object> </model>
/**
* read - record(s) data recovery
*
* @param array $filter - ? list of "where" conditions formatted as: '(and,or)|field_name:(=,!=,>,>=,<,<=,LIKE)|value'
* @param array $fields - optional list of field name(s) to select in query
* @param string $graph - optional a graph object listing the db relation aliases used for joining related tables
* format is in JSON notation {"rel_alias_0":{},"rel_alias_1":{"rel_alias_2":{}}}
*
* @return array - containing the data set
*/
public function read( $filter, $fields = false, $graph = false ) {
/*** prepare new xPDO query ***/
$this->query = $this->xpdo_instance->newQuery( $this->db_class );
# retain only fields specified in $fields parameter (if any) otherwise retain all
$base_fields = $fields;
$fields = ( $fields ) ? $fields : array_keys( $this->xpdo_instance->getFields( $this->db_class ));
/*
* the primary key(s) is (are) required for the query to execute properly, so we add it (them) if necessary
*/
$pk = $this->xpdo_instance->getPK( $this->db_class );
if ( !is_array( $pk ) && $pk != null ) {
$pk = array( $pk );
}
if ( $pk != null ) {
$fields = array_unique( array_merge( $fields, $pk ));
}
# the $fields are safe now
$select_columns = $this->xpdo_instance->getSelectColumns( $this->db_class, $this->db_class, '', $fields );
$this->query->select( $select_columns );
# build query based on specified conditions
# TODO -> check if filter is required for the query to function
if ( $filter ) {
$this->filterToConditions( $filter );
}
/*** collect objects ***/
if ( $graph ) {
# when $graph parameter is specified, use collectionGraph
$x_objs = $this->xpdo_instance->getCollectionGraph( $this->db_class, $graph, $this->query );
}
else {
# standard collection - no table relation specified
$x_objs = $this->xpdo_instance->getCollection( $this->db_class, $this->query );
}
$this->debug->log($x_objs,'x_objs');
/*** extract fields data ***/
$data = array();
foreach( $x_objs as $x_obj ) {
# collect graph data if any
$j_data = array();
if ( $graph ) {
$j_data = $this->extractGraphData( $graph, $x_obj );
}
array_push( $data, array_merge( $x_obj->toArray(), $j_data ) );
}
/*
* when using graph (getCollectionGraph) all fields are returned -> filter them out if necessary (only first level of data array)
*/
if ( $base_fields ) {
$filtered = array();
foreach ( $data as $key => $row ) {
$f_row = array();
foreach ( $base_fields as $field ) {
if ( array_key_exists( $field, $row )) {
$f_row[$field] = $row[$field];
}
}
$filtered[$key] = $f_row;
}
$data = $filtered;
}
# return result set
return $data;
}/**
* filterToConditions - parses a filer array creating and / or conditions in the query object
*
* @param array $filer - required list of "where" conditions formatted as: '(and,or)|field_name:(=,!=,>,>=,<,<=,LIKE)|value'
*/
private function filterToConditions( $filter ) {
foreach ( $filter as $condition_txt ) {
$condition_list = explode( '|', $condition_txt );
# check numerical value
$condition_list[2] = ( $condition_list[2] === (int)$condition_list[2] ) ? (int)$condition_list[2] : $condition_list[2];
# check php code
if ( stripos( $condition_list[2], '<?' ) !== false ) {
$condition_list[2] = str_replace( '<?', '', $condition_list[2] );
$condition_list[2] = stripslashes( $condition_list[2] );
if (( stripos( $condition_list[2], '$_SESSION' ) !== false ) && !isset( $_SESSION )) {
session_start();
}
eval ( '$condition_list[2] = ' . $condition_list[2] . ';' );
}
$condition = array( $condition_list[1] => $condition_list[2] );
if ( strripos( $condition_list[0], 'and' ) !== false ) {
$this->query->andCondition( $condition );
}
else {
$this->query->orCondition( $condition );
}
}
}/**
* extractGraphData - recursively parses a collectionGraph object to extract data based on graph's defined relationships
*
* @param string $graph - optional a graph object listing the db relation aliases used for joining related tables
* format is in JSON notation {"rel_alias_0":{},"rel_alias_1":{"rel_alias_2":{}}}
* @param abject $db_obj an xPDO object collection returned by the getCollectionGraph method with same graph applied
*
* @return array - a possibly multi-dimensional array containing the objects data with graph names as keys for relational data
*/
private function extractGraphData( $graph, $db_obj ) {
$graph = json_decode( $graph );
foreach( $graph as $join => $v ) {
if ( is_array( $db_obj->$join )) {
$count = 0;
foreach( $db_obj->$join as $x_join ) {
$xj_data[$count] = ( $x_join != null && !empty( $x_join )) ? $x_join->toArray() : null;
if ( count( get_object_vars( $v )) > 0) {
$xj_data[$count] = array_merge( $xj_data[$count], $this->extractGraphData( json_encode ( $v ), $x_join ));
$count++;
}
}
$j_data[$join] = $xj_data;
}
else {
$j_data[$join] = ( $db_obj->$join != null && !empty( $db_obj->$join )) ? $db_obj->$join->toArray() : null;
if ( count( get_object_vars( $v )) > 0) {
$j_data[$join] = array_merge( $j_data[$join], $this->extractGraphData( json_encode ( $v ), $x_join ));
}
}
}
return $j_data;
}