admin16.01.2016 14:11

Сжатие ZIP при обмене данными с 1C

Данное дополнение будет полезно тем кто часто использует синхронизацию 1с и UMI-CMS с 1c.

При обмене мелкими пакетами между системи, все работает хорошо и достаточно быстро, но если обмен информацией переваливает за 100-200MB и интернет оставляет желать лучшего, хочеться как то ускорить процесс потому что только сама передача данных занимает много времени. Тем у кого имеются такие же объемы передаваемой информации пригодится мой скрипт.

Проверял на версии 2.11. Полет нормальный. 

Необходимо заменить функцию saveIncomingFile

protected function saveIncomingFile() {
      $file_name = getRequest('filename');
            $buffer = outputBuffer::current('HTTPOutputBuffer');
            $content = $buffer->getHTTPRequestBody();

            if (!strlen($file_name)) return "failure\nEmpty filename.";
            list($dir_name, , $extension) = array_values(getPathInfo($file_name));
            if (!strlen($extension) || !umiFile::isAllowedFileType($extension)) return "failure\nUnknown file type.";

            if (!isset($_SESSION['1c_latest_catalog-file'])) {
                $_SESSION['1c_latest_catalog-file'] = "";
            }
            $i_flag = ($_SESSION['1c_latest_catalog-file'] == $file_name ? FILE_APPEND : 0);

            $base_name = substr($file_name, 0, strlen($file_name) - strlen($extension) - 1);

            $temp_dir = self::$importDirectory;
            if (!is_dir($temp_dir)) mkdir($temp_dir, 0777, true);

            switch(strtolower($extension)){
                case "zip":
                case "xml":
                    file_put_contents($temp_dir . $base_name . "." . $extension, $content, $i_flag);
                    break;
                default:
                    $quota_byte = getBytesFromString( mainConfiguration::getInstance()->get('system', 'quota-files-and-images') );

                    if ( $quota_byte != 0 ) {
                        $all_size = getBusyDiskSize();
                        if( ($all_size + strlen($content)) >= $quota_byte ) {
                            return "failure\nReached maximum allowed size for /files and /images directories.";
                        }
                    }

                    $images_dir = "./images/cms/data/" . $dir_name . "/";
                    if (!is_dir($images_dir)) mkdir($images_dir, 0777, true);
                    file_put_contents("./images/cms/data/" . $file_name, $content, $i_flag);

                    if (realpath("./images/cms/data/" . $file_name) != CURRENT_WORKING_DIR . "/images/cms/data/" . $file_name) {
                        unlink("./images/cms/data/" . $file_name);
                        return "failure\nWrong file path.";
                    }
                    break;
            }

            $_SESSION['1c_latest_catalog-file'] = $file_name;

            return "success";
        }

Так же в самое начало функции protected function importCommerceML() нужно вставить

if(class_exists("ZipArchive")) {
                $filesZip = glob(self::$importDirectory . "*.zip");
                if (!empty($filesZip)) {
                    #file_put_contents(CURRENT_WORKING_DIR . "/test1c.txt", "\r\n" . $filesZip[0] . "\r\n", FILE_APPEND);

                    $zip = new ZipArchive();
                    if ($zip->open($filesZip[0]) === true) {
                        $zip->extractTo(self::$importDirectory); //Извлекаем файлы в указанную директорию
                        $zip->close(); //Завершаем работу с архивом
                    } else return "failure\nNo zip file.";//Выводим уведомление об ошибке

                    if (is_dir(self::$importDirectory . "/import_files")) {
                        exec("mv " . self::$importDirectory . "/import_files " . CURRENT_WORKING_DIR . "/images/cms/data");
                        removeDirectory(self::$importDirectory . "/import_files");
                    }

                    unlink($filesZip[0]);
                }
            }
        

Как вы заметили я использую не самое изящное решение по перемещению файлов :-)) exec("mv " . self::$importDirectory . "/import_files " . CURRENT_WORKING_DIR . "/images/cms/data"); перепишете под себя так как считаете будет лучше.

И последнее  нужно заменить строку $buffer->push("zip=no\nfile_limit={$maxFileSize}");

на $buffer->push("zip=".(class_exists("ZipArchive")?"yes":"no")."\nfile_limit={$maxFileSize}");

Или можете скачать весь фаил целиком _auto.php