Source of file WrapperDriver.php

Size: 8,399 Bytes - Last Modified: 2020-10-25T23:00:04+00:00

/root/gitwork/work/tornelib-php-netcurl-6.1/src/Module/Config/WrapperDriver.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
<?php
/**
 * Copyright © Tomas Tornevall / Tornevall Networks. All rights reserved.
 * See LICENSE.md for license details.
 */

namespace TorneLIB\Module\Config;

use Exception;
use TorneLIB\Exception\Constants;
use TorneLIB\Exception\ExceptionHandler;
use TorneLIB\Module\Network\Wrappers\CurlWrapper;
use TorneLIB\Module\Network\Wrappers\SoapClientWrapper;
use TorneLIB\Module\Network\Wrappers\SimpleStreamWrapper;
use TorneLIB\Module\Network\Wrappers\RssWrapper;
use TorneLIB\Model\Interfaces\WrapperInterface;

/**
 * Class WrapperDriver
 * @package TorneLIB\Module\Config
 * @since 6.1.0
 */
class WrapperDriver
{
    /**
     * Internal wrappers loaded.
     * @var array $wrappers
     * @since 6.1.0
     */
    private static $wrappers = [];

    /**
     * What we support internally.
     *
     * @var array $internalWrapperList
     * @since 6.1.0
     */
    private static $internalWrapperList = [
        CurlWrapper::class,
        SoapClientWrapper::class,
        SimpleStreamWrapper::class,
        RssWrapper::class,
    ];

    /**
     * List of self developed wrappers to use if nothing else works.
     * @var array $externalWrapperList
     * @since 6.1.0
     */
    private static $externalWrapperList = [];

    /**
     * @var $instanceClass
     * @since 6.1.0
     */
    private static $instanceClass;

    /**
     * If true, make NetWrapper try to use those wrappers first.
     * @var bool $useRegisteredWrappersFirst
     * @since 6.1.0
     */
    private static $useRegisteredWrappersFirst = false;

    /**
     * Register external wrapper class as useble if it implements the wrapper interface.
     *
     * @param $wrapperClass
     * @throws ExceptionHandler
     * @since 6.1.0
     */
    private static function registerClassInterface($wrapperClass)
    {
        $badClass = false;

        $wrapperClassName = @get_class($wrapperClass);
        if (!isset(self::$externalWrapperList[$wrapperClassName])) {
            if (self::registerCheckImplements($wrapperClass)) {
                self::$externalWrapperList[$wrapperClassName] = $wrapperClass;
            } else {
                $badClass = true;
            }
        }

        self::registerCheckBadClass($badClass, $wrapperClass);
    }

    /**
     * Check if class is not properly registered and throw exception.
     *
     * @param $badClass
     * @param $wrapperClass
     * @throws ExceptionHandler
     * @since 6.1.0
     */
    private static function registerCheckBadClass($badClass, $wrapperClass)
    {
        if ($badClass) {
            throw new ExceptionHandler(
                sprintf(
                    'Unable to register class %s in %s with wrong interface.',
                    get_class($wrapperClass),
                    __CLASS__
                ),
                Constants::LIB_CLASS_UNAVAILABLE
            );
        }
    }

    /**
     * Checks if registering class implements WrapperInterface.
     *
     * @param $wrapperClass
     * @return bool
     * @since 6.1.0
     */
    private static function registerCheckImplements($wrapperClass)
    {
        $implements = class_implements($wrapperClass);

        return in_array(WrapperInterface::class, $implements, false);
    }

    /**
     * Find out if internal wrapper is available and return it.
     *
     * @param $wrapperNameClass
     * @param bool $testOnly Test wrapper only. Meaning: Do not throw exceptions during control.
     * @return mixed
     * @throws ExceptionHandler
     * @since 6.1.0
     */
    private static function getWrapper($wrapperNameClass, $testOnly = false)
    {
        $return = null;

        //$wrapperNameClass = preg_replace('/\//', "\", $wrapperNameClass);

        $allWrappers = self::getWrappers();
        foreach ($allWrappers as $wrapperClass) {
            $currentWrapperClass = @get_class($wrapperClass);
            if ($currentWrapperClass === $wrapperNameClass ||
                $currentWrapperClass === sprintf('TorneLIB\Module\Network\Wrappers\%s', $wrapperNameClass)
            ) {
                self::$instanceClass = $wrapperNameClass;
                $return = $wrapperClass;
                break;
            }
        }

        if (!$testOnly && !is_object($return)) {
            throw new ExceptionHandler(
                sprintf(
                    'Could not find a proper NetWrapper (%s) to communicate with!',
                    $wrapperNameClass
                ),
                Constants::LIB_NETCURL_NETWRAPPER_NO_DRIVER_FOUND
            );
        }

        // When instance handling resided in Netwrapper, the last instance was always stored internally.
        // This is not necessary here.
        // @todo Remove this entirely in future releases.
        //self::$instance = $return;

        return $return;
    }

    /**
     * Returns proper wrapper for internal wrapper requests, depending on external available wrappers.
     *
     * @param $wrapperName
     * @param bool $testOnly
     * @return mixed
     * @throws ExceptionHandler
     * @since 6.1.0
     */
    public static function getWrapperAllowed($wrapperName, $testOnly = false)
    {
        // If there are no available external wrappers, let getWrapper do its actions and throw exceptions if
        // the internal wrapper fails to load.
        if (!count(self::$externalWrapperList)) {
            $return = self::getWrapper($wrapperName, $testOnly);
        } else {
            // If there are available external wrappers, just try to load external wrapper and proceed
            // without noise on failures, as we'd like to try to use the externals first. Always.
            $return = self::getWrapper($wrapperName, true);
        }

        return $return;
    }

    /**
     * Initialize available wrappers.
     * @return mixed
     * @since 6.1.0
     */
    public static function initializeWrappers()
    {
        foreach (self::$internalWrapperList as $wrapperClass) {
            if (!empty($wrapperClass) &&
                !isset(self::$wrappers[$wrapperClass])
            ) {
                try {
                    self::$wrappers[$wrapperClass] = new $wrapperClass();
                } catch (Exception $wrapperLoadException) {
                }
            }
        }

        return self::$wrappers;
    }

    /**
     * Returns the instance classname if set and ready.
     *
     * @return string
     * @throws ExceptionHandler
     * @since 6.1.0
     */
    public static function getInstanceClass()
    {
        if (empty(self::$instanceClass)) {
            throw new ExceptionHandler(
                sprintf(
                    '%s instantiation failure: No wrapper available.',
                    __CLASS__
                ),
                Constants::LIB_NETCURL_NETWRAPPER_NO_DRIVER_FOUND
            );
        }

        return (string)self::$instanceClass;
    }

    /**
     * Register a new wrapperclass for netcurl (NetWrapper).
     *
     * @param $wrapperClass
     * @param bool $tryFirst
     * @return string
     * @throws ExceptionHandler
     * @since 6.1.0
     */
    public static function register($wrapperClass, $tryFirst = false)
    {
        if (!is_object($wrapperClass)) {
            throw new ExceptionHandler(
                sprintf(
                    'Unable to register wrong class type in %s.',
                    __CLASS__
                ),
                Constants::LIB_CLASS_UNAVAILABLE
            );
        }

        self::$useRegisteredWrappersFirst = $tryFirst;
        self::registerClassInterface($wrapperClass);

        return self::class;
    }

    /**
     * If this is true Netwrapper will try the registered drivers before the internal.
     *
     * @return bool
     * @since 6.1.0
     */
    public static function getRegisteredWrappersFirst()
    {
        return self::$useRegisteredWrappersFirst;
    }

    /**
     * Get list of available wrappers, both internal and external.
     *
     * @return array
     * @since 6.1.0
     */
    public static function getWrappers()
    {
        // return self::$wrappers;
        return array_merge(self::$wrappers, self::$externalWrapperList);
    }

    /**
     * Get list of externally registered wrappers.
     *
     * @return array
     * @since 6.1.0
     */
    public static function getExternalWrappers()
    {
        return self::$externalWrapperList;
    }
}