false, 'error' => 'Нет доступа')); } } function ps_es($s) { return mysql_real_escape_string($s); } function ps_post_str($key, $def) { if (isset($_POST[$key])) return (string)$_POST[$key]; return (string)$def; } function ps_post_int($key) { if (isset($_POST[$key])) return (int)$_POST[$key]; return 0; } function ps_safe_ext($name) { $name = (string)$name; $pos = strrpos($name, '.'); if ($pos === false) return ''; $ext = substr($name, $pos + 1); $ext = preg_replace('/[^a-zA-Z0-9]+/', '', $ext); $ext = strtolower($ext); if (strlen($ext) > 12) $ext = substr($ext, 0, 12); return $ext; } function ps_max_file_size_bytes() { return 20 * 1024 * 1024; } function ps_allowed_ext_map() { return array( 'pdf' => array('application/pdf'), 'doc' => array('application/msword', 'application/octet-stream'), 'docx' => array( 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/octet-stream' ), 'rtf' => array('application/rtf', 'text/rtf', 'application/octet-stream'), 'txt' => array('text/plain', 'application/octet-stream'), 'xls' => array('application/vnd.ms-excel', 'application/octet-stream'), 'xlsx' => array( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/octet-stream' ), 'csv' => array('text/csv', 'text/plain', 'application/vnd.ms-excel', 'application/octet-stream'), 'jpg' => array('image/jpeg'), 'jpeg' => array('image/jpeg'), 'png' => array('image/png'), 'webp' => array('image/webp'), ); } function ps_denied_ext_list() { return array( 'exe','bat','cmd','com','msi','sh', 'js','mjs','cjs', 'php','php3','php4','php5','phtml','phar', 'xlsm','docm','pptm', 'zip','rar','7z','tar','gz' ); } function ps_detect_mime($tmpPath) { $mime = ''; if (function_exists('finfo_open')) { $fi = @finfo_open(FILEINFO_MIME_TYPE); if ($fi) { $m = @finfo_file($fi, $tmpPath); if (is_string($m)) $mime = $m; @finfo_close($fi); } } if ($mime === '' && function_exists('mime_content_type')) { $m = @mime_content_type($tmpPath); if (is_string($m)) $mime = $m; } return strtolower(trim((string)$mime)); } function ps_read_magic($tmpPath, $len) { $fh = @fopen($tmpPath, 'rb'); if (!$fh) return ''; $bin = @fread($fh, (int)$len); @fclose($fh); if (!is_string($bin)) return ''; return $bin; } function ps_is_zip_like($tmpPath) { $head = ps_read_magic($tmpPath, 4); return (substr($head, 0, 2) === "PK"); } function ps_magic_ok_by_ext($ext, $tmpPath) { $ext = strtolower((string)$ext); if ($ext === 'pdf') { $h = ps_read_magic($tmpPath, 5); return (substr($h, 0, 4) === '%PDF'); } if ($ext === 'jpg' || $ext === 'jpeg') { $h = ps_read_magic($tmpPath, 3); return ($h === "\xFF\xD8\xFF"); } if ($ext === 'png') { $h = ps_read_magic($tmpPath, 8); return ($h === "\x89PNG\x0D\x0A\x1A\x0A"); } if ($ext === 'webp') { $h = ps_read_magic($tmpPath, 12); return (substr($h, 0, 4) === 'RIFF' && substr($h, 8, 4) === 'WEBP'); } if ($ext === 'docx' || $ext === 'xlsx') { return ps_is_zip_like($tmpPath); } return true; } function ps_is_allowed_file($origName, $tmpPath, &$errorCode, &$detectedMime) { $errorCode = ''; $detectedMime = ''; $ext = ps_safe_ext($origName); if ($ext === '') { $errorCode = 'bad_ext'; return false; } $denied = ps_denied_ext_list(); if (in_array($ext, $denied, true)) { $errorCode = 'bad_ext'; return false; } $allowedMap = ps_allowed_ext_map(); if (!isset($allowedMap[$ext])) { $errorCode = 'bad_ext'; return false; } $detectedMime = ps_detect_mime($tmpPath); if (!ps_magic_ok_by_ext($ext, $tmpPath)) { $errorCode = 'bad_mime'; return false; } $okMime = false; $allowMimes = $allowedMap[$ext]; $i = 0; while ($i < count($allowMimes)) { if ($detectedMime === strtolower($allowMimes[$i])) { $okMime = true; break; } $i++; } if (!$okMime && $detectedMime !== '') { $errorCode = 'bad_mime'; return false; } return true; } function ps_random_file_name($ext) { $ext = ps_safe_ext($ext); if ($ext === '') $ext = 'bin'; try { if (function_exists('random_bytes')) { $b = random_bytes(16); $hex = bin2hex($b); } else { $hex = md5(uniqid('', true) . mt_rand()); } } catch (Exception $e) { $hex = md5(uniqid('', true) . mt_rand()); } // 8-4-4-4-12 $name = substr($hex, 0, 8) . '-' . substr($hex, 8, 4) . '-' . substr($hex, 12, 4) . '-' . substr($hex, 16, 4) . '-' . substr($hex, 20, 12); return $name . '.' . $ext; } function ps_err_text_by_code($code, $ext) { if ($code === 'too_big') return 'Файл слишком большой. Максимум 20 МБ'; if ($code === 'bad_ext') return 'Формат .' . $ext . ' не поддерживается'; if ($code === 'bad_mime') return 'Формат .' . $ext . ' не поддерживается'; return 'Ошибка загрузки файла'; } function ps_public_root() { return 'https://data.joywork.ru'; } function ps_storage_prefix() { return 'partner/partner-materials'; } function ps_public_prefix_url() { return ps_public_root() . '/' . ps_storage_prefix(); } function ps_mime_by_ext($ext) { $ext = strtolower((string)$ext); if ($ext === 'pdf') return 'application/pdf'; if ($ext === 'doc') return 'application/msword'; if ($ext === 'docx') return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; if ($ext === 'rtf') return 'application/rtf'; if ($ext === 'txt') return 'text/plain'; if ($ext === 'xls') return 'application/vnd.ms-excel'; if ($ext === 'xlsx') return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; if ($ext === 'csv') return 'text/csv'; if ($ext === 'jpg' || $ext === 'jpeg') return 'image/jpeg'; if ($ext === 'png') return 'image/png'; if ($ext === 'webp') return 'image/webp'; return 'application/octet-stream'; } function ps_files_table() { return 'partner_material_documents'; } function ps_selectel_auth() { static $cached = null; if ($cached !== null) return $cached; if (!empty($_SESSION['selectel_token']) && !empty($_SESSION['selectel_storage_url']) && !empty($_SESSION['selectel_token_till'])) { if ((int)$_SESSION['selectel_token_till'] > time() + 60) { $cached = array((string)$_SESSION['selectel_token'], (string)$_SESSION['selectel_storage_url']); return $cached; } } if (!class_exists('SelectelApi')) { $cached = array('', ''); return $cached; } if (!method_exists('SelectelApi', 'getTokenAndUrl')) { $cached = array('', ''); return $cached; } $r = SelectelApi::getTokenAndUrl(); $token = (string)($r[0]); $storageUrl = (string)($r[1]); if ($token === '' || $storageUrl === '') { $cached = array('', ''); return $cached; } $_SESSION['selectel_token'] = $token; $_SESSION['selectel_storage_url'] = $storageUrl; $_SESSION['selectel_token_till'] = time() + 3600; $cached = array($token, $storageUrl); return $cached; } function ps_selectel_jwdata_base($storageUrl) { $storageUrl = rtrim((string)$storageUrl, '/'); return $storageUrl . '/jwdata/'; } function ps_selectel_object_from_any($value) { $s = trim((string)$value); if ($s === '') return ''; if (strpos($s, 'http://') === 0 || strpos($s, 'https://') === 0) { $path = parse_url($s, PHP_URL_PATH); $s = (string)$path; } $s = ltrim($s, '/'); $prefix = rtrim(ps_storage_prefix(), '/') . '/'; if (strpos($s, $prefix) === 0) return $s; if (preg_match('~^\d+/\d+/~', $s)) { return $prefix . $s; } return $prefix . $s; } function ps_selectel_upload_raw($baseUrl, $token, $tmpPath, $objectName, $contentType) { $fh = @fopen($tmpPath, 'rb'); if (!$fh) return false; $size = @filesize($tmpPath); if ($size === false) $size = 0; $url = rtrim((string)$baseUrl, '/') . '/' . ltrim((string)$objectName, '/'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($ch, CURLOPT_UPLOAD, 1); curl_setopt($ch, CURLOPT_INFILE, $fh); if ($size > 0) curl_setopt($ch, CURLOPT_INFILESIZE, $size); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 180); curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1024); curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 20); curl_setopt($ch, CURLOPT_HTTPHEADER, array( "X-Auth-Token: $token", "Content-Type: $contentType", "Expect:" )); curl_exec($ch); $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = (int)curl_errno($ch); curl_close($ch); fclose($fh); if ($err) return false; return ($code === 201); } function ps_selectel_delete_raw($baseUrl, $token, $objectName) { $url = rtrim((string)$baseUrl, '/') . '/' . ltrim((string)$objectName, '/'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1024); curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 20); curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-Auth-Token: $token")); curl_exec($ch); $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = (int)curl_errno($ch); curl_close($ch); if ($err) return false; if ($code === 204) return true; if ($code === 404) return true; return false; } function ps_selectel_head_raw($baseUrl, $token, $objectName) { $url = rtrim((string)$baseUrl, '/') . '/' . ltrim((string)$objectName, '/'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-Auth-Token: $token")); curl_exec($ch); $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); $err = (int)curl_errno($ch); curl_close($ch); if ($err) return 0; return $code; } function ps_selectel_upload_object($tmpPath, $objectName, $contentType) { $r = ps_selectel_auth(); $token = (string)$r[0]; $storageUrl = (string)$r[1]; if ($token === '' || $storageUrl === '') return false; $base = ps_selectel_jwdata_base($storageUrl); return ps_selectel_upload_raw($base, $token, $tmpPath, $objectName, $contentType); } function ps_selectel_delete_any($value) { $r = ps_selectel_auth(); $token = (string)$r[0]; $storageUrl = (string)$r[1]; if ($token === '' || $storageUrl === '') return false; $obj = ps_selectel_object_from_any($value); if ($obj === '') return false; $base = ps_selectel_jwdata_base($storageUrl); return ps_selectel_delete_raw($base, $token, $obj); } function ps_selectel_head_object($objectName) { $r = ps_selectel_auth(); $token = (string)$r[0]; $storageUrl = (string)$r[1]; if ($token === '' || $storageUrl === '') return 0; $base = ps_selectel_jwdata_base($storageUrl); return ps_selectel_head_raw($base, $token, $objectName); } ps_need_auth(); $agencyId = (int)$_SESSION['agency_id']; $userId = (int)$_SESSION['id']; $action = ps_post_str('action', ''); if ($action === '' && isset($_GET['action'])) $action = (string)$_GET['action']; $filesTable = ps_files_table(); if ($action === 'url_save') { $partners = new Partners(); $val = trim(ps_post_str('partner_url', '')); $ok = $partners->savePartnerUrl($val); if (!$ok) { $err = 'Ошибка'; if (!empty($partners->errors)) $err = implode('
', $partners->errors); ps_json(array('ok' => false, 'error' => $err)); } $slug = $partners->getPartnerUrl($userId); $full = $partners->getPartnerCabinetUrl($_SESSION['agency_id'], $_SESSION['id']); ps_json(array('ok' => true, 'partner_url' => $slug, 'full_url' => $full)); } if ($action === 'materials_list') { $cats = array(); $res = mysql_query("SELECT id, title FROM partner_material_categories WHERE agency_id={$agencyId} ORDER BY id ASC"); if ($res) { while ($r = mysql_fetch_assoc($res)) { $id = (int)$r['id']; $cats[$id] = array('id' => $id, 'title' => (string)$r['title'], 'files' => array()); } } if (!empty($cats)) { $ids = implode(',', array_keys($cats)); $res2 = mysql_query("SELECT id, category_id, file_path, file_name, file_size FROM {$filesTable} WHERE agency_id={$agencyId} AND category_id IN ({$ids}) AND doc_type='file' ORDER BY id ASC"); if ($res2) { while ($f = mysql_fetch_assoc($res2)) { $cid = (int)$f['category_id']; if (!isset($cats[$cid])) continue; $path = (string)$f['file_path']; $url = ''; if ($path !== '') { if (strpos($path, 'http://') === 0 || strpos($path, 'https://') === 0) { $url = $path; } else { $url = ps_public_prefix_url() . '/' . ltrim($path, '/'); } } $cats[$cid]['files'][] = array( 'id' => (int)$f['id'], 'category_id' => $cid, 'file_name' => (string)$f['file_name'], 'file_size' => (int)$f['file_size'], 'file_url' => $url, 'file_path' => $path ); } } } ps_json(array('ok' => true, 'categories' => array_values($cats))); } if ($action === 'materials_category_create') { $title = trim(ps_post_str('title', '')); if ($title === '') ps_json(array('ok' => false, 'error' => 'Введите название')); $t = ps_es($title); $ok = mysql_query("INSERT INTO partner_material_categories (agency_id, title) VALUES ({$agencyId}, '{$t}')"); if (!$ok) ps_json(array('ok' => false, 'error' => 'Ошибка создания категории')); ps_json(array('ok' => true, 'id' => (int)mysql_insert_id(), 'title' => $title)); } if ($action === 'materials_category_rename') { $categoryId = ps_post_int('category_id'); $title = trim(ps_post_str('title', '')); if ($categoryId <= 0) ps_json(array('ok' => false, 'error' => 'Категория не выбрана')); if ($title === '') ps_json(array('ok' => false, 'error' => 'Введите название')); $t = ps_es($title); $ok = mysql_query("UPDATE partner_material_categories SET title='{$t}' WHERE agency_id={$agencyId} AND id={$categoryId} LIMIT 1"); if (!$ok) ps_json(array('ok' => false, 'error' => 'Ошибка переименования')); ps_json(array('ok' => true)); } if ($action === 'materials_category_delete') { $categoryId = ps_post_int('category_id'); if ($categoryId <= 0) ps_json(array('ok' => false, 'error' => 'Категория не выбрана')); $res = mysql_query("SELECT file_path FROM {$filesTable} WHERE agency_id={$agencyId} AND category_id={$categoryId} AND doc_type='file'"); if ($res) { while ($r = mysql_fetch_assoc($res)) { $p = (string)$r['file_path']; if ($p !== '') ps_selectel_delete_any($p); } } mysql_query("DELETE FROM {$filesTable} WHERE agency_id={$agencyId} AND category_id={$categoryId} AND doc_type='file'"); $ok = mysql_query("DELETE FROM partner_material_categories WHERE agency_id={$agencyId} AND id={$categoryId} LIMIT 1"); if (!$ok) ps_json(array('ok' => false, 'error' => 'Ошибка удаления категории')); ps_json(array('ok' => true)); } if ($action === 'materials_files_upload') { $categoryId = ps_post_int('category_id'); if ($categoryId <= 0) ps_json(array('ok' => false, 'error' => 'Категория не выбрана')); $chk = mysql_query("SELECT id FROM partner_material_categories WHERE agency_id={$agencyId} AND id={$categoryId} LIMIT 1"); if (!$chk || !mysql_num_rows($chk)) ps_json(array('ok' => false, 'error' => 'Категория не найдена')); if (!isset($_FILES['files'])) ps_json(array('ok' => false, 'error' => 'Файлы не переданы')); $names = $_FILES['files']['name']; $tmp = $_FILES['files']['tmp_name']; $size = $_FILES['files']['size']; $err = $_FILES['files']['error']; if (!is_array($names)) { $names = array($names); $tmp = array($tmp); $size = array($size); $err = array($err); } $count = count($names); if ($count <= 0) ps_json(array('ok' => false, 'error' => 'Файлы не выбраны')); $r = ps_selectel_auth(); if ((string)$r[0] === '' || (string)$r[1] === '') { ps_json(array('ok' => false, 'error' => 'Selectel token/url пустые')); } $created = array(); $errorsOut = array(); $i = 0; while ($i < $count) { $e = (int)$err[$i]; $origName = isset($names[$i]) ? (string)$names[$i] : ''; $tmpName = isset($tmp[$i]) ? (string)$tmp[$i] : ''; $fsize = isset($size[$i]) ? (int)$size[$i] : 0; if ($e !== 0 || $tmpName === '' || !is_uploaded_file($tmpName)) { $errorsOut[] = array( 'file_name' => $origName, 'message' => 'Ошибка загрузки файла' ); $i++; continue; } $ext = ps_safe_ext($origName); if ($ext === '') $ext = 'unknown'; if ($fsize <= 0 || $fsize > ps_max_file_size_bytes()) { $errorsOut[] = array( 'file_name' => $origName, 'message' => ps_err_text_by_code('too_big', $ext) ); $i++; continue; } $detectedMime = ''; $errCode = ''; if (!ps_is_allowed_file($origName, $tmpName, $errCode, $detectedMime)) { $errorsOut[] = array( 'file_name' => $origName, 'message' => ps_err_text_by_code($errCode, $ext) ); $i++; continue; } $storedFileName = ps_random_file_name($ext); $objectName = rtrim(ps_storage_prefix(), '/') . '/' . $agencyId . '/' . $categoryId . '/' . $storedFileName; $publicUrl = ps_public_root() . '/' . ltrim($objectName, '/'); $contentType = ps_mime_by_ext($ext); $uploaded = ps_selectel_upload_object($tmpName, $objectName, $contentType); if (!$uploaded) { $errorsOut[] = array( 'file_name' => $origName, 'message' => 'Ошибка загрузки файла' ); $i++; continue; } $swiftCode = ps_selectel_head_object($objectName); if ($swiftCode !== 200) { ps_selectel_delete_any($objectName); $errorsOut[] = array( 'file_name' => $origName, 'message' => 'Ошибка загрузки файла' ); $i++; continue; } $dbMime = ($detectedMime !== '') ? $detectedMime : $contentType; $fp = ps_es($publicUrl); $on = ps_es($origName); $mm = ps_es($dbMime); $ttl = ps_es($origName); $sql = "INSERT INTO {$filesTable} (agency_id, category_id, title, doc_type, file_path, file_name, file_mime, file_size, link_url, text_content) VALUES ({$agencyId}, {$categoryId}, '{$ttl}', 'file', '{$fp}', '{$on}', '{$mm}', {$fsize}, '', NULL)"; $ok = mysql_query($sql); if ($ok) { $id = (int)mysql_insert_id(); $created[] = array( 'id' => $id, 'file_name' => $origName, 'file_size' => $fsize, 'file_url' => $publicUrl, 'file_path' => $publicUrl ); } else { ps_selectel_delete_any($objectName); $errorsOut[] = array( 'file_name' => $origName, 'message' => 'Ошибка сохранения в базе' ); } $i++; } ps_json(array( 'ok' => true, 'created' => $created, 'errors' => $errorsOut )); } if ($action === 'materials_file_delete') { $fileId = ps_post_int('file_id'); if ($fileId <= 0) ps_json(array('ok' => false, 'error' => 'Файл не выбран')); $p = ''; $res = mysql_query("SELECT file_path FROM {$filesTable} WHERE agency_id={$agencyId} AND id={$fileId} AND doc_type='file' LIMIT 1"); if ($res && mysql_num_rows($res)) { $r = mysql_fetch_assoc($res); $p = (string)$r['file_path']; } $ok = mysql_query("DELETE FROM {$filesTable} WHERE agency_id={$agencyId} AND id={$fileId} AND doc_type='file' LIMIT 1"); if (!$ok) ps_json(array('ok' => false, 'error' => 'Ошибка удаления')); if ($p !== '') ps_selectel_delete_any($p); ps_json(array('ok' => true)); } if ($action === 'news_list') { $newsItems = array(); $sql = "SELECT id, title, body_html, is_important, created_at FROM partner_news WHERE agency_id={$agencyId} ORDER BY is_important DESC, id DESC"; $res = mysql_query($sql); if (!$res) ps_json(array('ok' => false, 'error' => 'SQL ошибка: ' . mysql_error())); while ($row = mysql_fetch_assoc($res)) { $newsItems[] = array( 'id' => (int)$row['id'], 'title' => (string)$row['title'], 'body_html' => (string)$row['body_html'], 'is_important' => (int)$row['is_important'], 'created_at' => (string)$row['created_at'] ); } ps_json(array('ok' => true, 'items' => $newsItems)); } if ($action === 'news_create') { $newsTitle = trim(ps_post_str('title', '')); $newsBodyHtml = (string)ps_post_str('body_html', ''); $isImportant = ps_post_int('is_important') ? 1 : 0; if ($newsTitle === '') ps_json(array('ok' => false, 'error' => 'Введите заголовок')); $newsBodyHtml = str_replace("\0", '', $newsBodyHtml); $newsTitleSql = ps_es($newsTitle); $newsBodySql = ps_es($newsBodyHtml); $insertSql = "INSERT INTO partner_news (`agency_id`, `title`, `body_html`, `is_important`, `created_at`, `updated_at`) VALUES ({$agencyId}, '{$newsTitleSql}', '{$newsBodySql}', {$isImportant}, NOW(), NOW())"; $insertOk = mysql_query($insertSql); if (!$insertOk) ps_json(array('ok' => false, 'error' => 'Ошибка создания новости: ' . mysql_error())); ps_json(array('ok' => true, 'id' => (int)mysql_insert_id())); } if ($action === 'news_update') { $newsId = ps_post_int('news_id'); $newsTitle = trim(ps_post_str('title', '')); $newsBodyHtml = (string)ps_post_str('body_html', ''); $isImportant = ps_post_int('is_important') ? 1 : 0; if ($newsId <= 0) ps_json(array('ok' => false, 'error' => 'Некорректный ID новости')); if ($newsTitle === '') ps_json(array('ok' => false, 'error' => 'Введите заголовок')); $newsBodyHtml = str_replace("\0", '', $newsBodyHtml); $newsTitleSql = ps_es($newsTitle); $newsBodySql = ps_es($newsBodyHtml); $updateSql = "UPDATE partner_news SET `title` = '{$newsTitleSql}', `body_html` = '{$newsBodySql}', `is_important` = {$isImportant}, `updated_at` = NOW() WHERE `id` = {$newsId} AND `agency_id` = {$agencyId} LIMIT 1"; $updateOk = mysql_query($updateSql); if (!$updateOk) ps_json(array('ok' => false, 'error' => 'Ошибка обновления новости: ' . mysql_error())); if (function_exists('mysql_affected_rows') && mysql_affected_rows() < 0) { ps_json(array('ok' => false, 'error' => 'Не удалось обновить новость')); } ps_json(array('ok' => true, 'id' => (int)$newsId)); } if ($action === 'news_delete') { $newsId = ps_post_int('news_id'); if ($newsId <= 0) ps_json(array('ok' => false, 'error' => 'Новость не выбрана')); $ok = mysql_query("DELETE FROM partner_news WHERE agency_id={$agencyId} AND id={$newsId} LIMIT 1"); if (!$ok) ps_json(array('ok' => false, 'error' => 'Ошибка удаления новости: ' . mysql_error())); ps_json(array('ok' => true)); } if ($action === 'ckeditor_exportpdf_token') { header('Content-Type: application/json; charset=utf-8'); echo json_encode(array('token' => '')); exit; } if ($action === 'materials_file_download') { $fileId = 0; if (isset($_GET['file_id'])) $fileId = (int)$_GET['file_id']; if ($fileId <= 0) { header('HTTP/1.1 400 Bad Request'); echo 'file_id missing'; exit; } $res = mysql_query("SELECT file_path, file_name, file_mime, file_size FROM {$filesTable} WHERE agency_id={$agencyId} AND id={$fileId} AND doc_type='file' LIMIT 1"); if (!$res || !mysql_num_rows($res)) { header('HTTP/1.1 404 Not Found'); echo 'not found'; exit; } $r = mysql_fetch_assoc($res); $url = (string)($r['file_path']); if ($url !== '' && strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) { $url = ps_public_prefix_url() . '/' . ltrim($url, '/'); } if ($url === '') { header('HTTP/1.1 404 Not Found'); echo 'empty path'; exit; } $fname = (string)($r['file_name']); if ($fname === '') $fname = 'file'; $fname = preg_replace('/[\r\n]+/', ' ', $fname); $fname = str_replace(array('"', '\\'), array("'", ''), $fname); $mime = (string)($r['file_mime']); if ($mime === '') $mime = 'application/octet-stream'; $size = (int)($r['file_size'] ); header('Content-Type: ' . $mime); header('Content-Disposition: attachment; filename="' . $fname . '"'); header('X-Content-Type-Options: nosniff'); header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Pragma: no-cache'); if ($size > 0) header('Content-Length: ' . $size); $out = fopen('php://output', 'wb'); if (!$out) { header('HTTP/1.1 500 Internal Server Error'); echo 'output error'; exit; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0); curl_setopt($ch, CURLOPT_FILE, $out); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 0); curl_exec($ch); curl_close($ch); fclose($out); exit; } ps_json(array('ok' => false, 'error' => 'Неизвестное действие'));