We want to enable customers of an online shop implemented with Magento 2 to log in using a username (in addition to the regular login with an email address). There was already a nice extension for Magento 1 called "Diglin Username". It is currently in beta for Magento 2, but can be used quite effectively. Here we show you how:
Step 1)
Download the source files from [https://github.com/diglin/Diglin_Username2](https://github.com/diglin/Diglin_Username2) and copy them to
app/code/Diglin/Username/
Step 2)
In the console:
bin/magento module\:enable Diglin\_Username\
and
bin/magento setup\:upgrade\
Step 3)
If no error message appears in the customer management area or in the frontend when registering a new customer, etc.: Done.
If the following error message appears:
Exception #0 (InvalidArgumentException): Unable to unserialize value.\
Not done yet. We resolve this issue by adding the following line to the file
app/etc/di.xml\
which reads:
<preference for="Magento\Framework\Serialize\Serializer\Json" type="Diglin\Username\Serialize\Serializer\Json" />\
which gives us the option of modifying the affected functions. This is done by adding the following file:
app\code\Diglin\Username\Serialize\Serializer\Json.php\
which we create for this purpose with the following content:
<?php\
namespace Diglin\Username\Serialize\Serializer;\
class Json extends \Magento\Framework\Serialize\Serializer\Json\
{\
public function unserialize($string)\
{\
if($this->is\_serialized($string))\
{\
$string = $this->serialize($string);\
}\
$result = json\_decode($string, true);\
if (json\_last\_error() !== JSON\_ERROR\_NONE) {\
throw new \InvalidArgumentException('Unable to unserialize value.');\
}\
return $result;\
}\
function is\_serialized($value, &$result = null)\
{\
// Bit of a give away this one\
if (!is\_string($value))\
{\
return false;\
}\
// Serialized false, return true. unserialize() returns false on an\
// invalid string or it could return false if the string is serialized\
// false, eliminate that possibility.\
if ($value === 'b:0;')\
{\
$result = false;\
return true;\
}\
$length = strlen($value);\
$end = '';\
switch ($value[0])\
{\
case 's':\
if ($value[$length - 2] !== '"')\
{\
return false;\
}\
case 'b':\
case 'i':\
case 'd':\
// This looks odd but it is quicker than isset()ing\
$end .= ';';\
case 'a':\
case 'O':\
$end .= '}';\
if ($value[1] !== ':')\
{\
return false;\
}\
switch ($value[2])\
{\
case 0:\
case 1:\
case 2:\
case 3:\
case 4:\
case 5:\
case 6:\
case 7:\
case 8:\
case 9:\
break;\
default:\
return false;\
}\
case 'N':\
$end .= ';';\
if ($value[$length - 1] !== $end[0])\
{\
return false;\
}\
break;\
default:\
return false;\
}\
if (($result = @unserialize($value)) === false)\
{\
$result = null;\
return false;\
}\
return true;\
}\
}\
This makes everything work perfectly. Seen at [https://magento.stackexchange.com/questions/194010/magento-2-2-unable-to-unserialize-value](https://magento.stackexchange.com/questions/194010/magento-2-2-unable-to-unserialize-value). Tested with Magento CE 2.2.5.
