Application.php 5.1 KB
<?php

namespace Lackoxygen\TiktokShop;

use Illuminate\Support\Arr;
use Lackoxygen\TiktokShop\Attribute\Config\Option;
use Lackoxygen\TiktokShop\Exception\RequestNotFoundException;
use Lackoxygen\TiktokShop\Request\RequestProxy;
use Lackoxygen\TiktokShop\Support\Verify;

/**
 * @method Verify verify()
 * @method Request\Pigeon\PigeonInterface pigeon()
 * @method Request\Sms\SmsInterface sms()
 * @method Request\SupplyChain\SupplyChainInterface supplyChain()
 * @method Request\Topup\TopupInterface topup()
 * @method Request\OpenCloud\OpenCloudInterface openCloud()
 * @method Request\Btas\BtasInterface btas()
 * @method Request\Recycle\RecycleInterface recycle()
 * @method Request\Member\MemberInterface member()
 * @method Request\Buyin\BuyinInterface buyin()
 * @method Request\Yunc\YuncInterface yunc()
 * @method Request\OrderCode\OrderCodeInterface orderCode()
 * @method Request\Coupons\CouponsInterface coupons()
 * @method Request\Crossborder\CrossborderInterface crossborder()
 * @method Request\Iop\IopInterface iop()
 * @method Request\Antispam\AntispamInterface antispam()
 * @method Request\Token\TokenInterface token()
 * @method Request\Order\OrderInterface order()
 * @method Request\AfterSale\AfterSaleInterface afterSale()
 * @method Request\Logistics\LogisticsInterface logistics()
 * @method Request\Warehouse\WarehouseInterface warehouse()
 * @method Request\Product\ProductInterface product()
 * @method Request\Material\MaterialInterface material()
 * @method Request\Address\AddressInterface address()
 */
class Application
{
    /**
     * @var Option
     */
    protected Option $config;

    /**
     * @var array|string[]
     */
    protected array $fixedPriority = [
        'verify' => Verify::class
    ];

    /**
     * @param $options
     */
    public function __construct($options = null)
    {
        $this->config = $this->loadConfig($options);
    }

    /**
     * Read configuration
     *
     * @param $options
     * @return Option
     */
    protected function loadConfig($options): Option
    {
        if ($options instanceof Option) {
            return $options;
        }
        if (is_array($options)) {
            return static::newConfigFormArray($options);
        }
        if (is_string($options)) {
            return $this->configure($options);
        }
        return $this->configure();
    }

    /**
     * Load configuration
     *
     * @param string $app
     * @return Option
     */
    protected function configure(string $app = 'default'): Option
    {
        $configure = \config(ServiceProvider::$name . '.' . $app);

        if (is_null($configure)) {
            throw new \InvalidArgumentException('Please publish the configuration file first');
        }

        return static::newConfigFormArray($configure);
    }


    /**
     * Load configuration to object Option
     *
     * @param array $options
     * @return Option
     */
    public static function newConfigFormArray(array $options): Option
    {
        $option = new Option();
        $option->setAppKey((string)Arr::get($options, 'app_key', ''));
        $option->setAppSecret((string)Arr::get($options, 'app_secret', ''));
        $option->setBaseUri((string)Arr::get($options, 'base_uri', 'https://openapi-sandbox.jinritemai.com'));
        $option->setTimeout((float)Arr::get($options, 'timeout', 5));
        $option->setEnableMock((bool)Arr::get($options, 'enable_mock'));
        $option->setSignMethod((string)Arr::get($options, 'sign_method', 'sha256'));
        $option->setVersion((string)Arr::get($options, 'version', '2'));
        return $option;
    }

    /**
     * @param $options
     *
     * @return Application
     */
    public static function app($options = null): Application
    {
        return new static($options);
    }

    /**
     * Set access token
     *
     * @param string $accessToken
     * @return Application
     */
    public function accessToken(string $accessToken): Application
    {
        $this->config->setAccessToken($accessToken);

        return $this;
    }

    /**
     * Match object
     *
     * @param string $name
     * @return RequestProxy|object
     * @throws RequestNotFoundException
     */
    private function guide(string $name)
    {
        if (array_key_exists($name, $this->fixedPriority)) {
            return new $this->fixedPriority[$name]($this->config);
        }

        $name = ucfirst($name);

        $request = '\Lackoxygen\TiktokShop\Request\\' . $name . '\\' . $name;

        if (!class_exists($request)) {
            throw new RequestNotFoundException('class file(' . $request . ') not found');
        }

        return RequestProxy::proxy($request, $this->config);
    }

    /**
     * Call object
     *
     * @param $name
     * @param array $arguments
     * @return RequestProxy
     * @throws RequestNotFoundException
     */
    public function __call($name, array $arguments = [])
    {
        $guide = $this->guide($name);

        try {
            return $guide;
        } finally {
            if ($guide instanceof RequestProxy) {
                register_shutdown_function(function () {
                    $this->config->setAccessToken('');
                });
            }
        }
    }
}