/** * Returns the root node for a given structure ID, or creates one if it doesn't exist. * * @param int $structureId * * @return StructureElementRecord */ private function _getRootElementRecord($structureId) { if (!isset($this->_rootElementRecordsByStructureId[$structureId])) { $elementRecord = StructureElementRecord::model()->roots()->findByAttributes(array('structureId' => $structureId)); if (!$elementRecord) { // Create it $elementRecord = new StructureElementRecord(); $elementRecord->structureId = $structureId; $elementRecord->saveNode(); } $this->_rootElementRecordsByStructureId[$structureId] = $elementRecord; } return $this->_rootElementRecordsByStructureId[$structureId]; }
/** * Deletes an element(s) by its ID(s). * * @param int|array $elementIds The element’s ID, or an array of elements’ IDs. * * @throws \Exception * @return bool Whether the element(s) were deleted successfully. */ public function deleteElementById($elementIds) { if (!$elementIds) { return false; } if (!is_array($elementIds)) { $elementIds = array($elementIds); } $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { // Fire an 'onBeforeDeleteElements' event $this->onBeforeDeleteElements(new Event($this, array('elementIds' => $elementIds))); // First delete any structure nodes with these elements, so NestedSetBehavior can do its thing. We need to // go one-by-one in case one of theme deletes the record of another in the process. foreach ($elementIds as $elementId) { $records = StructureElementRecord::model()->findAllByAttributes(array('elementId' => $elementId)); foreach ($records as $record) { // If this element still has any children, move them up before the one getting deleted. $children = $record->children()->findAll(); foreach ($children as $child) { $child->moveBefore($record); } // Delete this element's node $record->deleteNode(); } } // Delete the caches before they drop their elementId relations (passing `false` because there's no chance // this element is suddenly going to show up in a new query) craft()->templateCache->deleteCachesByElementId($elementIds, false); // Now delete the rows in the elements table if (count($elementIds) == 1) { $condition = array('id' => $elementIds[0]); $matrixBlockCondition = array('ownerId' => $elementIds[0]); $searchIndexCondition = array('elementId' => $elementIds[0]); } else { $condition = array('in', 'id', $elementIds); $matrixBlockCondition = array('in', 'ownerId', $elementIds); $searchIndexCondition = array('in', 'elementId', $elementIds); } // First delete any Matrix blocks that belong to this element(s) $matrixBlockIds = craft()->db->createCommand()->select('id')->from('matrixblocks')->where($matrixBlockCondition)->queryColumn(); if ($matrixBlockIds) { craft()->matrix->deleteBlockById($matrixBlockIds); } // Delete the elements table rows, which will cascade across all other InnoDB tables $affectedRows = craft()->db->createCommand()->delete('elements', $condition); // The searchindex table is MyISAM, though craft()->db->createCommand()->delete('searchindex', $searchIndexCondition); if ($transaction !== null) { $transaction->commit(); } return (bool) $affectedRows; } catch (\Exception $e) { if ($transaction !== null) { $transaction->rollback(); } throw $e; } }
/** * Deletes an element(s) by its ID(s). * * @param int|array $elementIds The element’s ID, or an array of elements’ IDs. * * @throws \Exception * @return bool Whether the element(s) were deleted successfully. */ public function deleteElementById($elementIds) { if (!$elementIds) { return false; } if (!is_array($elementIds)) { $elementIds = array($elementIds); } $transaction = craft()->db->getCurrentTransaction() === null ? craft()->db->beginTransaction() : null; try { // First delete any structure nodes with these elements, so NestedSetBehavior can do its thing. We need to // go one-by-one in case one of theme deletes the record of another in the process. foreach ($elementIds as $elementId) { $records = StructureElementRecord::model()->findAllByAttributes(array('elementId' => $elementId)); foreach ($records as $record) { $record->deleteNode(); } } // Delete the caches before they drop their elementId relations (passing `false` because there's no chance // this element is suddenly going to show up in a new query) craft()->templateCache->deleteCachesByElementId($elementIds, false); // Fire an 'onBeforeDeleteElements' event $this->onBeforeDeleteElements(new Event($this, array('elementIds' => $elementIds))); // Now delete the rows in the elements table if (count($elementIds) == 1) { $condition = array('id' => $elementIds[0]); } else { $condition = array('in', 'id', $elementIds); } $affectedRows = craft()->db->createCommand()->delete('elements', $condition); if ($transaction !== null) { $transaction->commit(); } return (bool) $affectedRows; } catch (\Exception $e) { if ($transaction !== null) { $transaction->rollback(); } throw $e; } }