/** * Удаление из корзины определенных элементов * @param miex id удаляемых элементов * @return int количество удаленных элементов */ public function delete($trash_ids) { // Приводим все к массиву if (!is_array($trash_ids)) { $trash_ids = array($trash_ids); } $trash_ids = array_map('intval', $trash_ids); $db = $this->db; $TRASH_FOLDER = $this->core->TRASH_FOLDER; $deleted = 0; $trashed_objects = $db->get_results("\n SELECT `Trash_ID`, `Type`, `Message_ID`, `Class_ID`, `Subdivision_ID`, `Sub_Class_ID`,\n `System_Table_ID`, `Created`, `XML_Filename`, `XML_Filesize`, `IP`, `UserAgent`, `User_ID`\n FROM `Trash_Data`\n WHERE `Trash_ID` IN (" . join(', ', $trash_ids) . ")", ARRAY_A); if (!$trashed_objects) { return 0; } // узнаем номера всех компонентов и файлов, а так же различные связки $class_ids = array(); $xml_filepaths = array(); $class_file = array(); // связь между компонентом и файлом $message_file = array(); // все объект, находящиеся в данном файле foreach ($trashed_objects as $v) { $class_ids[] = $v['Class_ID']; $filepath = $this->xml_file_name($v); $xml_filepaths[] = $filepath; $class_file[$filepath] = $v['Class_ID']; $message_file[$filepath][] = $v['Message_ID']; //delete all files, related with Message DeleteMessageFiles($v['Class_ID'], $v['Message_ID'], $filepath); } $class_ids = array_unique($class_ids); $xml_filepaths = array_unique($xml_filepaths); // открываем каждый файл, ищем нужные объекты foreach ($xml_filepaths as $xml_filepath) { $doc = new DOMDocument('1.0', 'utf-8'); $doc->load($this->core->TRASH_FOLDER . $xml_filepath); $xpath = new DOMXPath($doc); $class_id = $class_file[$xml_filepath]; //смотрим поля на момент удаления $del_fields = array(); $fields_node = $doc->getElementsByTagName('fields')->item(0); if ($fields_node) { foreach ($fields_node->childNodes as $field_node) { if ($field_node->childNodes) { foreach ($field_node->childNodes as $v) { if ($v->nodeName == 'Field_Name') { $del_fields[] = $v->nodeValue; } } } } } // ищем каждый восстанавливаемый объект в файле foreach ($message_file[$filepath] as $id) { $node = $xpath->query("/netcatml/messages/message[@message_id='" . $id . "']"); $node = $node->item(0); if (!is_object($node)) { continue; } $cc_id = intval($node->getAttribute('sub_class_id')); $deleted++; $comments = $xpath->query("/netcatml/comments/comment[@message_id='" . $id . "' and @sub_class_id='" . $cc_id . "']"); if ($comments) { foreach ($comments as $comment) { $comment->parentNode->removeChild($comment); } } $node->parentNode->removeChild($node); $doc->save($this->core->TRASH_FOLDER . $xml_filepath); } unset($xpath, $doc); } $db->query("DELETE FROM `Trash_Data` WHERE `Trash_ID` IN (" . join(', ', $trash_ids) . ")"); $this->remove_xml_files($xml_filepaths); return $deleted; }
/** * Функция для удаления объектов компонентов * @param mixed `identificators` - идентификаторы объектов подлежащих удалению в виде массива, или цифры * @param int `class_id` номер компонента, в котором производится удаление * @param bool `trash` параметр, определяющий, перед будет ли объект помещен в корзину перед удалением. 1 - объект будет помещен в корзину, затем удален, 0 - объект будет удален. * @return int `affected` - затронутые объекты or false */ public function delete_by_id($identificators, $class_id, $trash = false) { $nc_core = nc_Core::get_object(); $MODULE_FOLDER = $nc_core->MODULE_FOLDER; // validate parameters $affected = 0; $classID = intval($class_id); // Приводим первый параметр к массиву if (!is_array($identificators)) { $messages_to_delete = array(intval($identificators)); } else { $messages_to_delete = array_map("intval", $identificators); } if (empty($messages_to_delete)) { return 0; } // Выясняем данные по всем объектам для удаления - номера разделов, // компонентов в разделе и номера сайтов, а тажке формируем массив номеров удаляемых объектов $temp_array = $this->db->get_results("SELECT m.* , m.`Message_ID` AS `m_id`, m.`Subdivision_ID` as `sub_id`, m.`Sub_Class_ID` as `cc_id`, s.`Catalogue_ID` as `cat_id`\n FROM `Message" . $classID . "` as m, `Subdivision` as s\n WHERE m.`Subdivision_ID` = s.`Subdivision_ID` AND m.`Message_ID` IN (" . join(',', $messages_to_delete) . ")", ARRAY_A); $message_to_delete = array(); $message_to_delete_ids = array(); $message_to_delete_data = array(); if (!empty($temp_array)) { foreach ($temp_array as $v) { // группируем объекты по сайты/разделу/сс $message_to_delete[$v['cat_id']][$v['sub_id']][$v['cc_id']][] = intval($v['m_id']); $message_to_delete_data[$v['cat_id']][$v['sub_id']][$v['cc_id']][intval($v['m_id'])] = $v; $message_to_delete_ids[] = $v['m_id']; } } else { return 0; } $nc_core->event->execute("dropMessagePrep", $messages_to_delete); try { if ($trash) { $trashing_result_arr = $nc_core->trash->add($messages_to_delete, $classID); } } catch (nc_Exception_Trash_Full $e) { $trash = 0; } catch (nc_Exception_Trash_Folder_Fail $e) { $trash = 0; } // Удаляем комментарии if (nc_module_check_by_keyword("comments")) { include_once $MODULE_FOLDER . "comments/function.inc.php"; // get need ids $comments_temp = $this->db->get_results("SELECT `Message_ID`, `Sub_Class_ID` FROM `Message" . $classID . "`\n WHERE `Message_ID` IN (" . join(',', $message_to_delete_ids) . ") OR `Parent_Message_ID` IN (" . join(',', $message_to_delete_ids) . ")", ARRAY_A); // compile arrays $temp_messages = array(); $temp_ccs = array(); foreach ((array) $comments_temp as $comments_temp_value) { if (!in_array($comments_temp_value['Message_ID'], $temp_messages)) { $temp_messages[] = $comments_temp_value['Message_ID']; } if (!in_array($comments_temp_value['Sub_Class_ID'], $temp_ccs)) { $temp_ccs[] = $comments_temp_value['Sub_Class_ID']; } } // delete comments nc_comments::dropComments($this->db, $temp_ccs, "Sub_Class", $temp_messages); // delete comment rules nc_comments::dropRuleMessage($this->db, $temp_messages, $temp_ccs); // clear unset($comments_temp, $temp_ccs, $temp_messages); } // delete related files // поочередно удаляем файлы у всех перечисленных к удалению объектов // если они не отправляются в корзину, иначе файлам ставим метку deleted if (!$trash) { require_once $this->core->INCLUDE_FOLDER . "s_files.inc.php"; foreach ($message_to_delete_ids as $id) { DeleteMessageFiles($classID, $id); } } else { $nc_core->trash->TrashMessageFiles($classID, $message_to_delete_ids); } // Удаляем сами объекты $this->db->query("DELETE FROM `Message" . $classID . "` WHERE `Message_ID` IN (" . join(',', $message_to_delete_ids) . ")"); if ($this->db->is_error) { throw new nc_Exception_DB_Error($this->db->last_query, $this->db->last_error); } else { $affected = $this->db->rows_affected; } // execute core action if ($message_to_delete) { foreach ($message_to_delete as $site_id => $site) { foreach ($site as $sub_id => $sub) { foreach ($sub as $cc_id => $messages_in_cc) { $nc_core->event->execute("dropMessage", $site_id, $sub_id, $cc_id, $classID, $messages_in_cc, $message_to_delete_data[$site_id][$sub_id][$cc_id]); } } } } $children_ids = $this->db->get_col("SELECT `Message_ID` FROM `Message" . $classID . "` WHERE `Parent_Message_ID` IN (" . join(',', $message_to_delete_ids) . ")"); if (!empty($children_ids)) { // delete related files if ($this->db->is_error) { throw new nc_Exception_DB_Error($this->db->last_query, $this->db->last_error); } $affected += $this->db->rows_affected; // execute core action $affected += $this->delete_by_id($children_ids, $classID, $trash); } return $affected; }
function CascadeDeleteCatalogue($catalogueId) { global $nc_core, $db, $MODULE_FOLDER; $catalogueId = (int) $catalogueId; $subClasses = (array) $db->get_results("SELECT `Subdivision_ID`, `Sub_Class_ID`, `Class_ID` FROM `Sub_Class` WHERE `Catalogue_ID` = {$catalogueId}", ARRAY_A); // execute core action $nc_core->event->execute("dropCataloguePrep", $catalogueId); $subdivisionsToDelete = array(); //delete messages foreach ($subClasses as $subClass) { $subdivisionId = (int) $subClass['Subdivision_ID']; $subClassId = (int) $subClass['Sub_Class_ID']; $classId = (int) $subClass['Class_ID']; $subdivisionsToDelete[] = $subdivisionId; $subClassesToDelete[] = $subClassId; $messages = (array) $db->get_results("SELECT `Message_ID` FROM `Message{$classId}` WHERE `Sub_Class_ID` = {$subClassId}", ARRAY_A); $messagesToDelete = array(); foreach ($messages as $message) { $messagesToDelete[] = (int) $message['Message_ID']; } if (count($messagesToDelete) > 0) { // execute core action $nc_core->event->execute("dropMessagePrep", $catalogueId, $subdivisionId, $subClassId, $classId, $messagesToDelete); // delete messages foreach ($messagesToDelete as $messageId) { DeleteMessageFiles($classId, $messageId); $db->query("DELETE FROM `Message{$classId}` WHERE `Message_ID` = {$messageId}"); } // execute core action $nc_core->event->execute("dropMessage", $catalogueId, $subdivisionId, $subClassId, $classId, $messagesToDelete); } //delete subclass // execute core action $nc_core->event->execute("dropSubClassPrep", $catalogueId, $subdivisionId, $subClassId); $db->query("DELETE FROM `Sub_Class` WHERE `Sub_Class_ID` = {$subClassId}"); DeleteSubClassDirAlways($subdivisionId, $subClassId); // execute core action $nc_core->event->execute("dropSubClass", $catalogueId, $subdivisionId, $subClassId); } if (count($subdivisionsToDelete) > 0) { // execute core action $nc_core->event->execute("dropSubdivisionPrep", $catalogueId, $subdivisionsToDelete); foreach ($subdivisionsToDelete as $subdivisionId) { $db->query("DELETE FROM `Subdivision` WHERE `Subdivision_ID` = {$subdivisionId}"); DeleteSubdivisionDir($subdivisionId); } // execute core action $nc_core->event->execute("dropSubdivision", $catalogueId, $subdivisionsToDelete); } if (nc_module_check_by_keyword("comments")) { include_once $MODULE_FOLDER . "comments/function.inc.php"; // delete comment rules nc_comments::dropRule($db, array($catalogueId)); // delete comments nc_comments::dropComments($db, $catalogueId, "Catalogue"); } // delete catalogue $db->query("DELETE FROM `Catalogue` WHERE `Catalogue_ID` = {$catalogueId}"); // execute core action $nc_core->event->execute("dropCatalogue", $catalogueId); return; }