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) { $compObj = new $composite['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; }
private static function hasNoCompositeRelatives(Wallop $compObj, $compColumn, $thisRelationTable, $thisId, $thisColumn, array $compIds = null) { global $database; // Initialize the list of ids and the inList $ids = array(); $inList = '('; if (isset($compIds)) { if (empty($compIds)) { return array(); } foreach ($compIds as $compId) { $ids[$compId] = true; $inList .= $compId . ','; } $inList = trim($inList, ',') . ')'; } else { // If compIds is not set then query from the database the ids $query = "SELECT `{$compColumn}` FROM `{$thisRelationTable}` "; $query .= "WHERE `{$thisColumn}` = {$thisId}"; $result = $database->execQuery($query); if (!$result) { $staticError = 'Failed to retrieve records of this composite (`' . $thisRelationTable . '`) '; $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; } $rows = $database->getAllRows(); // Returned an empty result set // Just finish the function and return an empty array if (!$rows || empty($rows)) { return array(); } $i = 0; $numRows = count($rows); while ($i != $numRows) { $row = $rows[$i]; $ids[$row[$compColumn]] = true; $inList .= $row[$compColumn] . ','; ++$i; } $inList = trim($inList, ',') . ')'; unset($rows); } // Foreach relation of this composite remove keys from the master array for composites that // only have any other composite relations to them $compRelationTypes = array(&$compObj->aggregates, &$compObj->composites); foreach ($compRelationTypes as $compRelationType) { foreach ($compRelationType as $compRelationTableName => $compRelation) { $compRelationData = $compObj->findRelationData($compRelationTableName); // If this relation has the composite also as a composite relation $compRelationObj = new $compRelationData['className'](); if (isset($compRelationObj->composites[$thisRelationTable])) { // Generate relation columns $relationColumns = $compRelationObj->generateRelationColumns($compRelationTableName, $compObj); if (!$relationColumns) { end($compRelationObj->errors); self::$staticErrors[] = $compRelationObj->errors[key($compRelationObj->errors)]; return false; } $compRelationColumn = $relationColumns['this']; $secondCompColumn = $relationColumns['relative']; $query = "SELECT `{$secondCompColumn}` "; $query .= "FROM `{$compRelationTableName}` "; $query .= "WHERE `{$secondCompColumn}` IN {$inList}"; // Add a claus to not if ($thisRelationTable == $compRelationTableName) { $query .= " AND `{$compRelationColumn}` != {$thisId}"; } $result = $database->execQuery($query); if (!$result) { $staticError = 'Failed to retrieve records of this composite (`'; $staticError .= $thisRelationTable . '`) This was likely due to a mismatch between '; $staticError .= 'the database structure and the columns and/or table name you '; $staticError .= 'specified in the constructor of this object!'; self::$staticErrors[] = $staticError; return false; } $rows = $database->getAllRows(); $rowId = 0; $numRows = count($rows); while ($rowId != $numRows) { $id = $rows[$rowId][$secondCompColumn]; unset($ids[$id]); $inList = str_replace_once(',' . $id . ',', ',', $inList, $found); if (!$found) { unset($found); $inList = str_replace_once('(' . $id . ',', '(', $inList, $found); if (!$found) { $inList = str_replace_once(',' . $id . ')', ')', $inList); } } ++$rowId; } } } } $outputArray = array(); foreach ($ids as $id => $unused) { $outputArray[] = $id; } return $outputArray; }
public static function getStaticErrors() { $temp = self::$staticErrors; self::$staticErrors = array(); return $temp; }