/** * Executes the child query and ties the result to the output of the parent query * * @param {array} $parentRows Query output of the parent query * @param {object} $child */ private function bindChild(&$parentRows, &$child) { $generalErrorMessage = "Cannot nest queries " . $this->name() . " and " . $child->name() . " - "; // This error should never occur, since the parser constructs the two childs automatically if (!$child->children || count($child->children) != 2) { throw new \Exception($generalErrorMessage . "child does not have 2 children"); } $paramID = $child->defaultParam; // Fall back in case there is no default param (should not occur anymore) if (!$paramID) { // Get parameters of second (last) child of $child. // Suppose you have "a(b)". This corresponds to parent = "a" and child = "b:a" // "b:a" has two childs: "b" and "b.a" // We should get the param of the link-query "b.a" which is the second child of $child $paramIDs = array_keys(get_object_vars($child->children[1]->params)); // There should be exactly 1 parameter if (count($paramIDs) != 1) { throw new \Exception($generalErrorMessage . "link-query " . $child->children[1]->name() . " should have exactly one parameter"); } $paramID = $paramIDs[0]; } // Get the parent key which should be matched with the childs parameter $keyIDs = array_keys(get_object_vars($this->keys)); if (count($keyIDs) != 1) { throw new \Exception($generalErrorMessage . "parent should have exactly one key"); } $parentKey = $this->keys->{$keyIDs[0]}; if (!is_array($parentRows)) { throw new \Exception($generalErrorMessage . "parentRows should be an array of associative arrays"); } if (count($parentRows) > 0 && !is_array($parentRows[0])) { throw new \Exception($generalErrorMessage . "parentRows should be an array of associative arrays"); } if (count($parentRows) > 0 && !array_key_exists($parentKey, $parentRows[0])) { throw new \Exception($generalErrorMessage . "parentRows should consist of associative arrays containing the field '" . $parentKey . "'"); } // Take root parameters as default params for child $params = $this->paramValues; // Select the child param values from the parent query output $values = array(); foreach ($parentRows as $row) { if (!in_array($row[$parentKey], $values)) { $values[] = $row[$parentKey]; } } $params[$paramID] = $values; // Execute child query and group results; cleanUp can also be done at this point $childRows = $child->group()->select($params, $paramID, true); $childFieldName = $child->prefix(); // Combine child rows with parent rows for ($i = 0; $i < count($parentRows); $i++) { $keyValue = $parentRows[$i][$parentKey]; $parentRows[$i][$childFieldName] = array_key_exists($keyValue, $childRows) ? $childRows[$keyValue] : array(); } }