Joywork/engine/classes/AdvertStats.php
2026-05-22 21:21:54 +03:00

2573 lines
118 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
class AdvertStats {
public $debug = false;
public $errors = [];
public $logs = [];
private $_db = null;
private $_user = null;
private $_agency_id;
private $_session_key = 'advert_stats';
private $_is_cli = false;
private $_api_attempts = 0;
private $_curl_attempts = 0;
private $_tokens = [];
private $_api_id = 0;
public static $_serviceList = [
1 => 'avito',
2 => 'cian',
3 => 'yandex',
4 => 'domclick',
];
public function __construct($db = null, $debug = false) {
if ($debug == true) {
$this->debug = true;
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
}
if (isset($_SESSION['id'])) {
if (isset($user)) {
$this->_user = $user;
} else {
$user_id = intval($_SESSION['id']);
$user = new User;
$user->get($user_id);
$this->_user = $user;
}
} else {
$this->_user = null;
}
if (!is_null($this->_user))
$this->_agency_id = User::getUserAgencyID($this->_user->id);
if (!is_null($db)) {
$this->_db = $db;
} else {
$pdo = new MysqlPdo(hst, ndb, user, pass);
$pdo->query("SET NAMES 'utf8'");
$this->_db = $pdo;
}
$this->_is_cli = isset($_SESSION);
}
private function _request($url, $options = null, $test = false) {
$this->_curl_attempts++;
if ($this->debug)
$this->logs[] = 'Попытка запроса: ' . $this->_curl_attempts . ' по URL: ' . $url;
$headers = [];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CERTINFO, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // запретить проверку сертификата удаленного сервера
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0");
curl_setopt($ch, CURLOPT_REFERER, "https://joywork.ru/");
curl_setopt($ch, CURLOPT_HEADER, 0); // При установке этого параметра в 1 результат будет включать полученные заголовки.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // При установке этого параметра в ненулевое значение CURL будет возвращать результат, а не выводить его.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //при получении HTTP заголовка "Location: " будет происходить перенаправление на указанный этим заголовком URL
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
if (!is_null($options)) {
if (isset($options['auth']) && isset($options['token'])) {
if ($options['auth'] == 'bearer') {
$headers[] = "Authorization: Bearer " . $options['token'];
} else if ($options['auth'] == 'oauth') {
$headers[] = "Authorization: OAuth " . $options['token'];
} else if ($options['auth'] == 'token') {
$headers[] = "Authorization: Token " . $options['token'];
}
}
if (isset($options['method'])) {
if ($options['method'] == 'post') {
curl_setopt($ch, CURLOPT_POST, 1);
}
} else {
curl_setopt($ch, CURLOPT_POST, 0);
}
if (isset($options['data'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($options['data']));
}
if (isset($options['type'])) {
if ($options['type'] == 'json') {
$headers[] = "Accept: application/json";
$headers[] = "Content-Type: application/json";
} else if ($options['type'] == 'xml') {
$headers[] = "Accept: application/xml";
$headers[] = "Content-Type: application/xml";
}
}
if (isset($options['headers']) && is_array($options['headers'])) {
$headers = array_merge($headers, $options['headers']);
}
}
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$content = curl_exec($ch);
if (isset($_GET['dev']))
echo "<pre style='color: darkgreen; font-family: monospace;'>" . var_export(curl_getinfo($ch), true) . "</pre>";
if ($test) {
$error = curl_error($ch);
// var_dump($error);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// var_dump(curl_getinfo($ch));
return [
'success' => ((int)$code === 200)
];
}
curl_close($ch);
if ((is_null($content) || $content == false) && !$test && $this->_curl_attempts < 3) {
return $this->_request($url, $options, $test);
} else {
$this->_curl_attempts = 0;
}
return $content;
}
private function _getAuthToken($service = null, $client_id = null, $secret_key = null) {
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения токена авторизации API';
if (is_null($client_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `client_id` для получения токена авторизации API';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения токена авторизации API';
if (is_null($service) || (is_null($client_id) && strtolower($service) == 'avito') || is_null($secret_key))
return false;
$token = null;
switch (strtolower($service)) {
case 'avito' :
if (isset($_SESSION[$this->_session_key]['avito'])) {
$stored = $_SESSION[$this->_session_key]['avito'];
if (time() <= intval($stored['expires'])) {
$token = $stored['token'];
}
}
if (is_null($token) || $this->_is_cli) {
//var_dump($this->_tokens);
if (isset($this->_tokens['avito']) && !is_null($this->_tokens['avito'])) {
$stored = $this->_tokens['avito'];
if (time() <= intval($stored['expires'])) {
$token = $stored['token'];
}
}
// var_dump($this->_api_id);
if(empty($token) && $this->_api_id > 0){
$sql = "SELECT * FROM users_api WHERE id = {$this->_api_id}";
echo $sql;
$q = $this->_db->query($sql);
$api = $this->_db->fetch_assoc($q);
if(isset($api['token']) && !empty($api['token'])){
if (time() <= intval($api['expires_in'])) {
$token = $api['token'];
}
}
}
if (is_null($token)) {
$url = "https://api.avito.ru/token/?grant_type=client_credentials&client_id=$client_id&client_secret=$secret_key";
$response = $this->_request($url, ['type' => 'json', 'method' => 'post']);
if ($this->debug)
$this->logs["https://api.avito.ru/token/?grant_type=client_credentials&client_id=$client_id&client_secret=$secret_key"] = $response;
$data = json_decode($response, true);
$token = $data['access_token'];
if($this->_api_id > 0){
$expires = intval($data['expires_in']) + time();
$sql_in = "UPDATE users_api set token='{$token}', expires_in='{$expires}' WHERE id = {$this->_api_id}";
$this->_db->query($sql_in);
}
if ($this->_is_cli) {
$this->_tokens['avito'] = [
'expires' => intval($data['expires_in']) + time(),
'type' => strtolower($data['token_type']),
'token' => $token,
];
return $token;
} else {
if ($token) {
$_SESSION[$this->_session_key]['avito'] = [
'expires' => intval($data['expires_in']) + time(),
'type' => strtolower($data['token_type']),
'token' => $token,
];
}
}
}
}
break;
case 'cian' :
$token = $secret_key;
break;
case 'yandex' :
$token = $secret_key;
break;
case 'domclick' :
$token = $secret_key;
break;
}
return $token;
}
private function _getObjectsIds($service = null, $agency_id = null) {
$sql = "SELECT `objects`.`id`, `objects`.`nazv`
FROM `objects` AS `objects`
WHERE `objects`.`archive` <> 1 AND
`objects`.`use_in_advert` > 0";
switch (strtolower($service)) {
case 'avito' :
$sql .= " AND `objects`.`add_to_avito_feed` > 0";
break;
case 'cian' :
$sql .= " AND `objects`.`add_to_cian_feed` > 0";
break;
case 'yandex' :
$sql .= " AND `objects`.`add_to_bn_feed` > 0";
break;
case 'domclick' :
$sql .= " AND `objects`.`add_to_domclick_feed` > 0";
break;
}
$sql .= " AND `objects`.`id_add_user` IN (
SELECT `id` FROM `users`
WHERE `id` = $agency_id OR
`id_manager` = $agency_id OR
`id_manager` IN (
SELECT `id` FROM `users`
WHERE `id_manager` = $agency_id
) OR
`id_manager` IN (
SELECT `id` FROM `users`
WHERE `id_manager` IN (
SELECT `id` FROM `users`
WHERE `id_manager` = $agency_id
)
)
)";
$rez = $this->_db->query($sql);
$obj_ids = [];
while ($object = $this->_db->fetch_assoc($rez)) {
$obj_id = $object['id'];
$obj_ids[$obj_id] = $object['nazv'];
}
return $obj_ids;
}
private static function _getServiceList() {
return self::$_serviceList;
}
public static function getServiceName($service_id = null) {
$serviceList = self::_getServiceList();
return $serviceList[$service_id];
}
public static function getServiceByName($service = null) {
return array_search($service, self::_getServiceList());
}
public static function cleanUpStats($service = null, $object_id = null, $agency_id = null) {
if (is_null($agency_id))
$agency_id = User::getUserAgencyID();
$service_id = self::getServiceByName($service);
if (!is_null($service_id) && !is_null($object_id) && !is_null($agency_id)) {
$sql = "DELETE FROM `ads_stats` WHERE `service_id` = '$service_id' AND `object_id` = '$object_id' AND `agency_id` = '$agency_id'";
return mysql_query($sql);
}
return false;
}
private function _getAvitoReportsIds($ext_user_id, $client_id, $secret_key, $page = 1) {
$reportIds = [];
if ($page > 1)
$url = "https://api.avito.ru/autoload/v1/accounts/$ext_user_id/reports/?page=".intval($page);
else
$url = "https://api.avito.ru/autoload/v1/accounts/$ext_user_id/reports/";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'type' => 'json'
];
if ($response = $this->_request($url, $options))
$this->logs[] = "Успешное обращение к серверу API Авито.";
else
$this->logs[] = "Произошла ошибка обращения к серверу API Авито.";
if ($this->debug)
$this->logs[$url] = $response;
$results = null;
try {
$results = json_decode($response, true);
$this->logs[] = $results;
if (is_array($results)) {
// собираем ИД последних рапортов за сутки по выгрузке и индексации фидов
$r_count = 0;
foreach ($results['reports'] as $report) {
if (!is_null($report['finished_at']) && $report['export_success'] == true) {
//if (strtotime($report['finished_at']) >= strtotime('-7 days')) {
$r_count++;
$reportIds[] = $report['id'];
//}
}
}
$this->logs[] = "Обработано " . $r_count . " рапортов о выгрузке от Avito";
$pages = intval($results['meta']['pages']);
$page = intval($results['meta']['page']);
$per_page = intval($results['meta']['per_page']);
$this->logs[] = "Текущая страница (оффсет): " . $page . " (" . ($page*$per_page) . ")";
if ($pages > $page) {
$page++;
$reportIds = array_merge($reportIds, $this->_getAvitoReportsIds($ext_user_id, $client_id, $secret_key, $page));
}
}
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
return $reportIds;
}
public function getStats($service_id = null, $period = null, $client_id = null, $secret_key = null, $ext_user_id = null, $object_id = null, $is_manual = false, $agency_id = null, $offset = 0) {
ini_set('memory_limit', '256M');
$this->errors = [];
$this->_api_attempts++;
if (!$is_manual)
echo "<pre>_api_attempts " .var_export($this->_api_attempts, true). "</pre>";
$service = $this->getServiceName($service_id);
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return false;
if (is_array($period)) {
$date_from = $period['date_from'];
$date_to = $period['date_to'];
} else {
$date_to = date('Y-m-d');
switch (strtolower($period)) {
case 'hour' :
$date_from = date('Y-m-d', strtotime('-1 hour'));
break;
case 'day' :
$date_from = date('Y-m-d', strtotime('-1 day'));
break;
case 'week' :
$date_from = date('Y-m-d', strtotime('-1 week'));
break;
case 'month' :
$date_from = date('Y-m-d', strtotime('-1 month'));
break;
default :
$date_from = date('Y-m-d', strtotime('-1 week'));
break;
}
}
$output = [];
$reports = [];
if (is_null($agency_id))
$agency_id = $this->_agency_id;
switch (strtolower($service)) {
case 'avito' :
// собираем ИД последних рапортов по выгрузке и индексации фидов
$reportIds = $this->_getAvitoReportsIds($ext_user_id, $client_id, $secret_key, 1, 1);
// Инвертируем список рапортов, будем шагать от старого к новому
//$reportIds = array_reverse($reportIds);
if (!$is_manual) {
echo "<pre>Всего обработано рапортов о выгрузке: " .count($reportIds). "</pre>";
echo "<pre>Рапорты о выгрузке: " . var_export($reportIds, true) . "</pre>";
}
if (count($reportIds)) {
$ads = [];
$objs = [];
$adsIds = [];
$service = $this->getServiceName($service_id);
$obj_ids = $this->_getObjectsIds($service, $agency_id);
if (!$is_manual) {
echo "<pre>Всего выгружается объектов: " . count($obj_ids) . "</pre>";
echo "<pre>Выгружаемые объекты: " . var_export($obj_ids, true) . "</pre>";
}
// обработка каждого рапорта и сбор ИД объявлений/объектов
$report_num = 0;
foreach ($reportIds as $reportId) {
if (!$is_manual)
echo "<pre>Обработка рапорта №: " . $reportId . "</pre>";
$report_status = false;
if (!is_null($reportId)) {
$url = "https://api.avito.ru/autoload/v1/accounts/$ext_user_id/reports/$reportId/";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'type' => 'json'
];
if ($response = $this->_request($url, $options))
$this->logs[date('Y-m-d H:i:s')][] = "Успешное обращение к серверу API Авито.";
else
$this->logs[date('Y-m-d H:i:s')][] = "Произошла ошибка обращения к серверу API Авито.";
if ($this->debug)
$this->logs["https://api.avito.ru/autoload/v1/accounts/$ext_user_id/reports/$reportId/"] = $response;
$results = null;
try {
$results = json_decode($response, true);
if (is_array($results)) {
if (!$is_manual)
echo "<pre>В рапорте № " . $reportId . " объвлений: ". count($results['report']['ads']) ."</pre>";
$added_count = 0;
foreach ($results['report']['ads'] as $offer) {
//if (isset($offer['avito_id']) && isset($offer['ad_id'])) {
//if ($offer['statuses']['avito']) {
$ads_id = intval($offer['avito_id']);
$obj_id = intval($offer['ad_id']);
//if (array_key_exists($obj_id, array_keys($obj_ids))) { // только существующие и рекламируемые объекты JW
if (!array_key_exists($obj_id, $ads)) {
$ads[$obj_id] = array_merge($offer, ['object_id' => $obj_id]);
$adsIds[] = $ads_id;
$objs[$ads_id] = $obj_id;
$added_count++;
if (!$is_manual)
echo "<pre> - получен ИД объекта № " . $obj_id . ", ИД объвления на Авито: " . $ads_id . "</pre>";
}
if (!isset($offer['avito_id']) && !$is_manual)
echo "<pre style='color: #a4402c;'>- для объекта $obj_id не присвоен ИД объвления на авито</pre>";
if (!isset($offer['ad_id']) && !$is_manual)
echo "<pre style='color: #a4402c;'>- не присвоен ИД объекта для объявления $ads_id на авито</pre>";
//}
//}
//}
}
$report_status = true;
if (!$is_manual)
echo "<pre> По рапорту № " . $reportId . " обработано всего ИД объвлений: ". $added_count ."</pre>";
}
} catch (\Exception $exception) {
$this->logs[date('Y-m-d H:i:s')][] = $exception;
}
}
if (!$is_manual)
echo "<pre>Статус обработки рапорта №: " . $reportId . " - завершено ". ($report_status) ? 'успешно' : 'с ошибкой' ."</pre>";
sleep(5);
$report_num++;
if ($report_num > 5) // (!) обрабатывает только 3 последних рапорта
break;
}
$not_stored_obj = array_diff(array_keys($obj_ids), array_values($objs));
if ($this->debug)
$this->logs[date('Y-m-d H:i:s')][] = "Объекты, по которым не удалось получить статистику: " . implode(', ', $not_stored_obj);
if (!$is_manual) {
echo "<pre>Всего объявлений получено: " . count($ads) . "</pre>";
echo "<pre>Объявления: " . var_export($ads, true) . "</pre>";
echo "<pre>Объекты, по которым не удалось получить статистику: " . implode(', ', $not_stored_obj) . "</pre>";
}
$adsIds = array_filter($adsIds, function($value) {
return ($value !== null && $value !== false && $value !== 0);
});
if (count($ads) > 0 && count($adsIds) > 0) {
if (is_null($offset) || !is_numeric($offset))
$offset = 0;
if (!$is_manual)
echo "<pre>Собираем статистику для объявлений: " .var_export($adsIds, true). "</pre>";
$itemsIds = array_slice($adsIds, $offset, 200);
if (count($itemsIds)) {
$_offset = 0;
$_total = count($ads);
if ($_total > $_offset && $offset !== $_offset) {
$_offset += 200;
$offset = $_offset;
} else {
$offset = null;
}
$this->logs["count(itemsIds)"][] = count($itemsIds);
$this->logs["itemsIds"][] = $itemsIds;
$this->logs["total"][] = $_total;
$this->logs["offset"][] = $offset;
if ($this->debug)
$this->logs["avito->total"][] = $_total;
if ($this->debug)
$this->logs["avito->offset"][] = $offset;
if (!$is_manual) {
echo "<pre>total " . $_total . "</pre>";
echo "<pre>offset " . $offset . "</pre>";
}
// обработка ошибок и сбор мета-данных по каждому объявлению
foreach ($ads as $offer) {
$obj_id = $offer['object_id'];
if (count($offer['messages']) > 0) {
foreach ($offer['messages'] as $message) {
//if ($message['type'] == 'error' || $message['type'] == 'warning') {
if ($message['type'] == 'error') {
if (!is_null($message['description'])) {
$reports[$obj_id]['errors'][] = $message['description'];
}
if (!$is_manual)
echo "<pre> - ошибка размещения у объекта $obj_id: " .$message['description']. "</pre>";
}
}
// Запись в сфинкс флага об ошибке размещения
try {
if (!is_null($this->_db_sphinx)) {
if (count($reports[$obj_id]['errors']) > 0)
$this->_db_sphinx->query("UPDATE objects SET ads_error = 1 WHERE id = $obj_id");
else
$this->_db_sphinx->query("UPDATE objects SET ads_error = 0 WHERE id = $obj_id");
}
} catch (\Exception $exception) {
$this->errors[] = $exception;
}
}
if ($offer['statuses']['general']['value'] == 'success' || $offer['statuses']['avito']['value'] == 'active')
$reports[$obj_id]['success'] = true;
else
$reports[$obj_id]['success'] = false;
if (isset($offer['url']))
$reports[$obj_id]['url'] = $offer['url'];
else
$reports[$obj_id]['url'] = null;
}
// Запрос и сбор статистики по просмотрам
$url = "https://api.avito.ru/stats/v1/accounts/$ext_user_id/items";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'post',
'type' => 'json',
'data' => [
'dateFrom' => $date_from,
'dateTo' => $date_to,
'fields' => [
'uniqViews',
'uniqContacts',
'uniqFavorites'
],
'itemIds' => array_values($itemsIds)
]
];
if (!$is_manual)
echo "<pre>Собираем статистику лишь для объявлений: " .var_export($itemsIds, true). "</pre>";
$response = $this->_request($url, $options);
if ($this->debug)
$this->logs["https://api.avito.ru/stats/v1/accounts/$ext_user_id/items"] = $response;
if (!$is_manual)
echo "<pre>response " .var_export($response, true). "</pre>";
try {
if ($results = json_decode($response, true)) {
if (isset($results['result']['items'])) {
foreach ($results['result']['items'] as $item) {
//$this->logs[date('Y-m-d H:i:s')][] = $results['result']['items'];
$ad_id = $item['itemId'];
if ($obj_id = $objs[$ad_id]) {
foreach ($item['stats'] as $stats) {
$reports[$obj_id]['views'] += intval($stats['uniqViews']);
$reports[$obj_id]['contacts'] += intval($stats['uniqContacts']);
$reports[$obj_id]['favorites'] += intval($stats['uniqFavorites']);
}
}
}
}
} else {
$this->logs[date('Y-m-d H:i:s')][] = "Ошибка разбора ответа от API Авито.";
}
} catch (\Exception $exception) {
$this->logs[date('Y-m-d H:i:s')][] = $exception;
}
sleep(5);
// запрос и сбор статистики по звонкам
$url = "https://api.avito.ru/core/v1/accounts/$ext_user_id/calls/stats/";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'post',
'type' => 'json',
'data' => [
'dateFrom' => $date_from,
'dateTo' => $date_to,
'itemIds' => array_values($itemsIds)
]
];
$response = $this->_request($url, $options);
if ($this->debug)
$this->logs["https://api.avito.ru/core/v1/accounts/$ext_user_id/calls/stats/"] = $response;
try {
if ($results = json_decode($response, true)) {
if (isset($results['result']['items'])) {
$this->logs = [];
foreach ($results['result']['items'] as $item) {
//$this->logs[date('Y-m-d H:i:s')][] = $results['result']['items'];
$ad_id = $item['itemId'];
if ($obj_id = $objs[$ad_id]) {
foreach ($item['days'] as $stats) {
$reports[$obj_id]['calls'] += intval($stats['calls']);
}
}
}
$this->logs[date('Y-m-d H:i:s')][] = $ads;
}
} else {
$this->logs[date('Y-m-d H:i:s')][] = "Ошибка разбора ответа от API Авито.";
}
} catch (\Exception $exception) {
$this->logs[date('Y-m-d H:i:s')][] = $exception;
}
if (!$is_manual)
echo "<pre>reports " .var_export($reports, true). "</pre>";
if (!is_null($object_id) && in_array($object_id, $objs)) {
$output = $reports[$object_id];
}
sleep(5);
}
}
/*if (count($not_stored_obj) > 0) {
}*/
}
break;
case 'cian' :
$url = "https://public-api.cian.ru/v1/get-order";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json'
];
if ($response = $this->_request($url, $options))
$this->logs[] = "Успешное обращение к серверу API ЦИАН.";
else
$this->logs[] = "Произошла ошибка обращения к серверу API ЦИАН.";
if ($this->debug)
$this->logs["https://public-api.cian.ru/v1/get-order"] = $response;
$results = null;
try {
$results = json_decode($response, true);
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
if (is_array($results)) {
$stored_ids = [];
foreach ($results['result']['offers'] as $offer) {
$ad_id = $offer['offerId'];
$offer_id = $offer['offerId'];
$url = "https://public-api.cian.ru/v1/get-views-statistics-by-days?offerId=$ad_id&dateFrom=$date_from&dateTo=$date_to";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json'
];
$response = $this->_request($url, $options);
if ($this->debug)
$this->logs["https://public-api.cian.ru/v1/get-views-statistics-by-days?offerId=$ad_id&dateFrom=$date_from&dateTo=$date_to"] = $response;
try {
$results2 = json_decode($response, true);
$report = [];
$report['errors'] = [];
if (isset($offer['result']['message'])) {
$report['errors'] = [$offer['result']['message']];
}
if (count($offer['errors']) > 0)
$report['errors'] = array_merge($report['errors'], $offer['errors']);
//if (count($offer['warnings']) > 0)
// $report['errors'] = array_merge($report['errors'], $offer['warnings']);
if ($offer['status'] == "Published") {
$report['success'] = true;
} else {
switch ($offer['status']) {
case "Blocked" :
$report['errors'][] = "Объявление снято с публикации по причине применения санкции.";
break;
case "Deactivated" :
$report['errors'][] = "Объявление было деактивировано (было скрыто).";
break;
case "Deleted" :
$report['errors'][] = "Объявление было удалёно.";
break;
case "Draft" :
$report['errors'][] = "Объявление является черновиком.";
break;
case "Moderate" :
$report['errors'][] = "Объявление требует модерации.";
break;
case "Refused" :
$report['errors'][] = "Объявление было отклонено модератором.";
break;
case "RemovedByModerator" :
$report['errors'][] = "Объявление было удалено модератором.";
break;
case "Sold" :
$report['errors'][] = "Объявление не активно (объект продан/сдан).";
break;
}
$report['success'] = false;
}
if (isset($offer['url']))
$report['url'] = $offer['url'];
else
$report['url'] = null;
if (isset($results2['result']['viewsByDays'])) {
foreach ($results2['result']['viewsByDays'] as $stats) {
if (isset($stats['views']))
$report['views'] += intval($stats['views']);
}
} else {
$this->logs[] = "Ошибка разбора ответа от API ЦИАН.";
}
$report['calls'] = null;
$report['favorites'] = null;
if (isset($results2['result']['phoneShowsByDays'])) {
foreach ($results2['result']['phoneShowsByDays'] as $stats) {
if (isset($stats['phoneShows']))
$report['contacts'] += intval($stats['phoneShows']);
}
} else {
$this->logs[] = "Ошибка разбора ответа от API ЦИАН.";
}
$ad_id = $offer['externalId'];
$stored_ids[$offer_id] = $ad_id;
$reports[$ad_id] = $report;
// Запись в сфинкс флага об ошибке размещения
try {
if (!is_null($this->_db_sphinx)) {
if (count($reports[$ad_id]['errors']) > 0)
$this->_db_sphinx->query("UPDATE objects SET ads_error = 1 WHERE id = $ad_id");
else
$this->_db_sphinx->query("UPDATE objects SET ads_error = 0 WHERE id = $ad_id");
}
} catch (\Exception $exception) {
$this->errors[] = $exception;
}
if (!is_null($object_id) && $object_id == $ad_id) {
$output = $reports[$ad_id];
}
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
}
//...
$part = 0;
$limit = 0;
$ads_query = [];
$ads_ids_query = '';
foreach ($results['result']['offers'] as $offer) {
if (!empty($ads_ids_query))
$ads_ids_query .= "&offersIds=" . $offer['offerId'];
else
$ads_ids_query .= "?offersIds=" . $offer['offerId'];
$ads_query[$part] = "https://public-api.cian.ru/v1/get-views-statistics" . $ads_ids_query;
if ($limit > 9) {
$ads_ids_query = '';
$limit = 0;
$part++;
} else {
$limit++;
}
}
if (isset($_GET['dev'])) {
var_export($ads_query);
}
if (!empty($ads_query)) {
foreach ($ads_query as $url) {
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json'
];
$response = $this->_request($url, $options);
if ($this->debug)
$this->logs[$url] = $response;
try {
$offer = json_decode($response, true);
if (isset($offer['result']['statistics'])) {
$add_report = [];
$add_report['contacts'] = null;
$add_report['views'] = null;
$statistics = $offer['result']['statistics'];
foreach ($statistics as $offer_stats) {
if (isset($_GET['dev'])) {
var_export($offer_stats);
}
$add_report['contacts'] = intval($offer_stats['phoneShows']);
$add_report['views'] = intval($offer_stats['totalViews']);
$offer_id = $offer_stats['offerId'];
$ad_id = $stored_ids[$offer_id];
if (isset($_GET['dev'])) {
var_export($reports[$ad_id]);
var_export($add_report);
}
//if (isset($reports[$ad_id])) {
$reports[$ad_id] = array_merge($reports[$ad_id], [
'contacts' => !is_null($add_report['contacts']) ? $add_report['contacts'] : $reports[$ad_id]['contacts'],
'views' => !is_null($add_report['views']) ? $add_report['views'] : $reports[$ad_id]['views']
]);
if (!is_null($object_id) && $object_id == $ad_id) {
$output = $reports[$ad_id];
}
//}
}
}
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
sleep(2);
}
}
}
break;
case 'yandex' :
$url = "https://api.realty.yandex.net/2.0/crm/feeds";
$options = [
'auth' => 'oauth',
'token' => $this->_getAuthToken('yandex', null, $secret_key),
'method' => 'get',
'type' => 'json',
'headers' => [
'X-Authorization: Vertis crm-dff153a8ef1a90d3bff5ee378dee416606cf8915'
],
];
if ($response = $this->_request($url, $options))
$this->logs[] = "Успешное обращение к серверу API Яндекс.Недвижимость.";
else
$this->logs[] = "Произошла ошибка обращения к серверу API Яндекс.Недвижимость.";
if ($this->debug)
$this->logs["https://api.realty.yandex.net/2.0/crm/feeds"] = $response;
$results = null;
try {
$results = json_decode($response, true);
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
if (is_array($results)) {
if (isset($results['feeds'])) {
$feed_uid = null;
foreach ($results['feeds'] as $feed) {
if ($feed['url'] == "https://joywork.ru/bn_ya_feeds/$agency_id.xml") {
if ($feed['status'] == "ACCEPTED" || $feed['status'] == "ACCEPTED_WITH_REMARKS")
$feed_uid = $feed['id'];
/*if ($feed['status'] == "ACCEPTED_WITH_REMARKS")
$reports['errors'] = ["XML-фид содержащий объект обработан с замечаниями публикации."];*/
}
}
if (!is_null($feed_uid)) {
if ($offset)
$url = "https://api.realty.yandex.net/2.0/crm/offers?offset=".$offset;
else
$url = "https://api.realty.yandex.net/2.0/crm/offers";
$options = [
'auth' => 'oauth',
'token' => $this->_getAuthToken('yandex', null, $secret_key),
'method' => 'get',
'type' => 'json',
'headers' => [
'X-Authorization: Vertis crm-dff153a8ef1a90d3bff5ee378dee416606cf8915'
],
];
$response = $this->_request($url, $options);
if ($this->debug)
$this->logs["https://api.realty.yandex.net/2.0/crm/offers"] = $response;
try {
$results2 = json_decode($response, true);
$_offset = 0;
$_total = $results2['listing']['slicing']['total'];
if (isset($results2['listing']['slicing']['range']['to']))
$_offset = intval($results2['listing']['slicing']['range']['to']);
elseif (isset($results2['listing']['slicing']['fragment']['offset']))
$_offset = intval($results2['listing']['slicing']['fragment']['offset']) + 100;
if ($_total > $_offset && $offset !== $_offset)
$offset = $_offset;
else
$offset = null;
if ($this->debug)
$this->logs["yandex->offset"][] = $offset;
$this->logs['yandex->offers'] = $results2;
if (isset($results2['listing']['snippets'])) {
foreach ($results2['listing']['snippets'] as $value) {
$offer = $value['offer'];
if ($feed_uid == $offer['feedId']) {
$report = [];
$ad_id = $offer['id'];
$url = "https://api.realty.yandex.net/2.0/crm/offer/$ad_id/stats?startTime=$date_from&endTime=$date_to";
$options = [
'auth' => 'oauth',
'token' => $this->_getAuthToken('yandex', null, $secret_key),
'method' => 'get',
'type' => 'json',
'headers' => [
'X-Authorization: Vertis crm-dff153a8ef1a90d3bff5ee378dee416606cf8915'
],
];
$response = $this->_request($url, $options);
if ($this->debug)
$this->logs["https://api.realty.yandex.net/2.0/crm/offer/$ad_id/stats?startTime=$date_from&endTime=$date_to"] = $response;
try {
$report['success'] = (empty($offer['state'])) ? true : false;
/*if (count($offer['state']['errors']) > 0)
$report['errors'] = array_merge($reports['errors'], $offer['state']['errors']['type']);*/
if (count($offer['state']['errors']) > 0) {
foreach ($offer['state']['errors'] as $error) {
switch ($error['type']) {
case 'AD_ON_PHOTO' :
$report['errors'][] = "На фотографиях размещена рекламная информация.";
break;
case 'AGENT_PHONE_NOT_SET' :
$report['errors'][] = "Телефон агента или продавца не указан или указан в неправильном формате.";
break;
case 'BAD_PHOTO' :
$report['errors'][] = "В объявлении используются неинформативные фотографии.";
break;
case 'BAN_OFFERS_WITHOUT_CADASTRAL_NUMBER' :
$report['errors'][] = "Пропущено обязательное поле.";
break;
case 'BANNED_AGENCY' :
$report['errors'][] = "Объявления этого агентства имеют низкий уровень достоверности.";
break;
case 'CHECK_ALREADY_BOOKED' :
$report['errors'][] = "При проверке выяснилось, что объект находится под залогом.";
break;
case 'CHECK_INCORRECT_WATERMARK' :
$report['errors'][] = "В объявлении используются фотографии, на которых есть посторонние изображения.";
break;
case 'CHECK_OFFER_IS_AD' :
$report['errors'][] = "Проверка модератором: объявление носит рекламный характер.";
break;
case 'CHECK_OFFER_SOLD_OUT' :
$report['errors'][] = "Проверка модератором: объект из объявления продан.";
break;
case 'CHECK_STOPWORD' :
$report['errors'][] = "В описании объявления или в имени автора используются нецензурные выражения или реклама.";
break;
case 'CHECK_UNAVAILABLE' :
$report['errors'][] = "До продавца невозможно дозвониться.";
break;
case 'CHECK_UNKNOWN_OBJECT' :
$report['errors'][] = "Контактное лицо, указанное в объявлении, не владеет информацией об объекте.";
break;
case 'CHECK_UNKNOWN_REASON' :
$report['errors'][] = "Объявление заблокировано по жалобе пользователя.";
break;
case 'CHECK_WRONG_ADDRESS' :
$report['errors'][] = "Проверка модератором: указан неверный адрес объекта.";
break;
case 'CHECK_WRONG_DATA' :
$report['errors'][] = "Проверка модератором: несоответствие параметров в объявлении.";
break;
case 'CHECK_WRONG_PHOTO' :
$report['errors'][] = "Объявление содержит фотографии низкого качества или фотографии, не относящиеся к объекту.";
break;
case 'CHECK_WRONG_PRICE' :
$report['errors'][] = "Проверка модератором: в объявлении указана неверная цена.";
break;
case 'CLONE' :
$report['errors'][] = "У вас уже есть такое объявление.";
break;
case 'COORDINATES_NOT_FOUND' :
$report['errors'][] = "Географические координаты объекта вычислены неправильно.";
break;
case 'COMMERCIAL_IN_LIVING' :
$report['errors'][] = "Тип объекта не соответствует разделу сервиса.";
break;
case 'COMPLAINT_FROM_OWNER' :
$report['errors'][] = "Информация о собственнике скрыта или объявление размещено без согласия собственника.";
break;
case 'CONTACT_IN_DESCRIPTION' :
$report['errors'][] = "Контакты в описании.";
break;
case 'CREATION_DATE_NOT_SET' :
$report['errors'][] = "Дата создания объявления не указана или указана в неподходящем формате.";
break;
case 'DAMAGED_PHOTO' :
$report['errors'][] = "В объявлении используются маленькие фотографии или фотографии низкого качества.";
break;
case 'HOTEL' :
$report['errors'][] = "Яндекс.Недвижимость не размещает объявления об аренде номеров в гостиницах и хостелах.";
break;
case 'HOUSE_IN_APARTMENT' :
$report['errors'][] = "Тип объекта не соответствует разделу сервиса.";
break;
case 'HOUSE_IN_LOT' :
$report['errors'][] = "Тип объекта не соответствует разделу сервиса.";
break;
case 'ILLEGAL_SELL_FOR_LEGAL_ADDRESS' :
$report['errors'][] = "В объявлении о продаже коммерческого объекта указана категория «legal address» (юридический адрес).";
break;
case 'INACTIVE_CAMPAIGN' :
$report['errors'][] = "Рекламная кампания неактивна.";
break;
case 'INTERNAL_ID_NOT_SET' :
$report['errors'][] = "Не указан идентификатор объявления.";
break;
case 'INVALID_COMMERCIAL_TYPES' :
$report['errors'][] = "Не указана категория коммерческого объекта.";
break;
case 'INVALID_COMMISSION' :
$report['errors'][] = "Неправильно указан размер комиссии.";
break;
case 'INVALID_ELECTRIC_CAPACITY' :
$report['errors'][] = "Неправильно указана выделенная электрическая мощность.";
break;
case 'INVALID_FULL_OPTION_SALE' :
$report['errors'][] = "Нельзя размещать переуступку на минимальном тарифе.";
break;
case 'INVALID_GARAGE_TYPE' :
$report['errors'][] = "Не указан тип гаража.";
break;
case 'INVALID_PALLET_PRICE' :
$report['errors'][] = "Неправильно указана стоимость палето-места.";
break;
case 'INVALID_PARKING_GUEST_PLACES' :
$report['errors'][] = "Неправильно указано количество гостевых парковочных мест.";
break;
case 'INVALID_PARKING_PLACE_PRICE' :
$report['errors'][] = "Неправильно указана стоимость парковочного места.";
break;
case 'INVALID_PARKING_PLACES' :
$report['errors'][] = "Неправильно указано количество предоставляемых парковочных мест.";
break;
case 'INVALID_PHONE_LINES' :
$report['errors'][] = "Неправильно указано количество телефонных линий.";
break;
case 'INVALID_PRICE' :
$report['errors'][] = "Недостоверная цена.";
break;
case 'INVALID_PRIMARY_SALE' :
$report['errors'][] = "Объявления «от застройщика» могут быть размещены только авторизованными партнерами.";
break;
case 'INVALID_SECURITY_PAYMENT' :
$report['errors'][] = "Неправильно указан размер обеспечительного платежа.";
break;
case 'INVALID_USE_OF_OPEN_PLAN' :
$report['errors'][] = "Значение «свободная планировка» используется только для объявлений о продаже квартир и коммерческой недвижимости.";
break;
case 'INVALID_USE_OF_STUDIO' :
$report['errors'][] = "Значение «студия» используется только для объявлений о продаже квартир.";
break;
case 'LIVING_SPACE_IS_TOO_HIGH' :
$report['errors'][] = "Неправильно указана жилая площадь.";
break;
case 'LOCATION_NOT_FOUND' :
$report['errors'][] = "Неизвестно местоположение объекта.";
break;
case 'LOT_AREA_NOT_SET' :
$report['errors'][] = "Не указана площадь участка.";
break;
case 'LOT_HAS_AREA_AND_LOT_AREA' :
$report['errors'][] = "В объявлении о продаже участка без дома площадь участка передана в теге area.";
break;
case 'LOT_RENT' :
$report['errors'][] = "Яндекс.Недвижимость не размещает объявления об аренде участков.";
break;
case 'LOW_ACTUALITY' :
$report['errors'][] = "Объявление не соответствуют требованиям Яндекс.Недвижимости.";
break;
case 'NEW_IN_OLD' :
$report['errors'][] = "Тип объекта не соответствует разделу сервиса.";
break;
case 'NO_IMAGES' :
$report['errors'][] = "Отсутствуют фотографии объекта.";
break;
case 'NO_INFO' :
$report['errors'][] = "Объект закрыт для просмотра или не существует.";
break;
case 'NO_PLACEMENT' :
$report['errors'][] = "Необходимо оплатить размещение объявлений.";
break;
case 'NO_PLAN_PHOTO' :
$report['errors'][] = "В объявлении о продаже квартиры в новостройке нет изображения планировки.";
break;
case 'NO_ROOMS_IN_APARTMENT' :
$report['errors'][] = "Не указано количество комнат в квартире.";
break;
case 'NO_ROOMS_OFFERED_FOR_ROOMS' :
$report['errors'][] = "В объявлении о продаже или аренде комнат не указано количество комнат, участвующих в сделке, и общее количество комнат.";
break;
case 'NO_SHOW' :
$report['errors'][] = "Объект закрыт для просмотра.";
break;
case 'NOT_REALTY' :
$report['errors'][] = "Объявление содержит информацию о продаже товаров или услуг.";
break;
case 'OFFER_TOO_OLD' :
$report['errors'][] = "Слишком старое объявление.";
break;
case 'OLD_PHOTO' :
$report['errors'][] = "В объявлении используются старые фотографии.";
break;
case 'PARTIALLY_ADDRESS' :
$report['errors'][] = "Неполный адрес или неточная метка на карте.";
break;
case 'PEOPLE_ON_PHOTO' :
$report['errors'][] = "На снимках есть люди или посторонние предметы.";
break;
case 'PHONE_NOT_EXIST' :
$report['errors'][] = "Указан неверный или недействительный телефон.";
break;
case 'PHONE_UNAVAILABLE' :
$report['errors'][] = "Указан неверный или недействительный телефон.";
break;
case 'PHOTO_STEAL' :
$report['errors'][] = "Недостоверные или чужие фотографии.";
break;
case 'REGISTRATION' :
$report['errors'][] = "Объявление содержит информацию об услугах.";
break;
case 'RENT_IN_SELL' :
$report['errors'][] = "Тип сделки не соответствует разделу сервиса.";
break;
case 'PRICE_ERROR' :
$report['errors'][] = "Недостоверная цена.";
break;
case 'PRICE_NOT_SET' :
$report['errors'][] = "Не указана цена объекта.";
break;
case 'PRICE_PERIOD_NOT_SET_FOR_RENT' :
$report['errors'][] = "Срок аренды указан в неподходящем формате.";
break;
case 'PRICE_PERIOD_SET_FOR_SELL' :
$report['errors'][] = "В объявлении о продаже объекта указан период для расчета стоимости аренды.";
break;
case 'PRICE_PERIOD_UNKNOWN' :
$report['errors'][] = "Неправильно указан период для расчета стоимости аренды.";
break;
case 'PRICE_UNIT_UNKNOWN' :
$report['errors'][] = "Неизвестная единица измерения площади.";
break;
case 'ROOM_IN_APARTMENT' :
$report['errors'][] = "Тип объекта не соответствует разделу сервиса.";
break;
case 'ROOMS_OFFERED_GREATER_OR_EQUAL_THAN_ROOMS' :
$report['errors'][] = "Количество комнат в квартире, предлагаемых для аренды или покупки, превышает общее количество комнат в квартире.";
break;
case 'ROOMS_SPACE_NOT_MATCH_ROOMS_COUNT' :
$report['errors'][] = "Количество переданных значений площади комнат не соответствует количеству комнат.";
break;
case 'SERVICE_SUGGEST' :
$report['errors'][] = "В объявлении предлагаются услуги или другие объекты.";
break;
case 'SITE_OFFER_BASE_FIELD_NOT_SET' :
$report['errors'][] = "Отсутствуют поля, обязательные для новостроек.";
break;
case 'STRANGE_DISTANCE_FOR_MANUAL_POINT' :
$report['errors'][] = "Указанные координаты не соответствуют действительности.";
break;
case 'SUSPICIOUS_OFFER_AGE' :
$report['errors'][] = "Объявление не соответствует требованиям к срокам размещения.";
break;
case 'TEXT_IN_PHOTO' :
$report['errors'][] = "В объявлении используются фотографии, на которых есть посторонние изображения.";
break;
case 'TOO_BIG_LOT_AREA' :
$report['errors'][] = "Объекты площадью более 1 гектара считаются участками коммерческого назначения.";
break;
case 'UNKNOWN_CATEGORY' :
$report['errors'][] = "Неправильно указаны категория объекта или тип продавца (арендодателя).";
break;
case 'UNKNOWN_LOCATION_TYPE' :
$report['errors'][] = "Недостаточно информации для определения точного местоположения объекта.";
break;
case 'UNKNOWN_NEWBUILDING' :
$report['errors'][] = "Объявление об объекте в неизвестной новостройке.";
break;
case 'UNKNOWN_TYPE' :
$report['errors'][] = "Неправильно указан тип сделки.";
break;
case 'URL_NOT_SET' :
$report['errors'][] = "Не указана ссылка на объявление.";
break;
case 'VILLAGE_NON_TARGET_SALE' :
$report['errors'][] = "В этом посёлке нельзя размещать вторичку.";
break;
case 'WRONG_AREA' :
$report['errors'][] = "Неверно указана площадь объекта.";
break;
case 'WRONG_CADASTRAL' :
$report['errors'][] = "Неверный или недействительный кадастровый номер.";
break;
case 'WRONG_FLOOR' :
$report['errors'][] = "Неверно указан этаж или количество этажей в здании.";
break;
case 'WRONG_LOT_AREA' :
$report['errors'][] = "Неверно указана площадь участка.";
break;
case 'WRONG_NAME' :
$report['errors'][] = "Имя продавца указано некорректно.";
break;
case 'WRONG_PIN' :
$report['errors'][] = "Неполный адрес или неточная метка на карте.";
break;
case 'WRONG_PRICE_PERIOD' :
$report['errors'][] = "Цена не соответствует периоду аренды.";
break;
case 'WRONG_ROOMS' :
$report['errors'][] = "Неверно указано число комнат.";
break;
}
}
}
if (isset($offer['url']))
$report['url'] = $offer['url'];
else
$report['url'] = null;
$results3 = json_decode($response, true);
if (isset($results3['stats']['daily'])) {
foreach ($results3['stats']['daily'] as $stats) {
$report['views'] += intval($stats['cardShows']);
$report['contacts'] += intval($stats['phoneShows']);
$report['favorites'] = null;
$report['calls'] += intval($stats['calls']);
}
} else {
$this->logs[] = "Ошибка разбора ответа от API Яндекс.Недвижимость.";
}
$ad_id = $offer['internalId'];
$reports[$ad_id] = $report;
// Запись в сфинкс флага об ошибке размещения
try {
if (!is_null($this->_db_sphinx)) {
if (count($reports[$ad_id]['errors']) > 0)
$this->_db_sphinx->query("UPDATE objects SET ads_error = 1 WHERE id = $ad_id");
else
$this->_db_sphinx->query("UPDATE objects SET ads_error = 0 WHERE id = $ad_id");
}
} catch (\Exception $exception) {
$this->errors[] = $exception;
}
if (!is_null($object_id) && $object_id == $ad_id) {
$output = $reports[$ad_id];
}
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
}
}
} else {
$this->logs[] = "Ошибка разбора ответа от API Яндекс.Недвижимость.";
}
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
} else {
$this->logs[] = "Не найден принятый и обработанный фид в Яндекс.Недвижимость.";
}
} else {
$this->logs[] = "Ошибка разбора ответа от API Яндекс.Недвижимость.";
}
}
break;
case 'domclick' :
$url = "https://my.domclick.ru/api/v1/company/$client_id/report";
$options = [
'auth' => 'token',
'token' => $this->_getAuthToken('domclick', $client_id, $secret_key),
'method' => 'get',
'type' => 'xml',
];
if ($response = $this->_request($url, $options))
$this->logs[] = "Успешное обращение к серверу API Домклик.";
else
$this->logs[] = "Произошла ошибка обращения к серверу API Домклик.";
if ($this->debug)
$this->logs["https://my.domclick.ru/api/v1/company/$client_id/report"] = $response;
$results = null;
try {
$xml = simplexml_load_string($response, null, LIBXML_NOCDATA);
$results = json_decode(json_encode((array)$xml), true);
$results = array($xml->getName() => $results);
} catch (\Exception $exception) {
$this->logs[] = $exception;
}
if (is_array($results)) {
if ($results['Report']['OfferList']['Offer']) {
foreach ($results['Report']['OfferList']['Offer'] as $offer) {
if ($offer['@attributes']['source'] == 'feed' && isset($offer['ExternalId'])) {
$report = [];
$ad_id = null;
$ads_url = $offer['Publication']['DomclickURL'];
$report['url'] = $ads_url;
$report['success'] = (!empty($ads_url)) ? true : false;
if (preg_match("/\_\_(\d+)+$/", $ads_url, $matches)) {
$ad_id = $matches[1];
if (!is_null($ad_id)) {
$report['views'] += intval($offer['Publication']['ViewsCount']);
$report['contacts'] = null;
$report['favorites'] = null;
$report['calls'] += intval($offer['Publication']['CallsCount']);
}
}
$ad_id = $offer['ExternalId'];
$reports[$ad_id] = $report;
// Запись в сфинкс флага об ошибке размещения
try {
if (!is_null($this->_db_sphinx)) {
if (count($reports[$ad_id]['errors']) > 0)
$this->_db_sphinx->query("UPDATE objects SET ads_error = 1 WHERE id = $ad_id");
else
$this->_db_sphinx->query("UPDATE objects SET ads_error = 0 WHERE id = $ad_id");
}
} catch (\Exception $exception) {
$this->errors[] = $exception;
}
if (!is_null($object_id) && $object_id == $ad_id) {
$output = $reports[$ad_id];
}
}
}
}
}
break;
}
$this->logs['save_report_status'] = $this->saveReports($service_id, $agency_id, $reports, $is_manual);
if (!$is_manual)
echo "<pre> Отчёт о сохранении статистики: " . var_export($this->logs['save_report_status'], true) ."</pre>";
if ($offset) {
return $this->getStats($service_id, $period, $client_id, $secret_key, $ext_user_id, $object_id, $is_manual, $agency_id, $offset);
} else {
if (!is_null($object_id)) {
if (!$is_manual)
echo "<pre> Результат выборки статистики: " . var_export($output, true) ."</pre>";
return $output;
} else {
if (!$is_manual)
echo "<pre> Результат выборки статистики: " . var_export($reports, true) ."</pre>";
return $reports;
}
}
}
public function getReports($service_id = null, $agency_id = null, $object_id = null) {
$processed_at = date('Y-m-d H:i:s', strtotime('-1 hours'));
$sql = "SELECT * FROM `ads_stats`
WHERE `object_id` = '$object_id' AND
`agency_id` = '$agency_id'";
if (!is_null($service_id)) {
$sql .= " AND `service_id` = '$service_id' LIMIT 1";
}
$sql .= " ORDER BY `processed_at` DESC";
if ($query = mysql_query($sql)) {
if (mysql_num_rows($query) > 0) {
$reports = [];
while ($row = mysql_fetch_assoc($query)) {
$service_id = intval($row['service_id']);
if ($serviceName = $this->getServiceName($service_id)) {
$report = [
'views' => (!is_null($row['views'])) ? intval($row['views']) : '-',
'contacts' => (!is_null($row['contacts'])) ? intval($row['contacts']) : '-',
'favorites' => (!is_null($row['favorites'])) ? intval($row['favorites']) : '-',
'calls' => (!is_null($row['calls'])) ? intval($row['calls']) : '-',
'url' => strval($row['url']),
'errors' => array_unique(json_decode($row['errors'])),
];
if (!isset($reports[$serviceName]))
$reports[$serviceName] = $report;
else
continue;
}
}
return $reports;
}
}
return null;
}
public function saveReports($service_id = null, $agency_id = null, $reports = [], $is_manual = false) {
if (is_null($service_id) || $service_id == 0)
return false;
if (is_null($agency_id) || $agency_id == 0)
return false;
if (count($reports) > 0) {
$is_manual = ($is_manual) ? '1' : '0';
$processed_at = date('Y-m-d H:i:s');
$sql = "DELETE FROM `ads_stats` WHERE `service_id` = '$service_id' AND (`agency_id` = '$agency_id' OR `agency_id` = 0)";
$sql2 = "INSERT INTO `ads_stats` (
`object_id`,
`service_id`,
`views`,
`contacts`,
`favorites`,
`calls`,
`url`,
`errors`,
`is_error`,
`is_manual`,
`agency_id`,
`status`,
`processed_at`
) VALUES ";
$ids = [];
$values = [];
foreach ($reports as $object_id => $report) {
$errors = json_encode($report['errors'], JSON_UNESCAPED_UNICODE);
if ($errors == "[]" || $errors == "null")
$errors = null;
$views = 'NULL';
if (!is_null($report['views']))
$views = $report['views'];
$contacts = 'NULL';
if (!is_null($report['contacts']))
$contacts = $report['contacts'];
$favorites = 'NULL';
if (!is_null($report['favorites']))
$favorites = $report['favorites'];
$calls = 'NULL';
if (!is_null($report['calls']))
$calls = $report['calls'];
$url = 'NULL';
if (!is_null($report['url']))
$url = "'$report[url]'";
if (is_null($errors))
$errors = 'NULL';
else
$errors = "'".addslashes($errors)."'";
$is_error = (count($report['errors']) > 0) ? '1' : '0';
$status = ($report['success']) ? '1' : '0';
$values[] = "(
'$object_id',
'$service_id',
$views,
$contacts,
$favorites,
$calls,
$url,
$errors,
'$is_error',
'$is_manual',
'$agency_id',
'$status',
'$processed_at'
)";
$ids[] = $object_id;
}
$sql .= " AND `object_id` IN (" . implode(', ', $ids) . ")";
$sql2 .= implode(', ', $values);
if (((count($ids) > 0) ? mysql_query($sql) : true) && mysql_query($sql2))
return ['success' => true, 'query' => [
'sql' => ((count($ids) > 0) ? $sql : null),
'sql2' => $sql2,
],
'object_ids' => $ids,
'processed' => count($ids)
];
else
return ['success' => false, 'query' => [
'sql' => ((count($ids) > 0) ? $sql : null),
'sql2' => $sql2,
],
'object_ids' => $ids,
'processed' => count($ids),
'errors' => mysql_error()
];
}
return false;
}
public function getApiSettings($agency_id = null, $only_active = true) {
$settings = [];
if (is_null($agency_id))
$agency_id = User::getUserAgencyID();
$sql = "SELECT * FROM `users_api` AS `api` WHERE `api`.`agency_id` = '$agency_id'";
if ($only_active)
$sql .= " AND `status` > 0";
if ($query = mysql_query($sql)) {
if (mysql_num_rows($query) > 0) {
while ($row = mysql_fetch_assoc($query)) {
$service_id = $row['service_id'];
if ($serviceName = $this->getServiceName($service_id)) {
$settings[$serviceName] = [
'service_id' => $row['service_id'],
'client_id' => $row['client_id'],
'secret_key' => $row['secret_key'],
'ext_user_id' => $row['ext_user_id'],
];
}
}
}
}
return $settings;
}
public function testAdvertApi($service = null, $client_id = null, $secret_key = null, $ext_user_id = null) {
if (empty($service))
$service = null;
if (empty($client_id))
$client_id = null;
if (empty($secret_key))
$secret_key = null;
if (empty($ext_user_id))
$ext_user_id = null;
$this->errors = [];
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
$result = false;
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return ['success' => $result, 'errors' => $this->errors];
$this->_session_key .= "_test";
switch (strtolower($service)) {
case 'avito' :
$url = "https://api.avito.ru/token/?grant_type=client_credentials&client_id=$client_id&client_secret=$secret_key";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'post',
'type' => 'json'
];
$result = $this->_request($url, $options, true);
if ($this->debug)
$this->logs["https://api.avito.ru/token/?grant_type=client_credentials&client_id=$client_id&client_secret=$secret_key"] = $result;
break;
case 'cian' :
$url = "https://public-api.cian.ru/v1/get-last-order-info";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json'
];
$result = $this->_request($url, $options, true);
if ($this->debug)
$this->logs["https://public-api.cian.ru/v1/get-last-order-info"] = $result;
break;
case 'yandex' :
$url = "https://api.realty.yandex.net/2.0/crm/offers";
$options = [
'auth' => 'oauth',
'token' => $this->_getAuthToken('yandex', null, $secret_key),
'method' => 'get',
'type' => 'json',
'headers' => [
'X-Authorization: Vertis crm-dff153a8ef1a90d3bff5ee378dee416606cf8915'
],
];
$result = $this->_request($url, $options, true);
if ($this->debug)
$this->logs["https://api.realty.yandex.net/2.0/crm/offers"] = $result;
break;
case 'domclick' :
$token = $this->_getAuthToken('domclick', $client_id, $secret_key);
$url = "https://public-api.domclick.ru/stats/v1/companies/$client_id/offers?token=$token&limit=10";
$options = [
'method' => 'get',
'type' => 'json',
];
$result = $this->_request($url, $options, true);
if ($this->debug)
$this->logs["https://my.domclick.ru/api/v1/company/$client_id/report"] = $result;
break;
}
return $result;
}
private function _getAgencies() {
$ids = [];
$sql = "SELECT *
FROM `users`
WHERE (now() <= DATE_ADD(
`date_tarif`, INTERVAL (
SELECT `t`.`period`
FROM `tariffs` `t`
WHERE t.id = `id_tarif`
LIMIT 1
) DAY)
) AND
`blocked` = 0";
$results = mysql_query($sql);
while($agency = mysql_fetch_assoc($results)) {
$ids[] = $agency['id'];
}
return array_unique($ids);
}
public function run($service = null, $agency_id = null) {
if (is_null($service))
throw new Exception("Service must be set.");
if (is_numeric($service) && !is_null($this->getServiceName($service)))
$service = $this->getServiceName($service);
if (!is_null($agency_id))
$agencies = [$agency_id];
else
$agencies = $this->_getAgencies();
if (!is_null($service) && count($agencies)) {
foreach ($agencies as $agency_id) {
$settings = $this->getApiSettings($agency_id, true);
if (isset($settings[$service])) {
if ($_GET['dev'])
var_export($settings[$service]);
$period = [
'date_from' => date('Y-m-d', strtotime("-6 month")),
'date_to' => date('Y-m-d'),
];
if ($service == 'yandex') {
$period['date_from'] = date('Y-m-d', strtotime('-119 days'));
} else if ($service == 'cian') {
$period['date_from'] = date('Y-m-d', strtotime('-179 days'));
} else if ($service == 'avito') {
$period['date_from'] = date('Y-m-d', strtotime('-269 days'));
}
if ($_GET['dev'])
var_export($period);
$service_id = $settings[$service]['service_id'];
$client_id = $settings[$service]['client_id'];
$secret_key = $settings[$service]['secret_key'];
$ext_user_id = $settings[$service]['ext_user_id'];
$this->getStats($service_id, $period, $client_id, $secret_key, $ext_user_id, null, false, $agency_id);
}
}
}
}
public function set_api_id($api_id){
$this->_api_id = $api_id;
}
public function on_message($service = null, $client_id = null, $secret_key = null, $ext_user_id = null, $api_id) {
if($api_id > 0){
$this->set_api_id($api_id);
}
if (empty($service))
$service = null;
if (empty($client_id))
$client_id = null;
if (empty($secret_key))
$secret_key = null;
if (empty($ext_user_id))
$ext_user_id = null;
$this->errors = [];
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
$result = false;
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return ['success' => $result, 'errors' => $this->errors];
// $this->_session_key .= "_test";
switch (strtolower($service)) {
case 'avito' :
$url = "https://api.avito.ru/messenger/v3/webhook";
$url_webhook = 'https://joywork.ru/webhooks/avito_mess.php?api='.$api_id;
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'post',
'type' => 'json',
'data' => [
'url' => $url_webhook,
"version" => "3"
],
];
//var_dump($options);
$result = json_decode($this->_request($url, $options),true);
if($result['ok']){
$result['success'] = true;
if(!empty($this->_agency_id)){
$sql = "UPDATE `users_api` SET `is_messages` = '1' WHERE agency_id={$this->_agency_id} AND service_id = 1";
$this->_db->query($sql);
//$this->add_users_service($service, $client_id, $secret_key, $ext_user_id);
}
} else {
return ['success' => false, 'errors' => $result['result']['message']];
}
if ($this->debug)
$this->logs["https://api.avito.ru/messenger/v3/webhook"] = $result;
break;
case 'cian' :
if(!empty($this->_agency_id)){
$url_webhook = 'https://joywork.ru/webhooks/cian/'.$this->_agency_id.'/cian_mess.php';
if(!file_exists($_SERVER['DOCUMENT_ROOT']."/webhooks/cian/".$this->_agency_id."/cian_mess.php")){
if (!is_dir($_SERVER['DOCUMENT_ROOT'] . "/webhooks/cian")) {
mkdir($_SERVER['DOCUMENT_ROOT'] . "/webhooks/cian");
}
if (!is_dir($_SERVER['DOCUMENT_ROOT'] . "/webhooks/cian/".$this->_agency_id)) {
mkdir($_SERVER['DOCUMENT_ROOT'] . "/webhooks/cian/".$this->_agency_id);
}
copy($_SERVER['DOCUMENT_ROOT'] ."/webhooks/cian_mess.php", $_SERVER['DOCUMENT_ROOT'] ."/webhooks/cian/".$this->_agency_id."/cian_mess.php");
}
$url = "https://public-api.cian.ru/v2/subscribe-webhooks";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json',
'data' => [
'webhookTypes' => ["offersMessagesIncoming", "offersMessagesApiOutgoing", "offersMessagesLkOutgoing"],
'url' => $url_webhook,
],
];
$result = json_decode($this->_request($url, $options),true);
//var_dump($result);
if(isset($result['result']['errors'])){
return ['success' => false, 'errors' => $result['result']['message']];
} else {
$result['success'] = true;
if(!empty($this->_agency_id)){
$sql = "UPDATE `users_api` SET `is_messages` = '1' WHERE agency_id={$this->_agency_id} AND service_id = 2";
$this->_db->query($sql);
}
}
if ($this->debug)
$this->logs["https://public-api.cian.ru/v2/subscribe-webhooks"] = $result;
}
break;
}
// $result['logs'] = $this->logs;
return $result;
}
public function off_message($service = null, $client_id = null, $secret_key = null, $ext_user_id = null, $api_id) {
if($api_id > 0){
$this->set_api_id($api_id);
}
if (empty($service))
$service = null;
if (empty($client_id))
$client_id = null;
if (empty($secret_key))
$secret_key = null;
if (empty($ext_user_id))
$ext_user_id = null;
$this->errors = [];
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
$result = false;
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return ['success' => $result, 'errors' => $this->errors];
// $this->_session_key .= "_test";
switch (strtolower($service)) {
case 'avito' :
$url = "https://api.avito.ru/messenger/v1/webhook/unsubscribe";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'post',
'type' => 'json',
'data' => [
'url' => 'https://joywork.ru/webhooks/avito_mess.php?api='.$api_id,
"version" => "3"
],
];
$result = json_decode($this->_request($url, $options),true);
if($result['ok']){
$result['success'] = true;
if(!empty($this->_agency_id)){
$sql = "UPDATE `users_api` SET `is_messages` = '0' WHERE agency_id={$this->_agency_id} AND service_id = 1";
$this->_db->query($sql);
//$this->add_users_service($service, $client_id, $secret_key, $ext_user_id);
}
} else {
return ['success' => false, 'errors' => $result['result']['message']];
}
if ($this->debug)
$this->logs["https://api.avito.ru/messenger/v1/webhook/unsubscribe"] = $result;
break;
case 'cian' :
if(!empty($this->_agency_id)){
$url_webhook = 'https://joywork.ru/webhooks/cian/'.$this->_agency_id.'/cian_mess.php';
$url = "https://public-api.cian.ru/v2/unsubscribe-webhooks";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json',
'data' => [
'url' => $url_webhook,
'webhookTypes' => ['offersMessages', 'systemMessages' ]
],
];
$result = json_decode($this->_request($url, $options),true);
if(isset($result['result']['errors'])){
return ['success' => false, 'errors' => $result['result']['message']];
} else {
$result['success'] = true;
$sql = "UPDATE `users_api` SET `is_messages` = '0' WHERE agency_id={$this->_agency_id} AND service_id = 2";
$this->_db->query($sql);
//$this->add_users_service($service, $client_id, $secret_key, $ext_user_id);
}
if ($this->debug)
$this->logs["https://public-api.cian.ru/v2/unsubscribe-webhooks"] = $result;
}
break;
}
// $result['logs'] = $this->logs;
return $result;
}
public function send_message($service = null, $client_id = null, $secret_key = null, $ext_user_id = null, $text, $chatId) {
if (empty($service))
$service = null;
if (empty($client_id))
$client_id = null;
if (empty($secret_key))
$secret_key = null;
if (empty($ext_user_id)){
$ext_user_id = null;
} else {
$ext_user_id = trim(str_replace(' ','',$ext_user_id));
}
$this->errors = [];
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
$result = false;
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return ['success' => $result, 'errors' => $this->errors];
// $this->_session_key .= "_test";
switch (strtolower($service)) {
case 'avito' :
$url = "https://api.avito.ru/messenger/v1/accounts/{$ext_user_id}/chats/{$chatId}/messages";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'post',
'type' => 'json',
'data' => [
"message"=> [
"text"=> $text,
],
"type"=> "text"
],
];
//var_dump($options);
$result = json_decode($this->_request($url, $options),true);
if(isset($result['created'])){
$result['created_at'] = date('d.m.Y H:i', $result['created']);
}
//var_dump($result);
if ($this->debug)
$this->logs["https://api.avito.ru/messenger/v1/accounts/{$ext_user_id}/chats/{$chatId}/messages"] = $result;
break;
case 'cian' :
$url = "https://public-api.cian.ru/v1/send-message";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json',
'data' => [
'chatId' => $chatId,
'content' => [
'text' => $text
],
],
];
// var_dump($options);
$result = json_decode($this->_request($url, $options), true);
//var_dump($result);
if(isset($result['result']['errors'])){
return ['success' => false, 'errors' => $result['result']['message']];
} else {
$result['success'] = true;
$result['created_at'] = date('d.m.Y H:i');
}
if ($this->debug)
$this->logs["https://public-api.cian.ru/v1/send-message"] = $result;
break;
}
// $result['logs'] = $this->logs;
return $result;
}
public function get_agent($service = null, $client_id = null, $secret_key = null, $ext_user_id = null, $agent_id) {
if (empty($service))
$service = null;
if (empty($client_id))
$client_id = null;
if (empty($secret_key))
$secret_key = null;
if (empty($ext_user_id)){
$ext_user_id = null;
} else {
$ext_user_id = trim(str_replace(' ','',$ext_user_id));
}
$this->errors = [];
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
$result = false;
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return ['success' => $result, 'errors' => $this->errors];
// $this->_session_key .= "_test";
switch (strtolower($service)) {
case 'cian' :
$url = "https://public-api.cian.ru/v1/get-agents?page=0&pageSize=1&userIds=".$agent_id;
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('cian', null, $secret_key),
'type' => 'json'
];
// var_dump($options);
$result = json_decode($this->_request($url, $options), true);
//var_dump($result);
if(isset($result['result']['errors'])){
return ['success' => false, 'errors' => $result['result']['message']];
} else {
$result['success'] = true;
}
if ($this->debug)
$this->logs["https://public-api.cian.ru/v1/get-agents?page=0&pageSize=1&userIds=".$agent_id] = $result;
break;
}
// $result['logs'] = $this->logs;
return $result;
}
public function get_chat($api, $chat_id){
if(empty($chat_id)){
return ['success' => false, 'errors' => "Пустой чат id"];
}
if($api['id'] > 0){
$this->set_api_id($api['id']);
}
$client_id = trim($api['client_id']);
$secret_key = trim($api['secret_key']);
$ext_user_id = trim(str_replace(' ','',$api['ext_user_id']));
if(!empty($api['token'])){
$this->_tokens['avito'] = array('expires'=>$api['expires_in'], 'token' => $api['token']);
}
$service = 'avito';
if (empty($client_id))
$client_id = null;
if (empty($secret_key))
$secret_key = null;
if (empty($ext_user_id))
$ext_user_id = null;
$this->errors = [];
if (is_null($service))
$this->errors[] = 'Не указана площадка для получения статистики';
if (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick'))
$this->errors[] = 'Не указан `client_id` для получения статистики';
if (is_null($secret_key))
$this->errors[] = 'Не указан `secret_key` для получения статистики';
if (is_null($ext_user_id) && strtolower($service) == 'avito')
$this->errors[] = 'Не указан `ext_user_id` обязательный для API Avito';
$result = false;
if (is_null($service) || (is_null($client_id) && (strtolower($service) == 'avito' || strtolower($service) == 'domclick')) || is_null($secret_key))
return ['success' => $result, 'errors' => $this->errors];
$url = "https://api.avito.ru/messenger/v2/accounts/{$ext_user_id}/chats/{$chat_id}";
$options = [
'auth' => 'bearer',
'token' => $this->_getAuthToken('avito', $client_id, $secret_key),
'method' => 'get',
'type' => 'json',
];
$result = json_decode($this->_request($url, $options),true);
$result['success'] = true;
return $result;
}
}
?>