Modules/devices/devices edit inc php: различия между версиями
Материал из MajorDoMo инфо
Elmax (обсуждение | вклад) (+ devices_edit.inc.php) |
Elmax (обсуждение | вклад) м (Elmax переименовал страницу Devices edit inc php в Modules/devices/devices edit inc php: Пропустил при создании путь Modules/devices/) |
(нет различий)
|
Текущая версия от 12:31, 2 апреля 2024
ᐂ В корневой раздел ᐃ В директорию расположения файла
<?php /** * @version 0.1 (wizard) */ // Проверяет, является ли текущий владелец панелью, и устанавливает флаг панели управления. if ($this->owner->name == 'panel') { $out['CONTROLPANEL'] = 1; } // Определяет имя таблицы для устройств и получает запись устройства по ID или по связанному объекту. $table_name = 'devices'; $rec = SQLSelectOne("SELECT * FROM $table_name WHERE ID='$id'"); if (!$id && gr('linked_object')) { $rec = SQLSelectOne("SELECT * FROM $table_name WHERE LINKED_OBJECT='" . DBSafe(gr('linked_object')) . "'"); } // Устанавливает флаг отсутствия навигации, если владелец имеет флаг печати. if ($this->owner->print == 1) { $out['NO_NAV'] = 1; } // Выполняет дополнительные действия, если связанный объект устройства не пуст. if (isset($rec['LINKED_OBJECT']) && $rec['LINKED_OBJECT'] != '') { // Получаем запись объекта по названию связанного объекта $object_rec = SQLSelectOne("SELECT ID FROM objects WHERE TITLE='" . $rec['LINKED_OBJECT'] . "'"); // Если ID объекта существует, выполняем дополнительные действия if ($object_rec['ID']) { // Получаем свойства объекта, связанные с модулями $properties = SQLSelect("SELECT pvalues.*, properties.TITLE as PROPERTY FROM pvalues LEFT JOIN properties ON properties.ID=pvalues.PROPERTY_ID WHERE pvalues.OBJECT_ID=" . $object_rec['ID'] . " AND pvalues.LINKED_MODULES!='' ORDER BY UPDATED DESC"); // Если свойства найдены, выполняем дополнительные действия $total = count($properties); if ($total > 0) { for ($i = 0; $i < $total; $i++) { // Разделяем связанные модули по запятым $linked_modules = explode(',', $properties[$i]['LINKED_MODULES']); // Экранируем специальные символы в значении свойства $properties[$i]['VALUE'] = htmlspecialchars($properties[$i]['VALUE']); // Создаем массив связанных модулей $properties[$i]['LINKED_MODULES'] = array(); foreach ($linked_modules as $module) { // Добавляем каждый модуль в массив связанных модулей $properties[$i]['LINKED_MODULES'][] = array('MODULE' => $module, 'PROPERTY' => $properties[$i]['PROPERTY'], 'OBJECT' => $rec['LINKED_OBJECT']); } // Добавляем свойства в выходной массив $out['LINKED_PROPERTIES'] = $properties; } } } } // Инициализирует массив для отображения методов и получает все методы для указанного типа устройства. $show_methods = array(); if ($rec['TYPE'] != '') { $methods = $this->getAllMethods($rec['TYPE']); // Если методы представлены в виде массива, выполняем дополнительные действия if (is_array($methods)) { foreach ($methods as $k => $v) { // Если метод должен быть показан в конфигурации, добавляем его в массив для отображения if (isset($v['_CONFIG_SHOW']) && $v['_CONFIG_SHOW']) { $v['NAME'] = $k; $show_methods[] = $v; } } } } // Если есть методы для отображения, сортирует их и добавляет в выходной массив. if (isset($show_methods[0])) { usort($show_methods, function ($a, $b) { if ($a['_CONFIG_SHOW'] == $b['_CONFIG_SHOW']) { return 0; } return ($a['_CONFIG_SHOW'] > $b['_CONFIG_SHOW']) ? -1 : 1; }); $out['SHOW_METHODS'] = $show_methods; } // Добавляет сообщения об успехе или ошибке в выходной массив. if (gr('ok_msg')) { $out['OK_MSG'] = gr('ok_msg'); } if (gr('err_msg')) { $out['ERR_MSG'] = gr('err_msg'); } // Выполняет дополнительные действия, если текущая вкладка - 'logic'. if ($this->tab == 'logic') { // Получаем имя метода из запроса или устанавливаем его как 'logicAction', если не указано $method_name = gr('method'); // Получаем объект по связанному объекту устройства $object = getObject($rec['LINKED_OBJECT']); // Получаем все методы родительского класса объекта $methods = $object->getParentMethods($object->class_id, '', 1); // Если есть методы, выполняем дополнительные действия $total = count($methods); for ($i = 0; $i < $total; $i++) { // Если есть описание метода, добавляем его к названию метода if ($methods[$i]['DESCRIPTION'] != '') { $methods[$i]['DESCRIPTION'] = $methods[$i]['TITLE'] . ' - ' . $methods[$i]['DESCRIPTION']; } else { $methods[$i]['DESCRIPTION'] = $methods[$i]['TITLE']; } // Если связанный объект устройства существует, выполняем дополнительные действия if (isset($object_rec['ID'])) { // Получаем метод объекта по названию метода и ID объекта $object_method = SQLSelectOne("SELECT * FROM methods WHERE TITLE='" . $methods[$i]['TITLE'] . "' AND OBJECT_ID=" . $object_rec['ID'] . " ORDER BY TITLE"); // Если метод объекта существует, выполняем дополнительные действия if (isset($object_method['ID'])) { // Добавляем символ '(*)' к описанию метода $methods[$i]['DESCRIPTION'] .= ' (*)'; // Если имя метода не установлено, устанавливаем его как название метода объекта if (!$method_name) { $method_name = $object_method['TITLE']; } } } } // Если имя метода не установлено, устанавливаем его как 'logicAction' if (!$method_name) { $method_name = 'logicAction'; } $out['METHOD'] = $method_name; // Добавляем методы в выходной массив $out['METHODS'] = $methods; // Получаем ID метода по имени метода, ID класса объекта и ID объекта $method_id = $object->getMethodByName($method_name, $object->class_id, $object->id); // Получаем запись метода по ID $method_rec = SQLSelectOne("SELECT * FROM methods WHERE ID=" . (int)$method_id); // Если ID объекта метода не совпадает с ID объекта устройства, создаем новую запись метода if ($method_rec['OBJECT_ID'] != $object->id) { $method_rec['CODE'] = ''; } // Если определены настройки редактора кода, добавляем их в выходной массив if (defined('SETTINGS_CODEEDITOR_TURNONSETTINGS')) { $out['SETTINGS_CODEEDITOR_TURNONSETTINGS'] = SETTINGS_CODEEDITOR_TURNONSETTINGS; $out['SETTINGS_CODEEDITOR_UPTOLINE'] = SETTINGS_CODEEDITOR_UPTOLINE; $out['SETTINGS_CODEEDITOR_SHOWERROR'] = SETTINGS_CODEEDITOR_SHOWERROR; } // Если режим работы - 'update', выполняем дополнительные действия if ($this->mode == 'update') { if ($method_rec['OBJECT_ID'] != $object->id) { $method_rec = array(); $method_rec['OBJECT_ID'] = $object->id; $method_rec['TITLE'] = $method_name; $method_rec['CALL_PARENT'] = 1; $method_rec['ID'] = SQLInsert('methods', $method_rec); } $code = gr('code'); // Сохраняем старый код метода $old_code = $method_rec['CODE']; // Обновляем код метода новым значением $method_rec['CODE'] = $code; $ok = 1; // Если код метода не пуст, проверяем его на наличие ошибок if ($method_rec['CODE'] != '') { $errors = php_syntax_error($method_rec['CODE']); // Если есть ошибки, обрабатываем их и устанавливаем флаг ошибки if ($errors) { $out['ERR_LINE'] = preg_replace('/[^0-9]/', '', substr(stristr($errors, 'php on line '), 0, 18)) - 2; $out['ERR_CODE'] = 1; $errorStr = explode('Parse error: ', htmlspecialchars(strip_tags(nl2br($errors)))); $errorStr = explode('Errors parsing', $errorStr[1]); $errorStr = explode(' in ', $errorStr[0]); //var_dump($errorStr); $out['ERRORS'] = $errorStr[0]; $out['ERR_FULL'] = $errorStr[0] . ' ' . $errorStr[1]; $out['ERR_OLD_CODE'] = $old_code; $ok = 0; } } else { if ($method_rec['ID']) { SQLExec("DELETE FROM methods WHERE ID=" . $method_rec['ID']); } $this->redirect("?id=" . $rec['ID'] . "&view_mode=" . $this->view_mode . "&tab=" . $this->tab . "&method=" . urlencode($method_rec['TITLE'])); } // Если нет ошибок, обновляем запись метода в базе данных if ($ok) { SQLUpdate('methods', $method_rec); $out['OK'] = 1; } else { $out['ERR'] = 1; } } // Добавляем код метода в выходной массив if (isset($method_rec['CODE'])) { $out['CODE'] = htmlspecialchars($method_rec['CODE']); } // Добавляем ID объекта в выходной массив $out['OBJECT_ID'] = $method_rec['OBJECT_ID']; // Получаем ID родительского метода по имени метода, ID класса объекта и ID объекта $parent_method_id = $object->getMethodByName($method_name, $object->class_id, 0); // Если есть ID родительского метода, добавляем его в выходной массив if ($parent_method_id) { $out['METHOD_ID'] = $parent_method_id; } else { // Иначе добавляем ID текущего метода в выходной массив $out['METHOD_ID'] = $method_rec['ID']; } } // Если текущая вкладка - 'settings', выполняем дополнительные действия if ($this->tab == 'settings') { // Получаем все свойства для типа устройства $properties = $this->getAllProperties($rec['TYPE']); //print_r($properties);exit; //debug // Если связанный объект устройства существует и свойства представлены в виде массива, выполняем дополнительные действия if ($rec['LINKED_OBJECT'] && is_array($properties)) { $res_properties = array(); $onchanges = array(); $apply_others = gr('apply_others'); foreach ($properties as $k => $v) { // Если тип конфигурации свойства не пуст, выполняем дополнительные действия if (isset($v['_CONFIG_TYPE'])) { // Если режим работы - 'update', выполняем дополнительные действия if ($this->mode == 'update') { global ${$k . '_value'}; // Если значение свойства установлено, выполняем дополнительные действия if (isset(${$k . '_value'})) { // Если значение свойства - массив, преобразуем его в строку if (is_array(${$k . '_value'})) { $value = implode(',', ${$k . '_value'}); } else { // Иначе очищаем пробелы в начале и конце строки $value = trim(${$k . '_value'}); } // Устанавливаем глобальное значение свойства setGlobal($rec['LINKED_OBJECT'] . '.' . $k, $value); // Если есть другие устройства для применения, выполняем дополнительные действия if (is_array($apply_others)) { foreach ($apply_others as $other_dev) { // Устанавливаем глобальное значение свойства для других устройств setGlobal($other_dev . '.' . $k, $value); // Если есть ограничения доступа для свойства, выполняем дополнительные действия if ($v['_CONFIG_RESTRICTIONS'] && checkAccessDefined('prop_' . $k, $rec['ID'])) { $other_obj = getObject($other_dev); // Если объект существует и имеет ID устройства, копируем права доступа if (is_object($other_obj) && $other_obj->device_id) { checkAccessCopy('prop_' . $k, $rec['ID'], $other_obj->device_id); } } } } } // Устанавливаем флаг успешного обновления $out['OK'] = 1; // Если есть метод, который должен быть вызван при изменении свойства, добавляем его в массив if (isset($v['ONCHANGE']) && $v['ONCHANGE'] != '') { $onchanges[$v['ONCHANGE']] = 1; } } // Добавляем имя свойства в массив свойств $v['NAME'] = $k; // Если есть справочная информация для свойства, добавляем ее в массив свойств if (isset($v['_CONFIG_HELP'])) $v['CONFIG_HELP'] = $v['_CONFIG_HELP']; // Добавляем тип конфигурации в массив свойств $v['CONFIG_TYPE'] = $v['_CONFIG_TYPE']; // Получаем глобальное значение свойства $v['VALUE'] = getGlobal($rec['LINKED_OBJECT'] . '.' . $k); // Если тип конфигурации - 'select' или 'multi_select', выполняем дополнительные действия if ($v['CONFIG_TYPE'] == 'select' || $v['CONFIG_TYPE'] == 'multi_select') { // Получаем выбранные опции из глобального значения свойства $selected_options = explode(',', gg($rec['LINKED_OBJECT'] . '.' . $k)); // Разделяем опции по запятым $tmp = explode(',', $v['_CONFIG_OPTIONS']); $total = count($tmp); for ($i = 0; $i < $total; $i++) { // Разделяем каждую опцию на значение и название $data_s = explode('=', trim($tmp[$i])); $value = $data_s[0]; if (isset($data_s[1])) { $title = $data_s[1]; } else { $title = $value; } // Создаем массив опции $option = array('VALUE' => $value, 'TITLE' => $title); // Если значение опции выбрано, устанавливаем флаг выбранной опции if (in_array($value, $selected_options)) $option['SELECTED'] = 1; // Добавляем опцию в массив свойств $v['OPTIONS'][] = $option; } } elseif ($v['CONFIG_TYPE'] == 'style_image') { // Если тип конфигурации - 'style_image', выполняем дополнительные действия include_once(DIR_MODULES . 'scenes/scenes.class.php'); $scene_class = new scenes(); // Получаем все типы сцен $styles = $scene_class->getAllTypes(); // Добавляем типы сцен в массив свойств $v['FOLDERS'] = $styles; } // Если есть ограничения доступа для свойства и они определены, устанавливаем флаг установленных ограничений if (isset($v['_CONFIG_RESTRICTIONS']) && $v['_CONFIG_RESTRICTIONS'] && checkAccessDefined('prop_' . $v['NAME'], $rec['ID'])) { $v['_CONFIG_RESTRICTIONS_SET'] = 1; } // Добавляем свойство в массив результатов $res_properties[] = $v; } } // Если режим работы - 'update', выполняем дополнительные действия if ($this->mode == 'update') { // Вызываем методы, которые должны быть вызваны при изменении свойства foreach ($onchanges as $k => $v) { callMethod($rec['LINKED_OBJECT'] . '.' . $k); } // Синхронизируем устройство с Homebridge $this->homebridgeSync($rec['ID'], 1); } //print_r($res_properties);exit; // debug // Добавляем свойства в выходной массив $out['PROPERTIES'] = $res_properties; } //print_r($res_properties);exit; // debug // Получаем все группы для типа устройства $groups = $this->getAllGroups($rec['TYPE']); // Инициализируем глобальную переменную для применения групп global $apply_groups; // Если режим работы - 'update', устанавливаем массив применения групп if ($this->mode == 'update') { if (!is_array($apply_groups)) { $apply_groups = array(); } } else { $apply_groups = array(); } // Получаем ID объекта $total = count($groups); $object_id = gg($rec['LINKED_OBJECT'] . '.object_id'); // Если есть группы, выполняем дополнительные действия if ($total > 0) { for ($i = 0; $i < $total; $i++) { // Формируем название свойства группы $property_title = 'group' . $groups[$i]['SYS_NAME']; // Если режим работы - 'update', выполняем дополнительные действия if ($this->mode == 'update') { // Если группа выбрана, устанавливаем значение свойства группы if (in_array($groups[$i]['SYS_NAME'], $apply_groups)) { sg($rec['LINKED_OBJECT'] . '.' . $property_title, 1); } elseif (gg($rec['LINKED_OBJECT'] . '.' . $property_title)) { // Если группа не выбрана, сбрасываем значение свойства группы sg($rec['LINKED_OBJECT'] . '.' . $property_title, 0); // Получаем ID свойства группы $property_id = current(SQLSelectOne("SELECT ID FROM properties WHERE OBJECT_ID=" . (int)$object_id . " AND TITLE='" . DBSafe($property_title) . "'")); // Если ID свойства группы существует, удаляем свойство группы if ($property_id) { SQLExec("DELETE FROM pvalues WHERE PROPERTY_ID=" . $property_id . " AND OBJECT_ID=" . $object_id); SQLExec("DELETE FROM properties WHERE ID=" . $property_id); } //echo $property_id;exit; } } // Если значение свойства группы установлено, устанавливаем флаг выбранной группы if (gg($rec['LINKED_OBJECT'] . '.' . $property_title)) { $groups[$i]['SELECTED'] = 1; } } // Добавляем группы в выходной массив $out['GROUPS'] = $groups; } } // Если текущая вкладка - 'interface', выполняем дополнительные действия if ($this->tab == 'interface') { // Если режим работы - 'update', выполняем дополнительные действия if ($this->mode == 'update') { global $add_menu; global $add_menu_id; global $add_scene; global $add_scene_id; // Если не указана сцена, устанавливаем ID сцены в 0 if (!$add_scene) { $add_scene_id = 0; } // Если не указан ID сцены, устанавливаем сцену в 0 if (!$add_scene_id) { $add_scene = 0; } // Добавляем значения в выходной массив $out['ADD_MENU'] = $add_menu; $out['ADD_MENU_ID'] = $add_menu_id; $out['ADD_SCENE'] = $add_scene; $out['ADD_SCENE_ID'] = $add_scene_id; // Если указано добавление в меню, добавляем устройство в меню if ($out['ADD_MENU']) { $this->addDeviceToMenu($rec['ID'], $add_menu_id); } // Если указано добавление в сцену и ID сцены указан, добавляем устройство в сцену if ($out['ADD_SCENE'] && $out['ADD_SCENE_ID']) { $this->addDeviceToScene($rec['ID'], $add_scene_id); } // Устанавливаем флаг успешного обновления $out['OK'] = 1; } // Получаем все сцены $out['SCENES'] = SQLSelect("SELECT ID,TITLE FROM scenes ORDER BY TITLE"); // Получаем все элементы меню $menu_items = SQLSelect("SELECT ID, TITLE FROM commands ORDER BY PARENT_ID,TITLE"); // Инициализируем массив для элементов меню $res_items = array(); // Получаем количество элементов меню $total = count($menu_items); for ($i = 0; $i < $total; $i++) { // Если у элемента меню есть подэлементы, добавляем его в массив $sub = SQLSelectOne("SELECT ID FROM commands WHERE PARENT_ID=" . $menu_items[$i]['ID']); if (isset($sub['ID'])) { $res_items[] = $menu_items[$i]; } } // Добавляем элементы меню в выходной массив $out['MENU'] = $res_items; } // Если текущая вкладка пуста, выполняем дополнительные действия if ($this->tab == '') { // Инициализируем массив для приоритетов for ($i = 1; $i < 100; $i++) { $out['PRIORITIES'][] = array('VALUE' => $i); } // Получаем переменные $prefix = gr('prefix'); $out['PREFIX'] = $prefix; $source_table = gr('source_table'); $out['SOURCE_TABLE'] = $source_table; $source_table_id = gr('source_table_id'); $out['SOURCE_TABLE_ID'] = $source_table_id; $type = gr('type'); $out['TYPE'] = $type; $linked_object = gr('linked_object'); // Если связанный объект не пуст, выполняем дополнительные действия if ($linked_object != '') { // Если объект не существует, очищаем связанный объект if (!getObject($linked_object)) { $linked_object = ''; } } // Добавляем связанный объект в выходной массив $out['LINKED_OBJECT'] = trim($linked_object); // Если связанный объект существует и ID устройства не установлен, выполняем дополнительные действия if ($out['LINKED_OBJECT'] && !$rec['ID']) { // Получаем запись устройства по связанному объекту $old_rec = SQLSelectOne("SELECT * FROM devices WHERE LINKED_OBJECT LIKE '" . DBSafe($out['LINKED_OBJECT']) . "'"); // Если запись устройства существует, обновляем текущую запись устройства if ($old_rec['ID']) { $rec = $old_rec; } } // Получаем глобальную переменную для добавления заголовка global $add_title; // Если заголовок указан, добавляем его в выходной массив if ($add_title) { $out['TITLE'] = $add_title; } // Если указана таблица источника и ID устройства не установлен, выполняем дополнительные действия if ($out['SOURCE_TABLE'] && !$rec['ID']) { // Формируем запрос для выбора устройства $qry_devices = 1; // Если тип устройства установлен, добавляем условие выборки по типу устройства if ($out['TYPE']) { $qry_devices .= " AND devices.TYPE='" . DBSafe($out['TYPE']) . "'"; } // Выполняем запрос к базе данных для получения списка существующих устройств $existing_devices = SQLSelect("SELECT ID, TITLE FROM devices WHERE $qry_devices ORDER BY TITLE"); // Если в результате запроса найдено хотя бы одно устройство, выполняем дополнительные действия if ($existing_devices[0]['ID']) { // Устанавливаем флаг наличия существующих устройств $out['SELECT_EXISTING'] = 1; // Добавляем список существующих устройств в выходной массив $out['EXISTING_DEVICES'] = $existing_devices; } } } // Если текущая вкладка - 'links', выполняем дополнительные действия if ($this->tab == 'links') { // Включаем файл с логикой работы с ссылками устройств include_once(dirname(__FILE__) . '/devices_links.inc.php'); } // Если текущая вкладка - 'schedule', выполняем дополнительные действия if ($this->tab == 'schedule') { // Включаем файл с логикой работы с расписанием устройств include_once(dirname(__FILE__) . '/devices_schedule.inc.php'); } // Если режим работы - 'update' и текущая вкладка пуста, выполняем дополнительные действия if ($this->mode == 'update' && $this->tab == '') { $added = 0; $ok = 1; // Получаем название устройства из запроса и удаляем пробелы в начале и конце строки $rec['TITLE'] = gr('title', 'trim'); // Если название устройства пустое, устанавливаем флаг ошибки if ($rec['TITLE'] == '') { $out['ERR_TITLE'] = 1; $ok = 0; } // Получаем альтернативные названия устройства из запроса и удаляем пробелы в начале и конце строки $rec['ALT_TITLES'] = gr('alt_titles', 'trim'); // Получаем тип устройства из глобальной переменной $rec['TYPE'] = $type; // Если тип устройства пустой, устанавливаем флаг ошибки if ($rec['TYPE'] == '') { $out['ERR_TYPE'] = 1; $ok = 0; } // Получаем ID локации из глобальной переменной global $location_id; $rec['LOCATION_ID'] = (int)$location_id; // Если устройство отмечено как избранное, устанавливаем приоритет избранного if (gr('favorite', 'int')) { $rec['FAVORITE'] = gr('favorite_priority', 'int'); } else { $rec['FAVORITE'] = 0; } // Устанавливаем флаг системного устройства $rec['SYSTEM_DEVICE'] = gr('system_device', 'int'); // Устанавливаем флаг архивированного устройства $rec['ARCHIVED'] = gr('archived', 'int'); // Получаем связанный объект устройства из глобальной переменной $rec['LINKED_OBJECT'] = $linked_object; // Если связанный объект устройства не пуст и ID устройства не установлен, выполняем дополнительные действия if ($rec['LINKED_OBJECT'] && !$rec['ID']) { // Проверяем, существует ли уже устройство с таким связанным объектом $other_device = SQLSelectOne("SELECT ID FROM devices WHERE LINKED_OBJECT LIKE '" . DBSafe($rec['LINKED_OBJECT']) . "'"); // Если устройство с таким связанным объектом уже существует, устанавливаем флаг ошибки if ($other_device['ID']) { $out['ERR_LINKED_OBJECT'] = 1; $ok = 0; } } // Получаем флаг добавления нового объекта из глобальной переменной global $add_object; $out['ADD_OBJECT'] = $add_object; // Если флаг добавления нового объекта установлен, очищаем связанный объект устройства if ($add_object) { $rec['LINKED_OBJECT'] = ''; } // Обновляем структуру устройств if ($ok) { $this->renderStructure(); // Если устройство уже существует, обновляем его запись if ($rec['ID']) { SQLUpdate($table_name, $rec); // update } else { $new_rec = 1; // Если устройство добавляется, создаем новую запись устройства $rec['ID'] = SQLInsert($table_name, $rec); // adding new record $added = 1; } // Если устройство связано с локацией, выполняем дополнительные действия if ($rec['LOCATION_ID']) { // Получаем название объекта локации $location_title = getRoomObjectByLocation($rec['LOCATION_ID'], 1); } // Устанавливаем флаг успешного обновления $out['OK'] = 1; // Если тип устройства не пуст, выполняем дополнительные действия // Получаем детали типа устройства $type_details = $this->getTypeDetails($rec['TYPE']); // Если связанный объект устройства не пуст и флаг добавления нового объекта установлен, выполняем дополнительные действия if (!$rec['LINKED_OBJECT'] && $out['ADD_OBJECT']) { // Формируем новое название связанного объекта $prefix = $out['PREFIX'] . ucfirst($rec['TYPE']); $new_object_title = $prefix . $this->getNewObjectIndex($type_details['CLASS'], $prefix); // Добавляем новый объект с новым названием $object_id = addClassObject($type_details['CLASS'], $new_object_title, 'sdevice' . $rec['ID']); // Устанавливаем новое название связанного объекта устройства $rec['LINKED_OBJECT'] = $new_object_title; // Обновляем запись устройства с новым названием связанного объекта SQLUpdate('devices', $rec); } // Добавляем объект устройства с текущим названием $object_id = addClassObject($type_details['CLASS'], $rec['LINKED_OBJECT'], 'sdevice' . $rec['ID']); // Получаем ID класса объекта $class_id = current(SQLSelectOne("SELECT ID FROM classes WHERE TITLE LIKE '" . DBSafe($type_details['CLASS']) . "'")); // Если класс объекта изменился, выполняем дополнительные действия $object_rec = SQLSelectOne("SELECT * FROM objects WHERE ID=" . $object_id); // Устанавливаем описание объекта $object_rec['DESCRIPTION'] = $rec['TITLE']; // Устанавливаем ID локации объекта $object_rec['LOCATION_ID'] = $rec['LOCATION_ID']; $class_changed = 0; $class_2b_changed = 1; $tmp_class_id = $object_rec['CLASS_ID']; // Проверяем, изменился ли класс объекта while (isset($tmp_class_id)) { if ($tmp_class_id == $class_id) { $class_2b_changed = 0; break; } $tmp = SQLSelectOne("SELECT PARENT_ID FROM classes WHERE ID=" . (int)$tmp_class_id); $tmp_class_id = (int)$tmp['PARENT_ID']; } if ($class_2b_changed) { // Если класс объекта изменился, обновляем ID класса объекта $object_rec['CLASS_ID'] = $class_id; $class_changed = 1; } // Обновляем запись объекта в базе данных SQLUpdate('objects', $object_rec); // Если класс объекта изменился, вызываем функцию для обработки изменения класса if ($class_changed) { objectClassChanged($object_rec['ID']); } // Если устройство связано с локацией, выполняем дополнительные действия if ($location_title) { // Устанавливаем глобальное значение для связи устройства с локацией setGlobal($object_rec['TITLE'] . '.linkedRoom', $location_title); } // Если устройство добавлено и имеет свойства, устанавливаем значения свойств по умолчанию if ($added && is_array($type_details['PROPERTIES'])) { foreach ($type_details['PROPERTIES'] as $property => $details) { // Если для свойства определено значение по умолчанию, устанавливаем его if (isset($details['_CONFIG_DEFAULT'])) { setGlobal($object_rec['TITLE'] . '.' . $property, $details['_CONFIG_DEFAULT']); } } } // Если устройство добавлено и имеет тип 'sensor_temp', устанавливаем значения свойств по умолчанию if ($added && $rec['TYPE'] == 'sensor_temp') { setGlobal($object_rec['TITLE'] . '.minValue', 16); setGlobal($object_rec['TITLE'] . '.maxValue', 25); } // Если устройство добавлено и имеет тип 'sensor_humidity', устанавливаем значения свойств по умолчанию if ($added && $rec['TYPE'] == 'sensor_humidity') { setGlobal($object_rec['TITLE'] . '.minValue', 30); setGlobal($object_rec['TITLE'] . '.maxValue', 60); } // Очищаем кэш данных clearCacheData(); // Добавляем задачу в очередь для синхронизации устройств addToOperationsQueue('connect_sync_devices', 'required'); // Если устройство связано с таблицей источника, выполняем дополнительные действия if ($out['SOURCE_TABLE'] && $out['SOURCE_TABLE_ID']) { // Добавляем устройство в таблицу источника $this->addDeviceToSourceTable($out['SOURCE_TABLE'], $out['SOURCE_TABLE_ID'], $rec['ID']); } // Синхронизируем устройство с Homebridge $this->homebridgeSync($rec['ID'], 1); // Если устройство добавлено, перенаправляем на вкладку настроек устройства if ($added) { $this->redirect("?view_mode=edit_devices&id=" . $rec['ID'] . "&tab=settings"); } } else { $out['ERR'] = 1; } } if (is_array($rec)) { foreach ($rec as $k => $v) { // Проверяем, что значение не является массивом и не пустое if ($v && !is_array($v)) { // Экранируем специальные символы в значении свойства для предотвращения XSS атак $rec[$k] = htmlspecialchars($v); } } } if (!isset($rec['LOCATION_ID'])) { // Получаем ID локации из глобальной переменной $rec['LOCATION_ID'] = gr('location_id', 'int'); } // Выполняем функцию для обработки хэша outHash($rec, $out); // Инициализируем массив для типов устройств $types = array(); // Проходим по всем типам устройств foreach ($this->device_types as $k => $v) { // Если у типа устройства есть название, добавляем его в массив типов if (isset($v['TITLE'])) { $types[] = array('NAME' => $k, 'TITLE' => $v['TITLE']); } // Если текущий тип устройства совпадает с типом устройства в записи и тип устройства не пуст, устанавливаем название типа устройства в выходной массив if (isset($rec['TYPE']) && $k == $rec['TYPE'] && $rec['TYPE'] != '') { $out['TYPE_TITLE'] = $v['TITLE']; } } if ($rec['LINKED_OBJECT']) { $processed = $this->processDevice($rec['ID']); $out['HTML'] = $processed['HTML']; } // Сортируем типы устройств по алфавиту usort($types, function ($a, $b) { return strcmp($a['TITLE'], $b['TITLE']); }); // Добавляем отсортированные типы устройств в выходной массив $out['TYPES'] = $types; // Получаем все локации $out['LOCATIONS'] = SQLSelect("SELECT ID, TITLE FROM locations ORDER BY TITLE+0"); // Если устройство связано с локацией, выполняем дополнительные действия if ($rec['LOCATION_ID']) { // Получаем запись локации по ID $location_rec = SQLSelectOne("SELECT ID,TITLE FROM locations WHERE ID=" . $rec['LOCATION_ID']); // Обрабатываем название локации и добавляем его в выходной массив $out['LOCATION_TITLE'] = processTitle($location_rec['TITLE']); // Получаем все устройства, связанные с текущей локацией $other_devices = SQLSelect("SELECT ID, TITLE, ARCHIVED FROM devices WHERE LOCATION_ID=" . (int)$rec['LOCATION_ID'] . " ORDER BY TITLE"); // Добавляем список устройств в выходной массив $out['OTHER_DEVICES'] = $other_devices; } // Если тип устройства не пуст, выполняем дополнительные действия if ($rec['TYPE']) { // Получаем все устройства, связанные с текущим типом устройства $other_devices_type = SQLSelect("SELECT ID, TITLE, ARCHIVED, LINKED_OBJECT FROM devices WHERE TYPE='" . $rec['TYPE'] . "' ORDER BY TITLE"); // Добавляем список устройств в выходной массив $out['OTHER_DEVICES_TYPE'] = $other_devices_type; }