# Serializer Module

The Serializer module provides a unified way to serialize and deserialize data in various formats. It supports JSON and PHP serialization with plans to add more formats in the future.

## Features

- Unified interface for all serializers
- Type-safe serialization and deserialization
- Robust error handling
- Configurable serialization options
- Factory methods for common configurations

## Usage

### Basic Usage

```php
use App\Framework\Serializer\SerializerFactory;

// Create a JSON serializer with default settings (pretty print)
$serializer = SerializerFactory::createJsonSerializer();

// Serialize data
$data = ['name' => 'John', 'age' => 30];
$json = $serializer->serialize($data);

// Deserialize data
$deserializedData = $serializer->deserialize($json);
```

### Serialization Options

The module provides several factory methods for common serialization configurations:

```php
// Pretty-printed JSON (default)
$prettySerializer = SerializerFactory::createPrettyJsonSerializer();
$prettyJson = $prettySerializer->serialize($data);
// Result: {
//     "name": "John",
//     "age": 30
// }

// Compact JSON (no whitespace)
$compactSerializer = SerializerFactory::createCompactJsonSerializer();
$compactJson = $compactSerializer->serialize($data);
// Result: {"name":"John","age":30}

// Minimal JSON (no special flags)
$minimalSerializer = SerializerFactory::createMinimalJsonSerializer();
$minimalJson = $minimalSerializer->serialize($data);
// Result: {"name":"John","age":30}
```

### Custom Configuration

You can create a serializer with custom configuration:

```php
// Custom JSON serializer with specific flags
$customSerializer = SerializerFactory::createCustomJsonSerializer(
    JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE,
    256 // Max depth
);

// Serialize an array as an object
$data = ['a', 'b', 'c'];
$json = $customSerializer->serialize($data);
// Result: {"0":"a","1":"b","2":"c"}
```

### Using Config Objects Directly

You can also create and use config objects directly:

```php
use App\Framework\Serializer\Json\JsonSerializer;
use App\Framework\Serializer\Json\JsonSerializerConfig;

// Create a config object
$config = new JsonSerializerConfig(
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES,
    512
);

// Create a serializer with the config
$serializer = new JsonSerializer($config);

// Or use the factory methods on the config class
$compactConfig = JsonSerializerConfig::compact();
$prettyConfig = JsonSerializerConfig::pretty();
$minimalConfig = JsonSerializerConfig::minimal();

// Create serializers with these configs
$compactSerializer = new JsonSerializer($compactConfig);
$prettySerializer = new JsonSerializer($prettyConfig);
$minimalSerializer = new JsonSerializer($minimalConfig);
```

### Exception Handling

The serializer module provides a dedicated exception hierarchy for better error handling:

- `SerializerException`: Base exception for all serializer-related exceptions
  - `SerializeException`: Thrown when serialization fails
  - `DeserializeException`: Thrown when deserialization fails

Example of handling deserialization errors:

```php
use App\Framework\Serializer\SerializerFactory;
use App\Framework\Serializer\Exception\SerializeException;
use App\Framework\Serializer\Exception\DeserializeException;

$serializer = SerializerFactory::createJsonSerializer();

try {
    // Try to deserialize invalid JSON
    $data = $serializer->deserialize('{"name": "John", }'); // Invalid JSON
} catch (DeserializeException $e) {
    // Handle deserialization errors
    echo "Deserialization error: " . $e->getMessage();
} catch (SerializeException $e) {
    // Handle serialization errors
    echo "Serialization error: " . $e->getMessage();
} catch (SerializerException $e) {
    // Handle other serializer-related errors
    echo "Serializer error: " . $e->getMessage();
}
```

### MIME Type and File Extension

The serializer provides methods to get the MIME type and file extension:

```php
$serializer = SerializerFactory::createJsonSerializer();

// Get MIME type
$mimeType = $serializer->getMimeType(); // "application/json"

// Get file extension
$extension = $serializer->getFileExtension(); // "json"
```

## Migration from Legacy Serializers

If you're using the legacy serializers, here's how to migrate:

### From Cache JsonSerializer

```php
// Old code
use App\Framework\Cache\Serializer\JsonSerializer;
$serializer = new JsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->unserialize($json);

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createJsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->deserialize($json);
```

### From Filesystem JsonSerializer

```php
// Old code
use App\Framework\Filesystem\Serializers\JsonSerializer;
$serializer = new JsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->deserialize($json);

// Factory methods
$compactSerializer = JsonSerializer::compact();
$prettySerializer = JsonSerializer::pretty();
$minimalSerializer = JsonSerializer::minimal();

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createJsonSerializer();
$json = $serializer->serialize($data);
$data = $serializer->deserialize($json);

// Factory methods
$compactSerializer = SerializerFactory::createCompactJsonSerializer();
$prettySerializer = SerializerFactory::createPrettyJsonSerializer();
$minimalSerializer = SerializerFactory::createMinimalJsonSerializer();
```

## Direct Usage of JsonSerializer

If you need direct access to the JsonSerializer class:

```php
use App\Framework\Serializer\Json\JsonSerializer;

// Create with default settings
$serializer = new JsonSerializer();

// Create with custom settings
$serializer = new JsonSerializer(
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES,
    512
);

// Use factory methods
$compactSerializer = JsonSerializer::compact();
$prettySerializer = JsonSerializer::pretty();
$minimalSerializer = JsonSerializer::minimal();
```

## PHP Serialization

The module also provides PHP serialization capabilities with a focus on security.

### Basic Usage

```php
use App\Framework\Serializer\SerializerFactory;

// Create a PHP serializer with default settings (safe with no allowed classes)
$serializer = SerializerFactory::createPhpSerializer();

// Serialize data
$data = ['name' => 'John', 'age' => 30];
$serialized = $serializer->serialize($data);

// Deserialize data
$deserializedData = $serializer->deserialize($serialized);
```

### Security Considerations

PHP serialization can be a security risk if used improperly, as it allows arbitrary code execution through object deserialization. The PHP serializer in this module is designed with security in mind:

- By default, no classes are allowed to be unserialized (only primitive types and arrays)
- You can explicitly specify which classes are allowed to be unserialized
- You can create an unsafe serializer if you need to deserialize any class (use with caution)

### Safe and Unsafe Deserialization

```php
use App\Framework\Serializer\SerializerFactory;

// Safe serializer with specific allowed classes
$safeSerializer = SerializerFactory::createSafePhpSerializer(['stdClass', 'DateTime']);

// Unsafe serializer (allows all classes - use with caution)
$unsafeSerializer = SerializerFactory::createUnsafePhpSerializer();
```

### Custom Configuration

You can create a serializer with custom options:

```php
use App\Framework\Serializer\SerializerFactory;

// Custom PHP serializer with specific allowed classes and max depth
$customSerializer = SerializerFactory::createCustomPhpSerializer(
    ['MyClass', 'MyOtherClass'], // allowed classes
    4096 // max depth (optional, defaults to 4096)
);
```

### Using PhpSerializer with Config Objects

You can create and use PHP serializer config objects directly:

```php
use App\Framework\Serializer\Php\PhpSerializer;
use App\Framework\Serializer\Php\PhpSerializerConfig;

// Create with default settings (safe with no allowed classes)
$serializer = new PhpSerializer();

// Create a config object with custom options
$config = new PhpSerializerConfig(
    ['MyClass'], // allowed classes
    4096 // max depth (optional, defaults to 4096)
);

// Create a serializer with the config
$serializer = new PhpSerializer($config);

// Or use the factory methods on the config class
$safeConfig = PhpSerializerConfig::safe(
    ['stdClass'], // allowed classes
    4096 // max depth (optional, defaults to 4096)
);
$unsafeConfig = PhpSerializerConfig::unsafe(
    4096 // max depth (optional, defaults to 4096)
);

// Create serializers with these configs
$safeSerializer = new PhpSerializer($safeConfig);
$unsafeSerializer = new PhpSerializer($unsafeConfig);
```

### Migration from Legacy PHP Serializers

If you're using the legacy PHP serializers, here's how to migrate:

#### From Cache PhpSerializer

```php
// Old code
use App\Framework\Cache\Serializer\PhpSerializer;
$serializer = new PhpSerializer();
$serialized = $serializer->serialize($data);
$data = $serializer->unserialize($serialized);

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createUnsafePhpSerializer(); // For backward compatibility
$serialized = $serializer->serialize($data);
$data = $serializer->deserialize($serialized);
```

#### From Filesystem PhpSerializer

```php
// Old code
use App\Framework\Filesystem\Serializers\PhpSerializer;
$serializer = new PhpSerializer();
$serialized = $serializer->serialize($data);
$data = $serializer->deserialize($data);

// Factory methods
$safeSerializer = PhpSerializer::safe(['stdClass']);
$unsafeSerializer = PhpSerializer::unsafe();

// New code
use App\Framework\Serializer\SerializerFactory;
$serializer = SerializerFactory::createPhpSerializer();
$serialized = $serializer->serialize($data);
$data = $serializer->deserialize($serialized);

// Factory methods
$safeSerializer = SerializerFactory::createSafePhpSerializer(['stdClass']);
$unsafeSerializer = SerializerFactory::createUnsafePhpSerializer();
```
