<?php
namespace CMSMSExt
{
  /**
   * based on https://developer.wordpress.org/reference/functions/is_serialized/
   *
   * @param $data
   * @param $strict
   *
   * @return bool
   */
  function is_serialized($data, $strict = TRUE) : bool
  {
    // If it isn't a string, it isn't serialized.
    if(!\is_string($data)) { return FALSE; }
    
    $data = \trim($data);
    
    if('N;' === $data) { return TRUE; }
    if(\strlen($data) < 4) { return FALSE; }
    if(':' !== $data[1]) { return FALSE; }
    
    if($strict)
    {
      $lastc = \substr($data, -1);
      
      if(';' !== $lastc && '}' !== $lastc) { return FALSE; }
    }
    else
    {
      $semicolon = \strpos($data, ';');
      $brace     = \strpos($data, '}');
      
      // Either ; or } must exist.
      if(FALSE === $semicolon && FALSE === $brace)
      {
        return FALSE;
      }
      // But neither must be in the first X characters.
      if(FALSE !== $semicolon && $semicolon < 3) { return FALSE; }
      
      if(FALSE !== $brace && $brace < 4) { return FALSE; }
    }
    
    $token = $data[0];
    
    switch($token)
    {
      case 's':
        if($strict)
        {
          if('"' !== $data[\strlen($data) - 2]) { return FALSE; }
        }
        else if( FALSE === \strpos($data, '"') )
        {
          return FALSE;
        }
      
      // Or else fall through.
      case 'a':
      case 'O':
        return (bool)\preg_match("/^{$token}:[0-9]+:/s", $data);
      case 'b':
      case 'i':
      case 'd':
        $end = $strict ? '$' : '';
        
        return (bool)\preg_match("/^{$token}:[0-9.E+-]+;$end/", $data);
    }
    
    return FALSE;
  }
}