2

I am facing "Deprecated Functionality: Zend_Http_UserAgent implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize()" Error in magento2.4.4

All version compatibility is fine.

My PHP version: 8.1.2

Magento Version: 2.4.4

Does anyone have solution for this?

Thanks

4

1 Answer 1

0

Past this code in your UserAgents.PHP After this run the command: bin/magento setup:di:compile

    <?php



class Zend_Http_UserAgent //implements Serializable 
{
    /**
     * 'desktop' by default if the sequence return false for each item or is empty
     */
    const DEFAULT_IDENTIFICATION_SEQUENCE = 'mobile,desktop';

    /**
     * Default persitent storage adapter : Session or NonPersitent
     */
    const DEFAULT_PERSISTENT_STORAGE_ADAPTER = 'Session';

    /**
     * 'desktop' by default if the sequence return false for each item
     */
    const DEFAULT_BROWSER_TYPE = 'desktop';

    /**
     * Default User Agent chain to prevent empty value
     */
    const DEFAULT_HTTP_USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)';

    /**
     * Default Http Accept param to prevent empty value
     */
    const DEFAULT_HTTP_ACCEPT = "application/xhtml+xml";

    /**
     * Default markup language
     */
    const DEFAULT_MARKUP_LANGUAGE = "xhtml";

    /**
     * Browser type
     *
     * @var string
     */
    protected $_browserType;

    /**
     * Browser type class
     *
     * Map of browser types to classes.
     *
     * @var array
     */
    protected $_browserTypeClass = array();

    /**
     * Array to store config
     *
     * Default values are provided to ensure specific keys are present at
     * instantiation.
     *
     * @var array
     */
    protected $_config = array(
        'identification_sequence' => self::DEFAULT_IDENTIFICATION_SEQUENCE,
        'storage'                 => array(
            'adapter'             => self::DEFAULT_PERSISTENT_STORAGE_ADAPTER,
        ),
    );

    /**
     * Identified device
     *
     * @var Zend_Http_UserAgent_Device
     */
    protected $_device;

    /**
     * Whether or not this instance is immutable.
     *
     * If true, none of the following may be modified:
     * - $_server
     * - $_browserType
     * - User-Agent (defined in $_server)
     * - HTTP Accept value (defined in $_server)
     * - $_storage
     *
     * @var bool
     */
    protected $_immutable = false;

    /**
     * Plugin loaders
     * @var array
     */
    protected $_loaders = array();

    /**
     * Valid plugin loader types
     * @var array
     */
    protected $_loaderTypes = array('storage', 'device');

    /**
     * Trace of items matched to identify the browser type
     *
     * @var array
     */
    protected $_matchLog = array();

    /**
     * Server variable
     *
     * @var array
     */
    protected $_server;

    /**
     * Persistent storage handler
     *
     * @var Zend_Http_UserAgent_Storage
     */
    protected $_storage;

    /**
     * Constructor
     *
     * @param  null|array|Zend_Config|ArrayAccess $options
     * @return void
     */
    public function __construct($options = null)
    {
        if (null !== $options) {
            $this->setOptions($options);
        }
    }

    /**
     * Serialized representation of the object
     *
     * @return string
     */
    public function serialize()
    {
        $device = $this->getDevice();
        $spec = array(
            'browser_type' => $this->_browserType,
            'config'       => $this->_config,
            'device_class' => get_class($device),
            'device'       => $device->serialize(),
            'user_agent'   => $this->getServerValue('http_user_agent'),
            'http_accept'  => $this->getServerValue('http_accept'),
        );
        return serialize($spec);
    }

    /**
     * Unserialize a previous representation of the object
     *
     * @param  string $serialized
     * @return void
     */
    public function unserialize($serialized)
    {
        $spec = unserialize($serialized);

        $this->setOptions($spec);

        // Determine device class and ensure the class is loaded
        $deviceClass          = $spec['device_class'];
        if (!class_exists($deviceClass)) {
            $this->_getUserAgentDevice($this->getBrowserType());
        }

        // Get device specification and instantiate
        $deviceSpec            = unserialize($spec['device']);
        $deviceSpec['_config'] = $this->getConfig();
        $deviceSpec['_server'] = $this->getServer();
        $this->_device = new $deviceClass($deviceSpec);
    }

    /**
     * Configure instance
     *
     * @param  array|Zend_Config|ArrayAccess $options
     * @return Zend_Http_UserAgent
     */
    public function setOptions($options)
    {
        if ($options instanceof Zend_Config) {
            $options = $options->toArray();
        }

        if (!is_array($options)
            && !$options instanceof ArrayAccess
            && !$options instanceof Traversable
        ) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Invalid argument; expected array, Zend_Config object, or object implementing ArrayAccess and Traversable; received %s',
                (is_object($options) ? get_class($options) : gettype($options))
            ));
        }

        // Set $_SERVER first
        if (isset($options['server'])) {
            $this->setServer($options['server']);
            unset($options['server']);
        }

        // Get plugin loaders sorted
        if (isset($options['plugin_loader'])) {
            $plConfig = $options['plugin_loader'];
            if (is_array($plConfig) || $plConfig instanceof Traversable) {
                foreach ($plConfig as $type => $class) {
                    $this->setPluginLoader($type, $class);
                }
            }
            unset($plConfig, $options['plugin_loader']);
        }

        // And then loop through the remaining options
        $config = array();
        foreach ($options as $key => $value) {
            switch (strtolower($key)) {
                case 'browser_type':
                    $this->setBrowserType($value);
                    break;
                case 'http_accept':
                    $this->setHttpAccept($value);
                    break;
                case 'user_agent':
                    $this->setUserAgent($value);
                    break;
                default:
                    // Cache remaining options for $_config
                    $config[$key] = $value;
                    break;
            }
        }
        $this->setConfig($config);

        return $this;
    }

    /**
     * Comparison of the UserAgent chain and browser signatures.
     *
     * The comparison is case-insensitive : the browser signatures must be in lower
     * case
     *
     * @param  string $deviceClass Name of class against which a match will be attempted
     * @return bool
     */
    protected function _match($deviceClass)
    {
        // Validate device class
        $r = new ReflectionClass($deviceClass);
        if (!$r->implementsInterface('Zend_Http_UserAgent_Device')) {
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Invalid device class provided ("%s"); must implement Zend_Http_UserAgent_Device',
                $deviceClass
            ));
        }

        $userAgent = $this->getUserAgent();

        // Call match method on device class
        return call_user_func(
            array($deviceClass, 'match'),
            $userAgent,
            $this->getServer()
        );
    }

    /**
     * Loads class for a user agent device
     *
     * @param  string $browserType Browser type
     * @return string
     * @throws Zend_Loader_PluginLoader_Exception if unable to load UA device
     */
    protected function _getUserAgentDevice($browserType)
    {
        $browserType = strtolower($browserType);
        if (isset($this->_browserTypeClass[$browserType])) {
            return $this->_browserTypeClass[$browserType];
        }

        if (isset($this->_config[$browserType])
            && isset($this->_config[$browserType]['device'])
        ) {
            $deviceConfig = $this->_config[$browserType]['device'];
            if (is_array($deviceConfig) && isset($deviceConfig['classname'])) {
                $device = (string) $deviceConfig['classname'];
                if (!class_exists($device)) {
                    #require_once 'Zend/Http/UserAgent/Exception.php';
                    throw new Zend_Http_UserAgent_Exception(sprintf(
                        'Invalid classname "%s" provided in device configuration for browser type "%s"',
                        $device,
                        $browserType
                    ));
                }
            } elseif (is_array($deviceConfig) && isset($deviceConfig['path'])) {
                $loader = $this->getPluginLoader('device');
                $path   = $deviceConfig['path'];
                $prefix = isset($deviceConfig['prefix']) ? $deviceConfig['prefix'] : 'Zend_Http_UserAgent';
                $loader->addPrefixPath($prefix, $path);

                $device = $loader->load($browserType);
            } else {
                $loader = $this->getPluginLoader('device');
                $device = $loader->load($browserType);
            }
        } else {
            $loader = $this->getPluginLoader('device');
            $device = $loader->load($browserType);
        }

        $this->_browserTypeClass[$browserType] = $device;

        return $device;
    }

    /**
     * Returns the User Agent value
     *
     * If $userAgent param is null, the value of $_server['HTTP_USER_AGENT'] is
     * returned.
     *
     * @return string
     */
    public function getUserAgent()
    {
        if (null === ($ua = $this->getServerValue('http_user_agent'))) {
            $ua = self::DEFAULT_HTTP_USER_AGENT;
            $this->setUserAgent($ua);
        }

        return $ua;
    }

    /**
     * Force or replace the UA chain in $_server variable
     *
     * @param  string $userAgent Forced UserAgent chain
     * @return Zend_Http_UserAgent
     */
    public function setUserAgent($userAgent)
    {
        $this->setServerValue('http_user_agent', $userAgent);
        return $this;
    }

    /**
     * Returns the HTTP Accept server param
     *
     * @param  string $httpAccept (option) forced HTTP Accept chain
     * @return string
     */
    public function getHttpAccept($httpAccept = null)
    {
        if (null === ($accept = $this->getServerValue('http_accept'))) {
            $accept = self::DEFAULT_HTTP_ACCEPT;
            $this->setHttpAccept($accept);
        }
        return $accept;
    }

    /**
     * Force or replace the HTTP_ACCEPT chain in self::$_server variable
     *
     * @param  string $httpAccept Forced HTTP Accept chain
     * @return Zend_Http_UserAgent
     */
    public function setHttpAccept($httpAccept)
    {
        $this->setServerValue('http_accept', $httpAccept);
        return $this;
    }

    /**
     * Returns the persistent storage handler
     *
     * Session storage is used by default unless a different storage adapter
     * has been set via the "persistent_storage_adapter" key. That key should
     * contain either a fully qualified class name, or a short name that
     * resolves via the plugin loader.
     *
     * @param  string $browser Browser identifier (User Agent chain)
     * @return Zend_Http_UserAgent_Storage
     */
    public function getStorage($browser = null)
    {
        if (null === $browser) {
            $browser = $this->getUserAgent();
        }
        if (null === $this->_storage) {
            $config  = $this->_config['storage'];
            $adapter = $config['adapter'];
            if (!class_exists($adapter)) {
                $loader = $this->getPluginLoader('storage');
                $adapter = $loader->load($adapter);
                $loader = $this->getPluginLoader('storage');
            }
            $options = array('browser_type' => $browser);
            if (isset($config['options'])) {
                $options = array_merge($options, $config['options']);
            }
            $this->setStorage(new $adapter($options));
        }
        return $this->_storage;
    }

    /**
     * Sets the persistent storage handler
     *
     * @param  Zend_Http_UserAgent_Storage $storage
     * @return Zend_Http_UserAgent
     */
    public function setStorage(Zend_Http_UserAgent_Storage $storage)
    {
        if ($this->_immutable) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(
                'The User-Agent device object has already been retrieved; the storage object is now immutable'
            );
        }

        $this->_storage = $storage;
        return $this;
    }

    /**
     * Clean the persistent storage
     *
     * @param  string $browser Browser identifier (User Agent chain)
     * @return void
     */
    public function clearStorage($browser = null)
    {
        $this->getStorage($browser)->clear();
    }

    /**
     * Get user configuration
     *
     * @return array
     */
    public function getConfig()
    {
        return $this->_config;
    }

    /**
     * Config parameters is an Array or a Zend_Config object
     *
     * The allowed parameters are :
     * - the identification sequence (can be empty) => desktop browser type is the
     * default browser type returned
     * $config['identification_sequence'] : ',' separated browser types
     * - the persistent storage adapter
     * $config['persistent_storage_adapter'] = "Session" or "NonPersistent"
     * - to add or replace a browser type device
     * $config[(type)]['device']['path']
     * $config[(type)]['device']['classname']
     * - to add or replace a browser type features adapter
     * $config[(type)]['features']['path']
     * $config[(type)]['features']['classname']
     *
     * @param  mixed $config (option) Config array
     * @return Zend_Http_UserAgent
     */
    public function setConfig($config = array())
    {
        if ($config instanceof Zend_Config) {
            $config = $config->toArray();
        }

        // Verify that Config parameters are in an array.
        if (!is_array($config) && !$config instanceof Traversable) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Config parameters must be in an array or a Traversable object; received "%s"',
                (is_object($config) ? get_class($config) : gettype($config))
            ));
        }

        if ($config instanceof Traversable) {
            $tmp = array();
            foreach ($config as $key => $value) {
                $tmp[$key] = $value;
            }
            $config = $tmp;
            unset($tmp);
        }

        $this->_config = array_merge($this->_config, $config);
        return $this;
    }

    /**
     * Returns the device object
     *
     * This is the object that will contain the various discovered device
     * capabilities.
     *
     * @return Zend_Http_UserAgent_Device $device
     */
    public function getDevice()
    {
        if (null !== $this->_device) {
            return $this->_device;
        }

        $userAgent = $this->getUserAgent();

        // search an existing identification in the session
        $storage = $this->getStorage($userAgent);

        if (!$storage->isEmpty()) {
            // If the user agent and features are already existing, the
            // Zend_Http_UserAgent object is serialized in the session
            $object = $storage->read();
            $this->unserialize($object);
        } else {
            // Otherwise, the identification is made and stored in the session.
            // Find the browser type:
            $this->setBrowserType($this->_matchUserAgent());
            $this->_createDevice();

            // put the result in storage:
            $this->getStorage($userAgent)
                 ->write($this->serialize());
        }

        // Mark the object as immutable
        $this->_immutable = true;

        // Return the device instance
        return $this->_device;
    }

    /**
     * Retrieve the browser type
     *
     * @return string $browserType
     */
    public function getBrowserType()
    {
        return $this->_browserType;
    }

    /**
     * Set the browser "type"
     *
     * @param string $browserType
     * @return Zend_Http_UserAgent
     */
    public function setBrowserType($browserType)
    {
        if ($this->_immutable) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(
                'The User-Agent device object has already been retrieved; the browser type is now immutable'
            );
        }

        $this->_browserType = $browserType;
        return $this;
    }

    /**
     * Retrieve the "$_SERVER" array
     *
     * Basically, the $_SERVER array or an equivalent container storing the
     * data that will be introspected.
     *
     * If the value has not been previously set, it sets itself from the
     * $_SERVER superglobal.
     *
     * @return array
     */
    public function getServer()
    {
        if (null === $this->_server) {
            $this->setServer($_SERVER);
        }
        return $this->_server;
    }

    /**
     * Set the "$_SERVER" array
     *
     * Basically, the $_SERVER array or an equivalent container storing the
     * data that will be introspected.
     *
     * @param  array|ArrayAccess $server
     * @return void
     * @throws Zend_Http_UserAgent_Exception on invalid parameter
     */
    public function setServer($server)
    {
        if ($this->_immutable) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(
                'The User-Agent device object has already been retrieved; the server array is now immutable'
            );
        }

        if (!is_array($server) && !$server instanceof Traversable) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Expected an array or object implementing Traversable; received %s',
                (is_object($server) ? get_class($server) : gettype($server))
            ));
        }

        // Get an array if we don't have one
        if ($server instanceof ArrayObject) {
            $server = $server->getArrayCopy();
        } elseif ($server instanceof Traversable) {
            $tmp = array();
            foreach ($server as $key => $value) {
                $tmp[$key] = $value;
            }
            $server = $tmp;
            unset($tmp);
        }

        // Normalize key case
        $server = array_change_key_case($server, CASE_LOWER);

        $this->_server = $server;
        return $this;
    }

    /**
     * Retrieve a server value
     *
     * @param  string $key
     * @return mixed
     */
    public function getServerValue($key)
    {
        $key    = strtolower($key);
        $server = $this->getServer();
        $return = null;
        if (isset($server[$key])) {
            $return = $server[$key];
        }
        unset($server);
        return $return;
    }

    /**
     * Set a server value
     *
     * @param  string|int|float $key
     * @param  mixed $value
     * @return void
     */
    public function setServerValue($key, $value)
    {
        if ($this->_immutable) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(
                'The User-Agent device object has already been retrieved; the server array is now immutable'
            );
        }

        $server = $this->getServer(); // ensure it's been initialized
        $key    = strtolower($key);
        $this->_server[$key] = $value;
        return $this;
    }

    /**
     * Set plugin loader
     *
     * @param  string $type Type of plugin loader; one of 'storage', (?)
     * @param  string|Zend_Loader_PluginLoader $loader
     * @return Zend_Http_UserAgent
     */
    public function setPluginLoader($type, $loader)
    {
        $type       = $this->_validateLoaderType($type);

        if (is_string($loader)) {
            if (!class_exists($loader)) {
                #require_once 'Zend/Loader.php';
                Zend_Loader::loadClass($loader);
            }
            $loader = new $loader();
        } elseif (!is_object($loader)) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Expected a plugin loader class or object; received %s',
                gettype($loader)
            ));
        }
        if (!$loader instanceof Zend_Loader_PluginLoader) {
            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Expected an object extending Zend_Loader_PluginLoader; received %s',
                get_class($loader)
            ));
        }

        $basePrefix = 'Zend_Http_UserAgent_';
        $basePath   = 'Zend/Http/UserAgent/';
        switch ($type) {
            case 'storage':
                $prefix = $basePrefix . 'Storage';
                $path   = $basePath   . 'Storage';
                break;
            case 'device':
                $prefix = $basePrefix;
                $path   = $basePath;
                break;
        }
        $loader->addPrefixPath($prefix, $path);
        $this->_loaders[$type] = $loader;
        return $this;
    }

    /**
     * Get a plugin loader
     *
     * @param  string $type A valid plugin loader type; see {@link $_loaderTypes}
     * @return Zend_Loader_PluginLoader
     */
    public function getPluginLoader($type)
    {
        $type = $this->_validateLoaderType($type);
        if (!isset($this->_loaders[$type])) {
            #require_once 'Zend/Loader/PluginLoader.php';
            $this->setPluginLoader($type, new Zend_Loader_PluginLoader());
        }
        return $this->_loaders[$type];
    }

    /**
     * Validate a plugin loader type
     *
     * Verifies that it is in {@link $_loaderTypes}, and returns a normalized
     * version of the type.
     *
     * @param  string $type
     * @return string
     * @throws Zend_Http_UserAgent_Exception on invalid type
     */
    protected function _validateLoaderType($type)
    {
        $type = strtolower($type);
        if (!in_array($type, $this->_loaderTypes)) {
            $types = implode(', ', $this->_loaderTypes);

            #require_once 'Zend/Http/UserAgent/Exception.php';
            throw new Zend_Http_UserAgent_Exception(sprintf(
                'Expected one of "%s" for plugin loader type; received "%s"',
                $types,
                (string) $type
            ));
        }
        return $type;
    }

    /**
     * Run the identification sequence to match the right browser type according to the
     * user agent
     *
     * @return Zend_Http_UserAgent_Result
     */
    protected function _matchUserAgent()
    {
        $type = self::DEFAULT_BROWSER_TYPE;

        // If we have no identification sequence, just return the default type
        if (empty($this->_config['identification_sequence'])) {
            return $type;
        }

        // Get sequence against which to match
        $sequence = explode(',', $this->_config['identification_sequence']);

        // If a browser type is already configured, push that to the front of the list
        if (null !== ($browserType = $this->getBrowserType())) {
            array_unshift($sequence, $browserType);
        }

        // Append the default browser type to the list if not alread in the list
        if (!in_array($type, $sequence)) {
            $sequence[] = $type;
        }

        // Test each type until we find a match
        foreach ($sequence as $browserType) {
            $browserType = trim($browserType);
            $className   = $this->_getUserAgentDevice($browserType);

            // Attempt to match this device class
            if ($this->_match($className)) {
                $type = $browserType;
                $this->_browserTypeClass[$type] = $className;
                break;
            }
        }

        return $type;
    }

    /**
     * Creates device object instance
     *
     * @return void
     */
    protected function _createDevice()
    {
        $browserType = $this->getBrowserType();
        $classname   = $this->_getUserAgentDevice($browserType);
        $this->_device = new $classname($this->getUserAgent(), $this->getServer(), $this->getConfig());
    }
}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.