First basic ready-to-use implementation

This commit is contained in:
2023-08-03 12:48:59 +08:00
parent 5cc681de63
commit 3b94911895
23 changed files with 1177 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Abstract;
use Exception;
use PmConverter\Exporters\{
RequestContract};
use PmConverter\FileSystem;
/**
*
*/
abstract class AbstractConverter
{
/**
* @var object|null
*/
protected ?object $collection = null;
/**
* @var string
*/
protected string $outputPath;
/**
* @throws Exception
*/
public function convert(object $collection, string $outputPath): void
{
$outputPath = sprintf('%s%s%s', $outputPath, DIRECTORY_SEPARATOR, static::OUTPUT_DIR);
$this->outputPath = FileSystem::makeDir($outputPath);
$this->collection = $collection;
foreach ($collection->item as $item) {
$this->convertItem($item);
}
}
/**
* @return string
*/
public function getOutputPath(): string
{
return $this->outputPath;
}
/**
* @param object $item
* @return bool
*/
protected function isItemFolder(object $item): bool
{
return !empty($item->item) && empty($item->request);
}
/**
* @throws Exception
*/
protected function convertItem(mixed $item): void
{
if ($this->isItemFolder($item)) {
static $dir_tree;
foreach ($item->item as $subitem) {
$dir_tree[] = $item->name;
$path = implode(DIRECTORY_SEPARATOR, $dir_tree);
if ($this->isItemFolder($subitem)) {
$this->convertItem($subitem);
} else {
$this->writeRequest($this->initRequest($subitem), $path);
}
array_pop($dir_tree);
}
} else {
$this->writeRequest($this->initRequest($item));
}
}
/**
* @param object $item
* @return RequestContract
*/
protected function initRequest(object $item): RequestContract
{
$request_class = static::REQUEST;
$result = new $request_class();
$result->setName($item->name);
$result->setDescription($item->request?->description ?? null);
$result->setVerb($item->request->method);
$result->setUrl($item->request->url->raw);
$result->setHeaders($item->request->header);
if ($item->request->method !== 'GET' && !empty($item->request->body)) {
$result->setBody($item->request->body);
}
return $result;
}
/**
* @param RequestContract $request
* @param string|null $subpath
* @return bool
* @throws Exception
*/
protected function writeRequest(RequestContract $request, string $subpath = null): bool
{
$filedir = sprintf('%s%s%s', $this->outputPath, DIRECTORY_SEPARATOR, $subpath);
$filedir = FileSystem::makeDir($filedir);
$filepath = sprintf('%s%s%s.%s', $filedir, DIRECTORY_SEPARATOR, $request->getName(), static::FILE_EXT);
return file_put_contents($filepath, (string)$request) > 0;
}
}

View File

@@ -0,0 +1,164 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Abstract;
use PmConverter\Exporters\Http\HttpRequest;
use PmConverter\Exporters\RequestContract;
/**
*
*/
abstract class AbstractRequest implements RequestContract
{
/**
* @var string
*/
protected string $http = 'HTTP/1.1'; //TODO verb
/**
* @var string
*/
protected string $name;
/**
* @var string|null
*/
protected ?string $description = null;
/**
* @var array
*/
protected array $headers = [];
/**
* @var mixed
*/
protected mixed $body = null;
/**
* @var string
*/
protected string $bodymode = 'raw';
/**
* @var string
*/
protected string $verb;
/**
* @var string
*/
protected string $url;
/**
* @param string $name
* @return HttpRequest
*/
public function setName(string $name): static
{
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getName(): string
{
return str_replace(DIRECTORY_SEPARATOR, '_', $this->name);
}
/**
* @param string|null $description
* @return HttpRequest
*/
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
/**
* @param string $verb
* @return HttpRequest
*/
public function setVerb(string $verb): static
{
$this->verb = $verb;
return $this;
}
/**
* @param string $url
* @return HttpRequest
*/
public function setUrl(string $url): static
{
$this->url = $url;
return $this;
}
/**
* @param object[]|null $headers
* @return $this
*/
public function setHeaders(?array $headers): static
{
foreach ($headers as $header) {
$this->headers[$header->key] = [
'value' => $header->value,
'disabled' => $header?->disabled ?? false,
];
}
return $this;
}
/**
* @param string $bodymode
* @return HttpRequest
*/
public function setBodymode(string $bodymode): static
{
$this->bodymode = $bodymode;
return $this;
}
/**
* @param string $body
* @return HttpRequest
*/
public function setBody(object $body): static
{
$this->setBodymode($body->mode);
if (!empty($body->options) && $body->options->{$this->bodymode}->language === 'json') {
empty($this->headers['Content-Type']) && $this->setHeaders([
(object)[
'key' => 'Content-Type',
'value' => 'application/json',
'disabled' => false,
],
]);
}
$body->mode === 'formdata' && $this->setHeaders([
(object)[
'key' => 'Content-Type',
'value' => 'multipart/form-data',
'disabled' => false,
],
]);
$this->body = $body->{$body->mode};
return $this;
}
/**
* @return string
*/
abstract protected function prepareBody(): ?string;
/**
* @return string
*/
abstract public function __toString(): string;
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters;
use PmConverter\Exporters\Curl\CurlConverter;
use PmConverter\Exporters\Http\HttpConverter;
use PmConverter\Exporters\Wget\WgetConverter;
enum ConvertFormat: string
{
case Http = HttpConverter::class;
case Curl = CurlConverter::class;
case Wget = WgetConverter::class;
}

View File

@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters;
interface ConverterContract
{
public function convert(object $collection, string $outputPath): void;
public function getOutputPath(): string;
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Curl;
use PmConverter\Exporters\{
Abstract\AbstractConverter,
ConverterContract};
class CurlConverter extends AbstractConverter implements ConverterContract
{
protected const FILE_EXT = 'sh';
protected const OUTPUT_DIR = 'curl';
protected const REQUEST = CurlRequest::class;
}

View File

@@ -0,0 +1,65 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Curl;
use PmConverter\Exporters\Abstract\AbstractRequest;
/**
*
*/
class CurlRequest extends AbstractRequest
{
/**
* @return string
*/
protected function prepareBody(): ?string
{
switch ($this->bodymode) {
case 'formdata':
$body = [];
foreach ($this->body as $data) {
$body[] = sprintf(
"%s\t--form '%s=%s' \ ",
isset($data->disabled) ? '# ' : '',
$data->key,
$data->type === 'file' ? "@$data->src" : $data->value
);
}
return implode(PHP_EOL, $body);
default:
return $this->body;
}
}
/**
* @return string
*/
public function __toString(): string
{
$output[] = '#!/bin/sh';
if ($this->description) {
$output[] = '# ' . str_replace("\n", "\n# ", $this->description);
$output[] = '';
}
$output[] = "curl \ ";
$output[] = "\t--http1.1 \ "; //TODO verb
$output[] = "\t--request $this->verb \ ";
$output[] = "\t--location $this->url \ ";
foreach ($this->headers as $header_key => $header) {
if ($header['disabled']) {
continue;
}
$output[] = sprintf("\t--header '%s=%s' \ ", $header_key, $header['value']);
}
if (!is_null($body = $this->prepareBody())) {
$output[] = match ($this->bodymode) {
'formdata' => $body,
default => "\t--data '$body'",
};
}
$output[] = rtrim(array_pop($output), '\ ');
return implode(PHP_EOL, $output);
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Http;
use PmConverter\Exporters\{
Abstract\AbstractConverter,
ConverterContract};
class HttpConverter extends AbstractConverter implements ConverterContract
{
protected const FILE_EXT = 'http';
protected const OUTPUT_DIR = 'http';
protected const REQUEST = HttpRequest::class;
}

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Http;
use PmConverter\Exporters\Abstract\AbstractRequest;
/**
*
*/
class HttpRequest extends AbstractRequest
{
/**
* @return string
*/
protected function prepareBody(): ?string
{
switch ($this->bodymode) {
case 'formdata':
$body = [];
foreach ($this->body as $data) {
$body[] = sprintf(
'%s%s=%s',
empty($data->disabled) ? '' : '# ',
$data->key,
$data->type === 'file' ? "$data->src" : $data->value
);
}
return implode(PHP_EOL, $body);
default:
return $this->body;
}
}
/**
* @return string
*/
public function __toString(): string
{
if ($this->description) {
$output[] = '# ' . str_replace("\n", "\n# ", $this->description);
$output[] = '';
}
$output[] = "$this->verb $this->url $this->http";
foreach ($this->headers as $header_key => $header) {
$output[] = sprintf('%s%s: %s', $header['disabled'] ? '# ' : '', $header_key, $header['value']);
}
$output[] = '';
$output[] = (string)$this->prepareBody();
return implode(PHP_EOL, $output);
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters;
interface RequestContract
{
public function setName(string $name): static;
public function getName(): string;
public function setDescription(?string $description): static;
public function setVerb(string $verb): static;
public function setUrl(string $url): static;
public function setHeaders(?array $headers): static;
public function setBodymode(string $bodymode): static;
public function setBody(object $body): static;
public function __toString(): string;
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Wget;
use PmConverter\Exporters\{
Abstract\AbstractConverter,
ConverterContract};
class WgetConverter extends AbstractConverter implements ConverterContract
{
protected const FILE_EXT = 'sh';
protected const OUTPUT_DIR = 'wget';
protected const REQUEST = WgetRequest::class;
}

View File

@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace PmConverter\Exporters\Wget;
use PmConverter\Exporters\Abstract\AbstractRequest;
/**
*
*/
class WgetRequest extends AbstractRequest
{
/**
* @return string
*/
protected function prepareBody(): ?string
{
switch ($this->bodymode) {
case 'formdata':
$lines = [];
foreach ($this->body as &$data) {
if ($data->type === 'file') {
continue;
}
$lines[$data->key] = $data->value;
}
$body[] = http_build_query($lines);
return implode(PHP_EOL, $body);
default:
return $this->body;
}
}
/**
* @return string
*/
public function __toString(): string
{
$output[] = '#!/bin/sh';
if ($this->description) {
$output[] = '# ' . str_replace("\n", "\n# ", $this->description);
$output[] = '';
}
$output[] = 'wget \ ';
$output[] = "\t--no-check-certificate \ ";
$output[] = "\t--quiet \ ";
$output[] = "\t--timeout=0 \ ";
$output[] = "\t--method $this->verb \ ";
foreach ($this->headers as $header_key => $header) {
if ($header['disabled']) {
continue;
}
$output[] = sprintf("\t--header '%s=%s' \ ", $header_key, $header['value']);
}
if (!is_null($body = $this->prepareBody())) {
$output[] = "\t--body-data '$body' \ ";
}
$output[] = rtrim(array_pop($output), '\ ');
$output[] = "\t'$this->url'";
return implode(PHP_EOL, $output);
}
}