Esempio n. 1
0
 /**
  * Return the XML object as an XML string
  * 
  * @return string
  */
 public function asXML($todo_for_empty_elements = true, $indent = "\t")
 {
     return $this->_root->asXML();
 }
Esempio n. 2
0
    /** 
     * Send an *Add request to QuickBooks to add an object to the QuickBooks database
     * 
     * @param string $type			The QuickBooks object type
     * @param object $Object		The object to add to QuickBooks
     * @param string $requestID		The requestID to use in the qbXML request
     * @param string $user			The username of the Web Connector user
     * @param string $action		The action type (example: "CustomerAdd", QUICKBOOKS_ADD_CUSTOMER)
     * @param string $ID			The qbsql_id value of the object to add
     * @param mixed $extra			Any extra data 
     * @param string $err			Set this to an error message if an error occurs
     * @param integer $last_action_time			The UNIX timestamp indicating the last time this type of action occured
     * @param integer $last_actionident_time	The UNIX timestamp indicating the (last time this type of action and $ID value) occured
     * @param float $version		The maximum qbXML version supports
     * @param string $locale		The QuickBooks locale (example: "US")
     * @param array $config			Callback configuration information
     * @return string				The qbXML string 
     */
    protected static function _AddRequest($type, $Object, $requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array())
    {
        // Driver instance...
        $Driver = QuickBooks_Driver_Singleton::getInstance();
        $type = strtolower($type);
        // This should actually always happen now that we fixed the Driver->get method to return an array
        if (!is_object($Object) and is_array($Object)) {
            $Object = new QuickBooks_SQL_Object(null, null, $Object);
        }
        $xml = '';
        $xml .= '<?xml version="1.0" encoding="utf-8"?>' . QUICKBOOKS_CRLF;
        $xml .= '<?qbxml version="' . QuickBooks_Callbacks_SQL_Callbacks::_version($version, $locale) . '"?>' . QUICKBOOKS_CRLF;
        $xml .= "\t" . '<QBXML>' . QUICKBOOKS_CRLF;
        $xml .= "\t" . "\t" . '<QBXMLMsgsRq onError="' . QUICKBOOKS_SERVER_SQL_ON_ERROR . '">' . QUICKBOOKS_CRLF;
        $xml .= "\t" . "\t" . "\t" . '<' . QuickBooks_Utilities::actionToRequest($action) . ' requestID="' . $requestID . '">' . QUICKBOOKS_CRLF;
        $file = '/QuickBooks/QBXML/Schema/Object/' . QuickBooks_Utilities::actionToRequest($action) . '.php';
        $class = 'QuickBooks_QBXML_Schema_Object_' . QuickBooks_Utilities::actionToRequest($action);
        QuickBooks_Loader::load($file);
        $schema_object = new $class();
        //print_r($Object->asArray());
        //exit;
        $Node = new QuickBooks_XML_Node($action);
        foreach ($Object->asArray() as $field => $value) {
            $map = '';
            $others = array();
            QuickBooks_SQL_Schema::mapToSchema($type . '.' . $field, QUICKBOOKS_SQL_SCHEMA_MAP_TO_XML, $map, $others);
            // Some drivers case fold all of the field names, which means that
            //	we can't depend on the field names to use in our XML requests
            //
            // If that happens, we need to go over to the schema object and
            //	try to fetch the correct, unfolded XML node name and set that
            //	instead.
            $unmapped = null;
            if ($Driver->foldsToLower()) {
                $unmapped = $map;
                $retpos = strpos($map, 'Ret ');
                $retval = substr($map, 0, $retpos + 4);
                $map = substr($map, $retpos + 4);
                $map = $retval . $schema_object->unfold($map);
            }
            //print('dealing with: [' . $map . '] unmapped from (' . $unmapped . ')' . "\n");
            if (!$map) {
                // This schema field doesn't map to anything in QuickBooks...
                continue;
            } else {
                if (!strlen($value)) {
                    // There's no value there, don't send it
                    // There are some special cases here... addresses commonly get
                    //	changes to set blank lines for some of the address lines,
                    //	and we need to send these blank values to overwrite the
                    //	existing values in QuickBooks.
                    //
                    // Here, we send these blank address lines only if at least one
                    //	address line is being sent.
                    $begi = substr($field, 0, -5);
                    $last = substr($field, -5, 5);
                    if (($last == 'Addr2' or $last == 'Addr3' or $last == 'Addr4' or $last == 'Addr5') and strlen($Object->get($begi . 'Addr1'))) {
                        // ... but don't allow 4 or 5 if they set the city, state, zip, or country?
                        //  EDIT: NEVER ALLOW ADDR4 OR ADDR5, IT JUST F***S SHIT UP! I HATE YOU INTUIT!
                        //   WHAT DOES THIS MEAN?!?   "The &quot;address&quot; field has an invalid value &quot;&quot;.  QuickBooks error message: The parameter is incorrect."
                        if ($last == 'Addr4' or $last == 'Addr5') {
                            continue;
                        }
                        /* and 
                        				( strlen($Object->get($begi . 'City')) or strlen($Object->get($begi . 'State')) or strlen($Object->get($begi . 'Country')) or strlen($Object->get($begi . 'PostalCode')) ))
                        			{
                        				continue;
                        			}
                        			*/
                        // <Judge Roy Snyder>... I'll allow it!
                    } else {
                        continue;
                    }
                } else {
                    if ($value == QUICKBOOKS_SERVER_SQL_VALUE_CLEAR) {
                        $value = '';
                    }
                    $use_abbrevs = false;
                    $htmlspecialchars = true;
                    //print('THIS RAN [' . $value . ']');
                    $value = QuickBooks_Cast::cast(null, null, $value, $use_abbrevs, $htmlspecialchars);
                    //print(' => [' . $value . ']' . "\n");
                }
            }
            // Special handling for non-US versions of QuickBooks
            $begi = substr($field, 0, -5);
            $last = substr($field, -5, 5);
            if ($locale == QUICKBOOKS_LOCALE_UK and $last == 'State' and !strlen($Object->get($begi . 'County'))) {
                $Object->set($begi . 'County', $value);
                //print_r($map);
                $map = substr($map, 0, -5) . 'County';
                //die();
            }
            // OK, the paths look like this:
            // 	CustomerRet FirstName
            //
            // We don't need the 'CustomerRet' part of it, that's actually incorrect, so we'll strip it off
            $explode = explode(' ', $map);
            $first = trim(current($explode));
            $map = trim(implode(' ', array_slice($explode, 1)));
            if (stripos($action, 'add') !== false) {
                $map = str_replace('Ret', 'Add', $map);
            } else {
                $map = str_replace('Ret', 'Mod', $map);
            }
            //print('	OK, handling [' . $map . ']' . "\n");
            if (false === strpos($map, ' ')) {
                if ($schema_object->exists($map)) {
                    $use_in_request = true;
                    // If this version doesn't support this field, skip it
                    if ($schema_object->sinceVersion($map) > $version and $schema_object->sinceVersion($map) < 100.0) {
                        $use_in_request = false;
                    }
                    switch ($schema_object->dataType($map)) {
                        case 'AMTTYPE':
                            $value = str_replace(',', '', number_format($value, 2));
                            break;
                        case 'DATETYPE':
                            if (!$value or $value == '0000-00-00') {
                                $use_in_request = false;
                            } else {
                                $value = QuickBooks_Utilities::date($value);
                            }
                            break;
                        case 'DATETIMETYPE':
                            if (!$value or $value == '0000-00-00 00:00:00') {
                                $use_in_request = false;
                            } else {
                                $value = QuickBooks_Utilities::datetime($value);
                            }
                            break;
                        case 'BOOLTYPE':
                            if ($value == 1) {
                                $value = 'true';
                            } else {
                                if ($value == 0) {
                                    $value = 'false';
                                } else {
                                    $use_in_request = false;
                                }
                            }
                            break;
                        default:
                            break;
                    }
                    if ($use_in_request) {
                        $Child = new QuickBooks_XML_Node($map);
                        $Child->setData($value);
                        $Node->addChild($Child);
                    }
                } else {
                    // ignore it
                }
            } else {
                $parts = explode(' ', $map);
                foreach ($parts as $key => $part) {
                    if (stripos($action, 'Mod') !== false) {
                        if ($part == 'SalesAndPurchase' or $part == 'SalesOrPurchase') {
                            $parts[$key] = $part . 'Mod';
                        }
                    } else {
                        if (stripos($action, 'Add') !== false) {
                        }
                    }
                }
                $map = implode(' ', $parts);
                if ($schema_object->exists($map)) {
                    $use_in_request = true;
                    // If this version doesn't support this field, skip it
                    if ($schema_object->sinceVersion($map) > $version and $schema_object->sinceVersion($map) < 100.0) {
                        $use_in_request = false;
                    }
                    switch ($schema_object->dataType($map)) {
                        case 'AMTTYPE':
                            $value = str_replace(',', '', number_format($value, 2));
                            break;
                        case 'DATETYPE':
                            if (!$value or $value == '0000-00-00') {
                                $use_in_request = false;
                            } else {
                                $value = QuickBooks_Utilities::date($value);
                            }
                            break;
                        case 'DATETIMETYPE':
                            if (!$value or $value == '0000-00-00 00:00:00') {
                                $use_in_request = false;
                            } else {
                                $value = QuickBooks_Utilities::datetime($value);
                            }
                            break;
                        case 'BOOLTYPE':
                            if ($value == 1) {
                                $value = 'true';
                            } else {
                                if ($value == 0) {
                                    $value = 'false';
                                } else {
                                    $use_in_request = false;
                                }
                            }
                            break;
                        default:
                            break;
                    }
                    if ($use_in_request) {
                        $Node->setChildDataAt($action . ' ' . $map, $value, true);
                    }
                }
            }
        }
        // Get the child tables here - make sure they're in the proper order for the xml schema
        $children = QuickBooks_Callbacks_SQL_Callbacks::_getChildTables(strtolower($type));
        //print('for type: [' . $type . ']');
        //print_r($children);
        //exit;
        if (!empty($children)) {
            $data = QuickBooks_Callbacks_SQL_Callbacks::_queryChildren($children, $Object->get($children[0]['parent']));
        } else {
            // @todo Why not just assign an empty array here...?
            $data = $children;
        }
        $nodes = QuickBooks_Callbacks_SQL_Callbacks::_childObjectsToXML(strtolower($type), $action, $data);
        //print('NODES:');
        //print_r($nodes);
        //exit;
        if (count($nodes)) {
            foreach ($nodes as $nd) {
                $Node->addChild($nd);
            }
        } else {
            // If we're adding a payment, but not applying it to anything, set IsAutoApply to TRUE
            if ($action == QUICKBOOKS_ADD_RECEIVEPAYMENT) {
                $Node->setChildDataAt($action . ' IsAutoApply', 'true', true);
            } else {
                if ($action == QUICKBOOKS_MOD_RECEIVEPAYMENT) {
                }
            }
        }
        //print('ACTION IS: [' . $action . ']');
        //print_r($Node);
        $xml .= $Node->asXML(QuickBooks_XML::XML_PRESERVE);
        // Bad hack...
        $xml = str_replace('&amp;#', '&#', $xml);
        $xml = str_replace('&amp;amp;', '&amp;', $xml);
        $xml = str_replace('&amp;quot;', '&quot;', $xml);
        $xml .= '</' . QuickBooks_Utilities::actionToRequest($action) . '>
				</QBXMLMsgsRq>
			</QBXML>';
        return $xml;
    }
Esempio n. 3
0
 public function asQBXML($request, $version = null, $locale = null, $root = null)
 {
     $todo_for_empty_elements = QuickBooks_XML::XML_DROP;
     $indent = "\t";
     // Call any cleanup routines
     $this->_cleanup();
     //
     if (strtolower(substr($request, -2, 2)) != 'rq') {
         $request .= 'Rq';
     }
     $Request = new QuickBooks_XML_Node($request);
     if ($schema = $this->_schema($request)) {
         $tmp = array();
         // Restrict it to a specific qbXML version?
         if ($version) {
         }
         // Restrict it to a specific qbXML locale?
         if ($locale) {
             // List of fields which are not supported for some versions of qbXML
             if (strlen($locale) == 2) {
                 // The OSR lists locales as 'QBOE', 'QBUK', 'QBCA', etc. vs. our QUICKBOOKS_LOCALE_* constants of just 'OE', 'UK', 'CA', etc.
                 $locale = 'QB' . $locale;
             }
             $locales = $schema->localePaths();
         }
         $thelist = $this->asList($request);
         $reordered = $schema->reorderPaths(array_keys($thelist));
         foreach ($reordered as $key => $path) {
             $value = $this->_object[$path];
             if (is_array($value)) {
                 $tmp[$path] = array();
                 foreach ($value as $arr) {
                     $tmp2 = array();
                     foreach ($arr->asList('') as $inkey => $invalue) {
                         $arr->set($path . ' ' . $inkey, $invalue);
                     }
                     foreach ($schema->reorderPaths(array_keys($arr->asList(''))) as $subkey => $subpath) {
                         // We need this later, so store it
                         $fullpath = $subpath;
                         if ($locale and isset($locales[$subpath])) {
                             if (in_array($locale, $locales[$subpath])) {
                                 //
                                 //print('found: ' . $subpath . ' (' . $locale . ') so skipping!' . "\n");
                             } else {
                                 $subpath = substr($subpath, strlen($path) + 1);
                                 $tmp2[$subpath] = $arr->get($subpath);
                             }
                         } else {
                             $subpath = substr($subpath, strlen($path) + 1);
                             $tmp2[$subpath] = $arr->get($subpath);
                         }
                         if ($schema->dataType($fullpath) == QUICKBOOKS_QBXML_SCHEMA_TYPE_AMTTYPE and isset($tmp2[$subpath])) {
                             $tmp2[$subpath] = sprintf('%01.2f', $tmp2[$subpath]);
                         }
                     }
                     $tmp2 = new QuickBooks_QBXML_Object_Generic($tmp2, $arr->object());
                     $tmp[$path][] = $tmp2;
                 }
             } else {
                 // Do some simple data type casting...
                 if ($schema->dataType($path) == QUICKBOOKS_QBXML_SCHEMA_TYPE_AMTTYPE) {
                     $this->_object[$path] = sprintf('%01.2f', $this->_object[$path]);
                 }
                 if ($locale and isset($locales[$path])) {
                     // Check to see if it's supported by the given locale
                     if (in_array($locale, $locales[$path])) {
                         // It's not supported by this locale, don't show add it
                     } else {
                         $tmp[$path] = $this->_object[$path];
                     }
                 } else {
                     // If we don't know whether or not it's supported, return it!
                     $tmp[$path] = $this->_object[$path];
                 }
             }
         }
         // *DO NOT* change the source values of the original object!
         //$this->_object = $tmp;
         if ($wrapper = $schema->qbxmlWrapper()) {
             $Node = $this->asXML($wrapper, null, $tmp);
             $Request->addChild($Node);
             return $Request->asXML($todo_for_empty_elements, $indent);
         } else {
             if (count($this->_object) == 0) {
                 // This catches the cases where we just want to get *all* objects
                 //	back (no filters) and thus the root level qbXML element is *empty*
                 //	and we need to *preserve* this empty element rather than just
                 //	drop it (which results in an empty string, and thus invalid query)
                 $Node = $this->asXML($request, null, $tmp);
                 return $Node->asXML(QuickBooks_XML::XML_PRESERVE, $indent);
             } else {
                 $Node = $this->asXML($request, null, $tmp);
                 return $Node->asXML($todo_for_empty_elements, $indent);
             }
         }
     }
     return '';
 }
Esempio n. 4
0
    /** 
     * Send an *Add request to QuickBooks to add an object to the QuickBooks database
     * 
     * @param string $type			The QuickBooks object type
     * @param object $Object		The object to add to QuickBooks
     * @param string $requestID		The requestID to use in the qbXML request
     * @param string $user			The username of the Web Connector user
     * @param string $action		The action type (example: "CustomerAdd", QUICKBOOKS_ADD_CUSTOMER)
     * @param string $ID			The qbsql_id value of the object to add
     * @param mixed $extra			Any extra data 
     * @param string $err			Set this to an error message if an error occurs
     * @param integer $last_action_time			The UNIX timestamp indicating the last time this type of action occured
     * @param integer $last_actionident_time	The UNIX timestamp indicating the (last time this type of action and $ID value) occured
     * @param float $version		The maximum qbXML version supports
     * @param string $locale		The QuickBooks locale (example: "US")
     * @param array $config			Callback configuration information
     * @return string				The qbXML string 
     */
    protected static function _AddRequest($type, $Object, $requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array())
    {
        $type = strtolower($type);
        $xml = '';
        $xml .= '<?xml version="1.0" encoding="utf-8"?>' . QUICKBOOKS_CRLF;
        $xml .= '<?qbxml version="' . QuickBooks_Server_SQL_Callbacks::_version($version, $locale) . '"?>' . QUICKBOOKS_CRLF;
        $xml .= "\t" . '<QBXML>' . QUICKBOOKS_CRLF;
        $xml .= "\t" . "\t" . '<QBXMLMsgsRq onError="' . QUICKBOOKS_SERVER_SQL_ON_ERROR . '">' . QUICKBOOKS_CRLF;
        $xml .= "\t" . "\t" . "\t" . '<' . QuickBooks_Utilities::actionToRequest($action) . ' requestID="' . $requestID . '">' . QUICKBOOKS_CRLF;
        $file = 'QuickBooks/QBXML/Schema/Object/' . QuickBooks_Utilities::actionToRequest($action) . '.php';
        $class = 'QuickBooks_QBXML_Schema_Object_' . QuickBooks_Utilities::actionToRequest($action);
        require_once $file;
        $schema_object = new $class();
        $Node = new QuickBooks_XML_Node($action);
        foreach ($Object->asArray() as $field => $value) {
            $map = '';
            $others = array();
            QuickBooks_SQL_Schema::mapToSchema($type . '.' . $field, QUICKBOOKS_SQL_SCHEMA_MAP_TO_XML, $map, $others);
            /*
            print($field . ' => ' . $value . "\n");
            print_r($map);
            print("\n\n");
            */
            if (!strlen($value)) {
                continue;
            } else {
                if (stripos($type, 'dataext') !== false) {
                    // DataExt related fields
                    $field = str_replace("_", " ", $field);
                    if (false === strpos($field, ' ')) {
                        if ($schema_object->exists($field)) {
                            switch ($schema_object->dataType($field)) {
                                case 'AMTTYPE':
                                    $value = str_replace(",", "", number_format($value, 2));
                                    break;
                                default:
                                    break;
                            }
                            if ($field == "DataExtValue" and $Object->get("DataExtType") == "AMTTYPE") {
                                $value = str_replace(",", "", number_format($value, 2));
                            }
                            $Child = new QuickBooks_XML_Node($map);
                            $Child->setData($value);
                            $Node->addChild($Child);
                        } else {
                            //ignore it
                        }
                    } else {
                        if ($schema_object->exists($field)) {
                            $use_in_request = true;
                            switch ($schema_object->dataType($field)) {
                                case 'AMTTYPE':
                                    $value = str_replace(",", "", number_format($value, 2));
                                    break;
                                case 'BOOLTYPE':
                                    if ($value == 1) {
                                        $value = 'true';
                                    } else {
                                        if ($value == 0) {
                                            $value = 'false';
                                        } else {
                                            $use_in_request = false;
                                        }
                                    }
                                    break;
                                default:
                                    break;
                            }
                            if ($use_in_request) {
                                $Node->setChildDataAt($action . ' ' . $field, $value, true);
                            }
                        }
                    }
                    continue;
                } else {
                    if (!$map) {
                        continue;
                    }
                }
            }
            // OK, the paths look like this:
            // 	CustomerRet FirstName
            //
            // We don't need the 'CustomerRet' part of it, that's actually incorrect, so we'll strip it off
            $explode = explode(' ', $map);
            $first = trim(current($explode));
            $map = trim(implode(' ', array_slice($explode, 1)));
            if (stripos($action, "add") !== false) {
                $map = str_replace("Ret", "Add", $map);
            } else {
                $map = str_replace("Ret", "Mod", $map);
            }
            if (false === strpos($map, ' ')) {
                if ($schema_object->exists($map)) {
                    $use_in_request = true;
                    switch ($schema_object->dataType($map)) {
                        case 'AMTTYPE':
                            $value = str_replace(',', '', number_format($value, 2));
                            break;
                        case 'DATETYPE':
                            if (!$value or $value == '0000-00-00') {
                                $use_in_request = false;
                            }
                            break;
                        case 'BOOLTYPE':
                            if ($value == 1) {
                                $value = 'true';
                            } else {
                                if ($value == 0) {
                                    $value = 'false';
                                } else {
                                    $use_in_request = false;
                                }
                            }
                            break;
                        default:
                            break;
                    }
                    if ($use_in_request) {
                        $Child = new QuickBooks_XML_Node($map);
                        $Child->setData($value);
                        $Node->addChild($Child);
                    }
                } else {
                    //ignore it
                }
            } else {
                $tempParts = explode(' ', $map);
                foreach ($tempParts as $key => $part) {
                    if (stripos($action, "Mod") !== false) {
                        if ($part == "SalesAndPurchase" or $part == "SalesOrPurchase") {
                            $tempParts[$key] = $part . "Mod";
                        }
                    } else {
                        if (stripos($action, "Add") !== false) {
                        }
                    }
                }
                $map = implode(' ', $tempParts);
                if ($schema_object->exists($map)) {
                    $use_in_request = true;
                    switch ($schema_object->dataType($map)) {
                        case 'AMTTYPE':
                            $value = str_replace(",", "", number_format($value, 2));
                            break;
                        case 'BOOLTYPE':
                            if ($value == 1) {
                                $value = 'true';
                            } else {
                                if ($value == 0) {
                                    $value = 'false';
                                } else {
                                    $use_in_request = false;
                                }
                            }
                            break;
                        default:
                            break;
                    }
                    if ($use_in_request) {
                        $Node->setChildDataAt($action . ' ' . $map, $value, true);
                    }
                }
            }
        }
        //Get the Children Tables here -- make sure they're in the proper order for the xml schema
        $daKids = QuickBooks_Server_SQL_Callbacks::_GetChildrenTables(strtolower($type));
        //mail("*****@*****.**", "April16PO", $action."\n\n".strtolower($type)."\n\n".var_export($daKids));
        if (!empty($daKids)) {
            $kidData = QuickBooks_Server_SQL_Callbacks::_QueryChildren($daKids, $Object->get($daKids[0]['parentKey']));
        } else {
            $kidData = $daKids;
        }
        $nodes = QuickBooks_Server_SQL_Callbacks::_ChildObjectsToXML(strtolower($type), $action, $kidData);
        if (count($nodes)) {
            foreach ($nodes as $nd) {
                $Node->addChild($nd);
            }
        } else {
            // If we're adding a payment, but not applying it to anything, set IsAutoApply to TRUE
            if ($action == QUICKBOOKS_ADD_RECEIVEPAYMENT) {
                $Node->setChildDataAt($action . ' IsAutoApply', 'true', true);
            } else {
                if ($action == QUICKBOOKS_MOD_RECEIVEPAYMENT) {
                }
            }
        }
        //print($Node->asXML());
        $xml .= $Node->asXML();
        $xml .= '</' . QuickBooks_Utilities::actionToRequest($action) . '>
				</QBXMLMsgsRq>
			</QBXML>';
        return $xml;
    }
Esempio n. 5
0
File: Object.php Progetto: rme/pm2qb
 /**
  * Convert this object to a valid qbXML request/response
  * 
  * @todo What should this function return if a schema can't be found...? 
  * 
  * @param boolean $compress_empty_elements
  * @param string $indent
  * @param string $root
  * @return string
  */
 public function asQBXML($request, $todo_for_empty_elements = QUICKBOOKS_XML_XML_DROP, $indent = "\t", $root = null)
 {
     if (strtolower(substr($request, -2, 2)) != 'rq') {
         $request .= 'Rq';
     }
     $Request = new QuickBooks_XML_Node($request);
     if ($schema = $this->_schema($request)) {
         $tmp = array();
         //print_r(array_keys($this->asList($request)));
         foreach ($schema->reorderPaths(array_keys($this->asList($request))) as $key => $path) {
             $value = $this->_object[$path];
             if (is_array($value)) {
                 $tmp[$path] = array();
                 foreach ($value as $arr) {
                     $tmp2 = array();
                     foreach ($arr->asList('') as $inkey => $invalue) {
                         $arr->set($path . ' ' . $inkey, $invalue);
                     }
                     foreach ($schema->reorderPaths(array_keys($arr->asList(''))) as $subkey => $subpath) {
                         $subpath = substr($subpath, strlen($path) + 1);
                         $tmp2[$subpath] = $arr->get($subpath);
                     }
                     $tmp2 = new QuickBooks_Object_Generic($tmp2, $arr->object());
                     $tmp[$path][] = $tmp2;
                 }
             } else {
                 $tmp[$path] = $this->_object[$path];
             }
         }
         $this->_object = $tmp;
         if ($wrapper = $schema->qbxmlWrapper()) {
             $Node = $this->asXML($wrapper);
             $Request->addChild($Node);
             return $Request->asXML($todo_for_empty_elements, $indent);
         } else {
             if (count($this->_object) == 0) {
                 // This catches the cases where we just want to get *all* objects
                 //	back (no filters) and thus the root level qbXML element is *empty*
                 //	and we need to *preserve* this empty element rather than just
                 //	drop it (which results in an empty string, and thus invalid query)
                 $Node = $this->asXML($request);
                 return $Node->asXML(QUICKBOOKS_XML_XML_PRESERVE, $indent);
             } else {
                 $Node = $this->asXML($request);
                 return $Node->asXML($todo_for_empty_elements, $indent);
             }
         }
     }
     return '';
 }