private static function removeRecursive(Wallop &$object, $id = 0, $keepRelatives = false) { if (isset($object->id)) { $objectId = $object->id; } else { $objectId = $id; // We'll need the object id for the getRelatives call // if the keepRelatives flag is set if ($keepRelatives) { $object->id = $id; } } global $database; foreach ($object->aggregates as $aggrRelTableName => &$aggregate) { // If the flag to keep relatives is set then get all aggregates // and store as newObjects if ($keepRelatives) { if (isset($aggregate['modifiedObjects'])) { // Create an inList so we don't query what we don't have to // then move the modifiedObject id to newObject $inList = '('; foreach ($aggregate['modifiedObjects'] as $aggrId => $unused) { $inList .= $aggrId . ','; $aggregate['newObjects'][$aggrId] = true; } $inList = trim($inList, ',') . ')'; } $objs = $object->getRelatives($aggrRelTableName, 0, -1, '', '', isset($inList) ? 'other.`id` NOT IN ' . $inList : ''); $i = 0; $numObjs = count($objs); while ($i != $numObjs) { $aggregate['objects'][$objs[$i]->id] = $objs[$i]; $aggregate['newObjects'][$objs[$i]->id] = true; ++$i; } } else { unset($aggregate['objects']); unset($aggregate['modifiedObjects']); unset($aggregate['newObjects']); unset($aggregate['removedStoredObjects']); unset($aggregate['uninitializedNewObjects']); } unset($aggregate['modifiedObjects']); // Generate this column $thisColumn = $object->generateThisColumn($aggrRelTableName); if (!$thisColumn) { end($object->errors); self::$staticErrors[] = $object->errors[key($object->errors)]; return false; } // Delete the records on the relation table $query = 'DELETE FROM `' . $aggrRelTableName . '` WHERE `' . $thisColumn . '` = ?'; $result = $database->execQuery($query, $objectId); if (!$result) { $staticError = 'Failed to delete the records on the relation table '; $staticError .= '`' . $aggrRelTableName . '`. '; $staticError .= 'This was likely due to a mismatch between the database structure and the '; $staticError .= 'columns and/or table name you specified in the constructor of this object!'; self::$staticErrors[] = $staticError; return false; } } foreach ($object->composites as $compRelTableName => &$composite) { $compositeData = $object->findRelationData($compRelTableName); $compObj = new $compositeData['className'](); // Generate the relation columns $columnNames = $object->generateRelationColumns($compRelTableName, $compObj); if (!$columnNames) { end($object->errors); self::$staticErrors[] = $object->errors[key($object->errors)]; return false; } // Now that we have retrieved the ids of our composites $compIds = self::hasNoCompositeRelatives($compObj, $columnNames['relative'], $compRelTableName, $objectId, $columnNames['this']); // Just return false, the public function using this function will use the error created // by hasNoCompositeRelatives() to explain what happened if (!$compIds && !is_array($compIds)) { return false; } // If the flag to keep relatives is set then get all aggregates // and store as newObjects if ($keepRelatives) { if (isset($composite['modifiedObjects'])) { // Create an inList so we don't query what we don't have to // then move the modifiedObject id to newObject $inList = '('; foreach ($composite['modifiedObjects'] as $modId => $unused) { if (!isset($compIds[$modId])) { $inList .= $modId . ','; $composite['newObjects'][$modId] = true; } } foreach ($compIds as $compId => $unused) { $inList .= $compId . ','; } $inList = trim($inList, ',') . ')'; } $objs = $object->getRelatives($compRelTableName, 0, -1, '', '', isset($inList) ? 'other.`id` NOT IN ' . $inList : ''); $i = 0; $numObjs = count($objs); while ($i != $numObjs) { $composite['objects'][$objs[$i]->id] = $objs[$i]; $composite['newObjects'][$objs[$i]->id] = true; ++$i; } } else { unset($composite['objects']); unset($composite['newObjects']); unset($composite['removedStoredObjects']); unset($composite['uninitializedNewObjects']); } unset($composite['modifiedObjects']); // remove all relations for this composite before recursing $query = 'DELETE FROM `' . $compRelTableName . '` '; $query .= 'WHERE `' . $columnNames['this'] . '`=' . $objectId; $result = $database->execQuery($query); if (!$result) { $staticError = 'Failed to delete the records on the relation table '; $staticError .= '`' . $compRelTableName . '`. '; $staticError .= 'This was likely due to a mismatch between the database structure and the '; $staticerror .= 'columns and/or table name you specified in the constructor of this object!'; self::$staticErrors[] = $staticError; return false; } $i = 0; $size = count($compIds); while ($i != $size) { // Try to recursively remove composites if (!self::removeRecursive($compObj, $compIds[$i], false)) { return false; } ++$i; } } // End of the composite foreach loop unset($object->id); unset($object->objectInfo['toBeRemoved']); unset($object->objectInfo['valueChanged']); $query = 'DELETE FROM `' . $object->objectInfo['tableName'] . '` WHERE `id` = ? LIMIT 1'; $result = $database->execQuery($query, $objectId); if (!$result) { $staticError = 'Failed to delete the record of composite `' . $object->objectInfo['tableName'] . ' '; $staticError .= 'This was likely due to a mismatch between the database structure and the '; $staticError .= 'columns and/or table name you specified in the constructor of this object!'; self::$staticErrors[] = $staticError; return false; } return true; }