false, 'log' => $log ]; } $log[] = '[OK] Pobrano listę wersji'; $versions = explode( PHP_EOL, $versions ); $log[] = '[INFO] Znaleziono ' . count($versions) . ' wersji do sprawdzenia'; foreach ( $versions as $ver ) { $ver = trim( $ver ); if ( floatval( $ver ) > (float)\S::get_version() ) { $log[] = '[INFO] Aktualizacja do wersji: ' . $ver; if ( strlen( $ver ) == 5 ) $dir = substr( $ver, 0, strlen( $ver ) - 2 ) . 0; else $dir = substr( $ver, 0, strlen( $ver ) - 1 ) . 0; $zip_url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '.zip'; $log[] = '[INFO] Pobieranie pliku ZIP: ' . $zip_url; $file = @file_get_contents( $zip_url ); if ( $file === false ) { $log[] = '[ERROR] Nie udało się pobrać pliku ZIP'; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $file_size = strlen( $file ); $log[] = '[OK] Pobrano plik ZIP, rozmiar: ' . $file_size . ' bajtów'; if ( $file_size < 100 ) { $log[] = '[ERROR] Plik ZIP jest za mały (prawdopodobnie błąd pobierania)'; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $dlHandler = @fopen( 'update.zip' , 'w' ); if ( !$dlHandler ) { $log[] = '[ERROR] Nie udało się otworzyć pliku update.zip do zapisu'; $log[] = '[INFO] Katalog roboczy: ' . getcwd(); $log[] = '[INFO] Uprawnienia katalogu: ' . substr(sprintf('%o', fileperms('.')), -4); self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $written = fwrite( $dlHandler, $file ); fclose( $dlHandler ); if ( $written === false || $written === 0 ) { $log[] = '[ERROR] Nie udało się zapisać pliku ZIP (zapisano: ' . ($written === false ? 'false' : $written) . ' bajtów)'; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $log[] = '[OK] Zapisano plik ZIP (' . $written . ' bajtów)'; if ( !file_exists( 'update.zip' ) ) { $log[] = '[ERROR] Plik update.zip nie istnieje po zapisie'; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $actual_size = filesize( 'update.zip' ); $log[] = '[OK] Plik update.zip istnieje, rozmiar na dysku: ' . $actual_size . ' bajtów'; /* aktualizacja bazy danych */ $sql_url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_sql.txt'; $log[] = '[INFO] Sprawdzanie aktualizacji SQL: ' . $sql_url; $ch = curl_init( $sql_url ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_HEADER, false ); $response = curl_exec( $ch ); $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); $content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE ); curl_close( $ch ); $sql = []; if ( $response && strpos( $content_type, 'text/plain' ) !== false ) { $sql = explode( PHP_EOL, $response ); $log[] = '[OK] Pobrano ' . count($sql) . ' zapytań SQL'; } else { $log[] = '[INFO] Brak aktualizacji SQL (HTTP: ' . $http_code . ')'; } if ( is_array( $sql ) && !empty( $sql ) ) { $sql_success = 0; $sql_errors = 0; foreach ( $sql as $query ) { $query = trim( $query ); if ( !empty( $query ) ) { $result = $mdb->query( $query ); if ( $result ) $sql_success++; else $sql_errors++; } } $log[] = '[INFO] Wykonano zapytania SQL - sukces: ' . $sql_success . ', błędy: ' . $sql_errors; } /* usuwanie zbędnych plików */ $files_url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_files.txt'; $log[] = '[INFO] Sprawdzanie plików do usunięcia: ' . $files_url; $ch = curl_init( $files_url ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_HEADER, false ); $response = curl_exec( $ch ); $http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); $content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE ); curl_close( $ch ); $files = []; if ( $response && strpos( $content_type, 'text/plain' ) !== false ) $files = explode( PHP_EOL, $response ); $deleted_files = 0; $deleted_dirs = 0; if ( is_array( $files ) && !empty( $files ) ) { foreach ( $files as $file ) { if ( strpos( $file, 'F: ' ) !== false ) { $file = substr( $file, 3, strlen( $file ) ); if ( file_exists( $file ) ) { if ( @unlink( $file ) ) $deleted_files++; else $log[] = '[WARNING] Nie udało się usunąć pliku: ' . $file; } } if ( strpos( $file, 'D: ' ) !== false ) { $dir_to_delete = substr( $file, 3, strlen( $file ) ); if ( is_dir( $dir_to_delete ) ) { \S::delete_dir( $dir_to_delete ); $deleted_dirs++; } } } } $log[] = '[INFO] Usunięto plików: ' . $deleted_files . ', katalogów: ' . $deleted_dirs; /* wgrywanie nowych plików */ $file_name = 'update.zip'; $log[] = '[INFO] Rozpoczęcie rozpakowywania pliku ZIP'; $path = pathinfo( realpath( $file_name ), PATHINFO_DIRNAME ); $log[] = '[INFO] Ścieżka pathinfo: ' . $path; $path = substr( $path, 0, strlen( $path ) - 5 ); $log[] = '[INFO] Ścieżka docelowa (po obcięciu): ' . $path; if ( !is_dir( $path ) ) { $log[] = '[ERROR] Ścieżka docelowa nie istnieje: ' . $path; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } if ( !is_writable( $path ) ) { $log[] = '[ERROR] Brak uprawnień do zapisu w: ' . $path; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $log[] = '[OK] Ścieżka docelowa istnieje i jest zapisywalna'; $zip = new \ZipArchive; $res = $zip->open( $file_name ); if ( $res !== true ) { $zip_errors = [ \ZipArchive::ER_EXISTS => 'Plik już istnieje', \ZipArchive::ER_INCONS => 'Archiwum ZIP jest niespójne', \ZipArchive::ER_INVAL => 'Nieprawidłowy argument', \ZipArchive::ER_MEMORY => 'Błąd alokacji pamięci', \ZipArchive::ER_NOENT => 'Plik nie istnieje', \ZipArchive::ER_NOZIP => 'Plik nie jest archiwum ZIP', \ZipArchive::ER_OPEN => 'Nie można otworzyć pliku', \ZipArchive::ER_READ => 'Błąd odczytu', \ZipArchive::ER_SEEK => 'Błąd seek', ]; $error_msg = isset( $zip_errors[$res] ) ? $zip_errors[$res] : 'Nieznany błąd (' . $res . ')'; $log[] = '[ERROR] Nie udało się otworzyć pliku ZIP: ' . $error_msg; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } $log[] = '[OK] Otwarto archiwum ZIP, liczba plików: ' . $zip->numFiles; $extracted_count = 0; $extract_errors = 0; $skipped_dirs = 0; for ( $i = 0; $i < $zip->numFiles; $i++ ) { $filename = $zip->getNameIndex( $i ); $filename_clean = str_replace( '\\', '/', $filename ); if ( substr( $filename_clean, -1 ) === '/' ) { $dir_path = $path . '/' . $filename_clean; if ( !is_dir( $dir_path ) ) { if ( @mkdir( $dir_path, 0755, true ) ) $log[] = '[DIR] Utworzono katalog: ' . $filename_clean; else $log[] = '[WARNING] Nie udało się utworzyć katalogu: ' . $filename_clean; } $skipped_dirs++; continue; } $target_file = $path . '/' . $filename_clean; $target_dir = dirname( $target_file ); if ( !is_dir( $target_dir ) ) { if ( !@mkdir( $target_dir, 0755, true ) ) { $log[] = '[ERROR] Nie udało się utworzyć katalogu dla: ' . $filename_clean; $extract_errors++; continue; } } $file_existed = file_exists( $target_file ); $old_size = $file_existed ? filesize( $target_file ) : 0; $old_mtime = $file_existed ? filemtime( $target_file ) : 0; $content = $zip->getFromIndex( $i ); if ( $content === false ) { $log[] = '[ERROR] Nie udało się odczytać z ZIP: ' . $filename_clean; $extract_errors++; continue; } $write_result = @file_put_contents( $target_file, $content ); if ( $write_result === false ) { $log[] = '[ERROR] Nie udało się zapisać: ' . $filename_clean . ' (uprawnienia?)'; $extract_errors++; } else { $new_size = filesize( $target_file ); $new_mtime = filemtime( $target_file ); if ( $file_existed ) { if ( $old_mtime !== $new_mtime || $old_size !== $new_size ) $log[] = '[UPDATED] ' . $filename_clean . ' (' . $old_size . ' -> ' . $new_size . ' bajtów)'; else $log[] = '[UNCHANGED] ' . $filename_clean . ' (nie zmieniono - identyczny?)'; } else { $log[] = '[NEW] ' . $filename_clean . ' (' . $new_size . ' bajtów)'; } $extracted_count++; } } $log[] = '[OK] Rozpakowano ' . $extracted_count . ' plików, błędów: ' . $extract_errors . ', katalogów: ' . $skipped_dirs; $zip->close(); if ( @unlink( $file_name ) ) $log[] = '[OK] Usunięto plik update.zip'; else $log[] = '[WARNING] Nie udało się usunąć pliku update.zip'; /* aktualizacja wersji */ $version_file = '../libraries/version.ini'; $updateThis = @fopen( $version_file, 'w' ); if ( !$updateThis ) { $log[] = '[ERROR] Nie udało się otworzyć pliku version.ini do zapisu'; self::saveUpdateLog( $log ); return [ 'success' => false, 'log' => $log ]; } fwrite( $updateThis, $ver ); fclose( $updateThis ); $log[] = '[OK] Zaktualizowano plik version.ini do wersji: ' . $ver; $log[] = '[SUCCESS] Aktualizacja do wersji ' . $ver . ' zakończona pomyślnie'; self::saveUpdateLog( $log ); return [ 'success' => true, 'log' => $log ]; } } $log[] = '[INFO] Brak nowych wersji do zainstalowania'; self::saveUpdateLog( $log ); return [ 'success' => true, 'log' => $log, 'no_updates' => true ]; } private static function saveUpdateLog( $log ) { $log_content = implode( "\n", $log ); @file_put_contents( '../libraries/update_log.txt', $log_content ); } public static function update0197() { global $mdb; $rows = $mdb -> select( 'pp_shop_order_products', [ 'id', 'product_id' ], [ 'parent_product_id' => null ] ); foreach ( $rows as $row ) { $parent_id = $mdb -> get( 'pp_shop_products', 'parent_id', [ 'id' => $row['product_id'] ] ); if ( $parent_id ) $mdb -> update( 'pp_shop_order_products', [ 'parent_product_id' => $parent_id ], [ 'id' => $row['id'] ] ); else $mdb -> update( 'pp_shop_order_products', [ 'parent_product_id' => $row['product_id'] ], [ 'id' => $row['id'] ] ); } $mdb -> update( 'pp_updates', [ 'done' => 1 ], [ 'name' => 'update0197' ] ); } }