Articles: finish admin refactor, uploads hardening, and attachment sorting (0.262)

This commit is contained in:
2026-02-13 09:00:24 +01:00
parent 42e4396064
commit 5354f97baa
31 changed files with 1951 additions and 1512 deletions

View File

@@ -1,154 +1,53 @@
<?php
require_once '../../config.php';
require_once '../medoo/medoo.php';
date_default_timezone_set( 'Europe/Warsaw' );
session_start();
require_once 'upload-common.php';
$upload_token = $_REQUEST['upload_token'] ?? '';
if ( !isset( $_SESSION['upload_tokens'][$upload_token] ) ) {
http_response_code(403);
echo json_encode( ['error' => 'Brak tokenu uploadu'] );
exit;
plupload_bootstrap();
plupload_require_post();
$userId = plupload_require_admin_user();
plupload_validate_token($userId);
$fileDir = '/upload/article_files/tmp';
$targetDir = '../..' . $fileDir;
plupload_ensure_target_dir($targetDir);
list($chunk, $chunks) = plupload_get_chunks();
list($fileName, $extension, $filePath, $partPath) = plupload_build_target_paths(
$targetDir,
$_REQUEST['name'] ?? '',
null,
[
'php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar',
'cgi', 'pl', 'py', 'rb',
'asp', 'aspx', 'jsp',
'js', 'mjs', 'vbs', 'wsf', 'hta',
'sh', 'bash', 'zsh', 'ps1', 'bat', 'cmd', 'com',
'exe', 'msi', 'scr', 'dll', 'jar',
]
);
plupload_cleanup_stale_parts($targetDir, $partPath, 5 * 3600);
plupload_write_chunk_to_part($partPath, $chunk);
plupload_assert_size_limit($partPath, 50 * 1024 * 1024, 'Plik przekracza dozwolony rozmiar (50 MB).');
$fileId = null;
$responseFileName = $fileName;
if (plupload_is_last_chunk($chunk, $chunks)) {
plupload_finalize_part($partPath, $filePath);
$mdb = plupload_create_medoo($database);
$mdb->insert('pp_articles_files', [
'article_id' => null,
'src' => substr($filePath, 5),
]);
$fileId = (int)$mdb->id();
$responseFileName = basename($filePath);
}
$tokenData = $_SESSION['upload_tokens'][$upload_token];
if ( $tokenData['expires'] < time() ) {
unset( $_SESSION['upload_tokens'][$upload_token] );
http_response_code(403);
echo json_encode( ['error' => 'Token wygasł'] );
exit;
}
plupload_send_success([
'file_name' => $responseFileName,
'file_id' => $fileId,
]);
$mdb = new medoo( [
'database_type' => 'mysql',
'database_name' => $database['name'],
'server' => $database['host'],
'username' => $database['user'],
'password' => $database['password'],
'charset' => 'utf8'
] );
header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" );
header( "Cache-Control: no-store, no-cache, must-revalidate" );
header( "Cache-Control: post-check=0, pre-check=0", false );
header( "Pragma: no-cache" );
$fileDir = '/upload/article_files/tmp';
$targetDir = '../..' . $fileDir;
if ( !is_dir( $targetDir ) )
mkdir( $targetDir, 0755, true );
$cleanupTargetDir = true;
$maxFileAge = 5 * 3600;
$chunk = isset( $_REQUEST["chunk"] ) ? intval( $_REQUEST["chunk"] ) : 0;
$chunks = isset( $_REQUEST["chunks"] ) ? intval( $_REQUEST["chunks"] ) : 0;
$fileName = isset( $_REQUEST["name"] ) ? $_REQUEST["name"] : '';
$fileName = preg_replace( '/[^\w\._]+/', '-', $fileName );
if ( file_exists( $targetDir . DIRECTORY_SEPARATOR . $fileName ) )
{
$ext = strrpos( $fileName, '.' );
$fileName_a = substr( $fileName, 0, $ext );
$fileName_b = substr( $fileName, $ext );
$count = 1;
while ( file_exists( $targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b ) )
$count++;
$fileName = $fileName_a . '_' . $count . $fileName_b;
}
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
if ( $cleanupTargetDir && is_dir( $targetDir ) && ( $dir = opendir( $targetDir ) ) )
{
while ( ( $file = readdir( $dir ) ) !== false )
{
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
if ( preg_match( '/\.part$/', $file ) && ( filemtime( $tmpfilePath ) < time() - $maxFileAge ) && ( $tmpfilePath != "{$filePath}.part" ) ) {
@unlink( $tmpfilePath );
}
}
closedir($dir);
}
else
die( '{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}' );
if ( isset( $_SERVER["HTTP_CONTENT_TYPE"] ) )
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
if ( isset( $_SERVER["CONTENT_TYPE"] ) )
$contentType = $_SERVER["CONTENT_TYPE"];
if ( strpos( $contentType, "multipart" ) !== false )
{
if ( isset( $_FILES['file']['tmp_name'] ) && is_uploaded_file( $_FILES['file']['tmp_name'] ) )
{
$out = fopen( "{$filePath}.part", $chunk == 0 ? "wb" : "ab" );
if ( $out )
{
$in = fopen( $_FILES['file']['tmp_name'], "rb" );
if ( $in )
{
while ( $buff = fread( $in, 4096 ) )
fwrite($out, $buff);
}
else
die( '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}' );
fclose( $in );
fclose( $out );
@unlink( $_FILES['file']['tmp_name'] );
}
else
die( '{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}' );
}
else
die( '{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}' );
}
else
{
$out = fopen( "{$filePath}.part", $chunk == 0 ? "wb" : "ab" );
if ( $out )
{
$in = fopen( "php://input", "rb" );
if ( $in )
{
while ( $buff = fread( $in, 4096 ) )
fwrite( $out, $buff );
}
else
die( '{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}' );
fclose( $in );
fclose( $out );
}
else
die( '{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}' );
}
if ( !$chunks || $chunk == $chunks - 1 )
{
rename( "{$filePath}.part", $filePath );
$mdb -> insert( 'pp_articles_files', [
'article_id' => null,
'src' => substr( $filePath, 5, strlen( $filePath ) )
] );
$file_id = $mdb -> id();
$file_name = explode( '/', $filePath );
$file_name = $file_name[ count( $file_name ) - 1 ];
}
die( '{"jsonrpc" : "2.0", "result" : null, "id" : "id", "file_name" : "' . $file_name . '", "file_id" : "' . $file_id . '"}' );
?>