Joywork/ajax/partner_settings_api.php

884 lines
28 KiB
PHP
Raw Permalink Normal View History

2026-05-22 20:21:54 +02:00
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/config.php");
if (!class_exists('SelectelApi')) {
$p1 = $_SERVER['DOCUMENT_ROOT'] . "/SelectelApi.php";
$p2 = $_SERVER['DOCUMENT_ROOT'] . "/classes/SelectelApi.php";
$p3 = $_SERVER['DOCUMENT_ROOT'] . "/lib/SelectelApi.php";
if (file_exists($p1)) require_once($p1);
else if (file_exists($p2)) require_once($p2);
else if (file_exists($p3)) require_once($p3);
}
header('Content-Type: application/json; charset=utf-8');
function ps_json($arr) {
echo json_encode($arr);
exit;
}
function ps_need_auth() {
if (empty($_SESSION['agency_id']) || empty($_SESSION['id'])) {
ps_json(array('ok' => 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('<br>', $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' => 'Неизвестное действие'));