Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gh 6 #8

Merged
merged 47 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e815be8
feat: reindex shop orders with new uuid
DEMAxx May 31, 2024
0197bf1
fix: changes in request to core api
DEMAxx May 31, 2024
1832c8e
fix: response check success answer
DEMAxx May 31, 2024
5e5102b
fix: remove not used method
DEMAxx May 31, 2024
9f3c078
fix: site name key change
DEMAxx May 31, 2024
02c3ff5
fix: exchange token to shop token was changed, get shop uuid inside f…
DEMAxx May 31, 2024
aeae10d
fix: cache token in file and get from cache
DEMAxx May 31, 2024
e42e719
fix: get and create api tasks
DEMAxx Jun 3, 2024
c40b6aa
fix: start task as schedule work
DEMAxx Jun 3, 2024
335aa4f
fix: rewrite cache, start events, tasks
DEMAxx Jun 3, 2024
353bb23
fix: task hook add prefix
DEMAxx Jun 3, 2024
de2422d
fix: small fix
DEMAxx Jun 3, 2024
b9d0a7c
feat: unregister events, rewrite api send, additional headers, rewrit…
DEMAxx Jun 4, 2024
df69551
fix: unregister events
DEMAxx Jun 4, 2024
2934250
fix: after review fixes
DEMAxx Jun 5, 2024
e259701
fix: test and fix work of core api
DEMAxx Jun 5, 2024
c75dba7
fix: rewrite classes for optimal work with core api
DEMAxx Jun 6, 2024
baecdb7
fix: remove check event on activate hook
DEMAxx Jun 6, 2024
2c87638
fix: change headers fixed
DEMAxx Jun 6, 2024
f497c68
feat: work with statuses
DEMAxx Jun 6, 2024
2383a4c
fix: remove cache, unschedule events with deactivation plugin, fix ac…
DEMAxx Jun 7, 2024
ff4d149
fix: change send headers logic
DEMAxx Jun 7, 2024
9ff066b
fix: postpone task for server fatal errors answer
DEMAxx Jun 7, 2024
5f6b0b7
feat: change exception to rest for schedule events
DEMAxx Jun 10, 2024
18df8e4
fix: methods witch work with update uuids from core api
DEMAxx Jun 10, 2024
ebb2f81
fix: reschedule task manager event if case api core error
DEMAxx Jun 10, 2024
4a64f54
fix: code style
DEMAxx Jun 10, 2024
7f2fa93
fix: fix after review
DEMAxx Jun 11, 2024
9c82b7a
fix: getPath method doc
DEMAxx Jun 11, 2024
5b6f655
fix: replace work with response logic to transport class
DEMAxx Jun 11, 2024
f5f8fe1
fix: server errors check
DEMAxx Jun 11, 2024
9fbd564
fix: server errors check + rename schedule exceptions
DEMAxx Jun 11, 2024
f781f45
fix: check DOING_CRON const in API exception
DEMAxx Jun 11, 2024
7dbcab4
fix: cache class work with only one file
DEMAxx Jun 11, 2024
4e33774
fix: add core request data as dto model
DEMAxx Jun 11, 2024
7dc1fa4
fix: remove headers data and fix status detect
DEMAxx Jun 11, 2024
e24d810
fix: remove rename task output data, remove Task Contract unnecessary…
DEMAxx Jun 13, 2024
4bf4e3c
fix: remove error collection
DEMAxx Jun 13, 2024
5f82a15
fix: task manager no more extends from Task Contract, type hints, met…
DEMAxx Jun 14, 2024
edf08a5
fix: response only array + error catch as exception
DEMAxx Jun 14, 2024
ce9259b
fix: type and methods doc
DEMAxx Jun 14, 2024
b7b5262
fix: type hint
DEMAxx Jun 14, 2024
3a704da
fix: fixes after review
DEMAxx Jun 17, 2024
ea2400f
fix: exceptions fixed
DEMAxx Jun 17, 2024
ae7b17b
fix: exception add $stopPropagation
DEMAxx Jun 17, 2024
ed84ca0
fix: global view to constants classes
DEMAxx Jun 17, 2024
afc65ca
fix: view mode to constants
DEMAxx Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/Actions/Schedule/CollectOrders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

vermorag marked this conversation as resolved.
Show resolved Hide resolved
namespace Cdek\Actions\Schedule;

use Cdek\Cache\FileCache;
use Cdek\CdekCoreApi;
use Cdek\Contracts\TaskContract;
use Cdek\Model\CoreApiHeadersData;
use Cdek\Model\Validate;

class CollectOrders extends TaskContract
{
const ORDERS_LIMIT = 10000;
private Validate $error;

public static function getName(): string
{
return 'collect-orphaned-orders';
}

public function start()
{
$query = new \WC_Order_Query(
[
'orderby' => 'id',
'order' => 'ASC',
'paginate' => true,
'limit' => self::ORDERS_LIMIT,
'return' => 'ids',
],
);

for ($page = 1, $maxPages = 1; $page <= $maxPages; $page++) {
$query->set('page', $page);
$result = $query->get_orders();

$maxPages = $result->max_num_pages;

$response = $this->cdekCoreApi->sendTaskData(
$this->taskId,
[
'status' => 'success',
'result' => [
'orders' => array_map(
static fn($order) => (string)$order,
$result->orders,
),
],
],
(new CoreApiHeadersData())
->setCurrentPage($page)
->setTotalPages($maxPages)
);

$this->initData($response);
}
}
}
57 changes: 57 additions & 0 deletions src/Actions/Schedule/ReindexOrders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php


namespace {

defined('ABSPATH') or exit;
}

namespace Cdek\Actions\Schedule {

use Cdek\Contracts\TaskContract;
use Cdek\Exceptions\CdekCoreApiException;
use Cdek\Model\OrderMetaData;
use Cdek\Model\Validate;

class ReindexOrders extends TaskContract
{
private Validate $error;

public function __construct(string $taskId)
{
parent::__construct($taskId);
$this->initTaskData();
}

public static function getName(): string
{
return 'restore-order-uuids';
}

public function start()
vermorag marked this conversation as resolved.
Show resolved Hide resolved
{
if (empty($this->getTaskMeta())) {
throw new CdekCoreApiException('[CDEKDelivery] Failed to get orders meta info',
'cdek_error.core.data',
$this->getTaskData(),
true);
}

foreach ($this->getTaskMeta() as $arOrder) {
OrderMetaData::updateMetaByOrderId(
$arOrder['external_id'],
[
'order_uuid' => $arOrder['id']
]
);
}

$this->initData($this->cdekCoreApi->sendTaskData(
$this->taskId,
[
'status' => 'success'
]
));
}
}
}
63 changes: 63 additions & 0 deletions src/Cache/FileCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

vermorag marked this conversation as resolved.
Show resolved Hide resolved
namespace Cdek\Cache;

use Cdek\Exceptions\CdekApiException;
use Cdek\Loader;

class FileCache
{
const CACHE_FILE_NAME = '.cache.php';
private static array $store;
private string $file;

public function __construct($fileName = self::CACHE_FILE_NAME)
vermorag marked this conversation as resolved.
Show resolved Hide resolved
{
$this->file = $fileName;
}

public function getVars()
{
if(!file_exists(Loader::getPluginPath() . DIRECTORY_SEPARATOR . $this->file)){
return null;
}

return self::$store[$this->file] ?? self::$store[$this->file] = require_once(Loader::getPluginPath() . DIRECTORY_SEPARATOR . $this->file);
}

public function putVars($vars)
{
if(empty($vars)){
vermorag marked this conversation as resolved.
Show resolved Hide resolved
return;
}

if(!is_writable(Loader::getPluginPath())){
throw new CdekApiException('[CDEKDelivery] Failed check directory rights',
'cdek_error.cache.rights',
['path' => Loader::getPluginPath()],
true);
}

$arPath = explode(DIRECTORY_SEPARATOR, $this->file);
unset($arPath[count($arPath) - 1]);

if(!is_writable(Loader::getPluginPath() . implode(DIRECTORY_SEPARATOR, $arPath))){
vermorag marked this conversation as resolved.
Show resolved Hide resolved
throw new CdekApiException('[CDEKDelivery] Failed check directory rights',
'cdek_error.cache.rights',
['path' => Loader::getPluginPath() . implode(DIRECTORY_SEPARATOR, $arPath)],
true);
}

$logFile = fopen( Loader::getPluginPath() . DIRECTORY_SEPARATOR . $this->file, 'w+');

$content = '<?php return ' . var_export($vars, true) . ';' . PHP_EOL;

fwrite($logFile, $content);
vermorag marked this conversation as resolved.
Show resolved Hide resolved
fclose($logFile);
}

public function clear()
{
unlink(Loader::getPluginPath() . DIRECTORY_SEPARATOR . $this->file);
}
}
178 changes: 178 additions & 0 deletions src/CdekCoreApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?php

namespace Cdek;

use Cdek\Contracts\TokenStorageContract;
use Cdek\Exceptions\CdekApiException;
use Cdek\Exceptions\CdekCoreApiException;
use Cdek\Helpers\DBCoreTokenStorage;
use Cdek\Helpers\DBTokenStorage;
use Cdek\Model\CoreApiHeadersData;
use Cdek\Transport\HttpCoreClient;

class CdekCoreApi
{
const SUCCESS_STATUS = 200;
const FINISH_STATUS = 201;
const HAS_NEXT_INFO_STATUS = 202;
const UNKNOWN_METHOD = 404;
const FATAL_ERRORS = [500, 502, 503, 504];
private const TOKEN_PATH = 'cms/wordpress/shops/%s/token';
private const SHOP = 'cms/wordpress/shops';
private const TASKS = 'wordpress/tasks';
public ?int $status;
private TokenStorageContract $generalTokenStorage;
private TokenStorageContract $tokenCoreStorage;
private HttpCoreClient $coreClient;

public function __construct(
?TokenStorageContract $tokenStorage = null,
?TokenStorageContract $tokenCoreStorage = null
)
{
$this->coreClient = new HttpCoreClient();
$this->generalTokenStorage = $tokenStorage ?? new DBTokenStorage();
$this->tokenCoreStorage = $tokenCoreStorage ?? new DBCoreTokenStorage();
}

/**
* @return array
vermorag marked this conversation as resolved.
Show resolved Hide resolved
* @throws CdekApiException
* @throws CdekCoreApiException
* @throws \JsonException
*/
public function fetchShopToken(): array
{
$response = $this->coreClient->sendCdekRequest(
Config::API_CORE_URL . self::SHOP,
'POST',
$this->generalTokenStorage->getToken(),
[
'name' => get_bloginfo('name'),
'url' => [
'rest' => rest_url(),
'home' => home_url(),
'admin' => admin_url(),
],
],
);

if(empty($response['body'])){
throw new CdekCoreApiException('[CDEKDelivery] Failed to get shop uuid',
'cdek_error.uuid.auth',
$response,
true);
}

$body = json_decode($response['body'], true);

if(empty($body) || empty($body['data']['id'])){
throw new CdekCoreApiException('[CDEKDelivery] Failed to get shop uuid',
'cdek_error.uuid.auth',
$response,
true);
}

$response = $this->coreClient->sendCdekRequest(
sprintf(Config::API_CORE_URL . self::TOKEN_PATH, $body['data']['id']),
'POST',
$this->generalTokenStorage->getToken(),
);

$body = json_decode($response['body'],true);

if ($body === null || !$body['success'] || empty($body['data'])) {
throw new CdekCoreApiException('[CDEKDelivery] Failed to get shop token',
'cdek_error.shop_token.auth',
$body,
true);
}

return ['tokens' => $body['data']];
}

/**
* @param $data
*
* @return array|false|string|\WP_Error
* @throws CdekApiException
* @throws CdekCoreApiException
* @throws \JsonException
*/
public function taskManager($data = null)
vermorag marked this conversation as resolved.
Show resolved Hide resolved
{
$response = $this->coreClient->sendCdekRequest($this->getShopApiUrl() . '/' . self::TASKS, 'GET',
$this->tokenCoreStorage->getToken(), $data);

return $this->initData($response);
}

/**
* @param $taskId
* @param null $data
* @param array $headers
*
* @return array|false|string|\WP_Error
* @throws CdekApiException
* @throws CdekCoreApiException
* @throws \JsonException
*/
public function taskInfo($taskId, $data = null, ?CoreApiHeadersData $headers = null)
{
$response = $this->coreClient->sendCdekRequest($this->getShopApiUrl() . '/' . self::TASKS . '/' . $taskId, 'GET',
$this->tokenCoreStorage->getToken(), $data, $headers);

return $this->initData($response);
}

/**
* @param $taskId
* @param $data
* @param ?CoreApiHeadersData $headers
*
* @return array|false|string|\WP_Error
* @throws CdekApiException
* @throws CdekCoreApiException
* @throws \JsonException
*/
public function sendTaskData($taskId, $data, ?CoreApiHeadersData $headers = null)
{
$response = $this->coreClient->sendCdekRequest(
$this->getShopApiUrl() . '/' . self::TASKS . '/' . $taskId,
'PUT',
$this->tokenCoreStorage->getToken(),
$data,
$headers ? $headers->getHeaders() : []
);

return $this->initData($response);
}

private function getShopApiUrl()
{
return $this->tokenCoreStorage->getPath();
}

private function initData($response)
{
$decodeResponse = json_decode($response['body'], true);

$this->status = $decodeResponse['status'];

if(
!in_array(
vermorag marked this conversation as resolved.
Show resolved Hide resolved
$this->status,
[self::FINISH_STATUS, self::HAS_NEXT_INFO_STATUS, self::SUCCESS_STATUS],
)
&&
!in_array($this->status, self::FATAL_ERRORS)
){
throw new CdekCoreApiException('[CDEKDelivery] Failed to get core api response',
'cdek_error.core.response',
$response,
true);
}

return $decodeResponse;
}
}
Loading