Files
michaelschiemer/src/Application/Analytics/ValueObject/BrowserBreakdown.php
Michael Schiemer 5050c7d73a docs: consolidate documentation into organized structure
- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
2025-10-05 11:05:04 +02:00

106 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Application\Analytics\ValueObject;
use App\Framework\Core\ValueObjects\Percentage;
use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\FrameworkException;
/**
* Browser usage breakdown for analytics reporting
*/
final readonly class BrowserBreakdown
{
public function __construct(
public int $chrome,
public int $firefox,
public int $safari,
public int $edge,
) {
if ($chrome < 0 || $firefox < 0 || $safari < 0 || $edge < 0) {
throw FrameworkException::create(
ErrorCode::VAL_BUSINESS_RULE_VIOLATION,
'Browser counts cannot be negative'
)->withData([
'chrome' => $chrome,
'firefox' => $firefox,
'safari' => $safari,
'edge' => $edge,
]);
}
}
/**
* Create from legacy array format: ['Chrome' => 65, 'Firefox' => 20, ...]
* @param array<string, int> $data
*/
public static function fromArray(array $data): self
{
return new self(
chrome: $data['Chrome'] ?? 0,
firefox: $data['Firefox'] ?? 0,
safari: $data['Safari'] ?? 0,
edge: $data['Edge'] ?? 0,
);
}
public function getTotal(): int
{
return $this->chrome + $this->firefox + $this->safari + $this->edge;
}
public function getChromePercentage(): Percentage
{
return Percentage::fromRatio($this->chrome, $this->getTotal());
}
public function getFirefoxPercentage(): Percentage
{
return Percentage::fromRatio($this->firefox, $this->getTotal());
}
public function getSafariPercentage(): Percentage
{
return Percentage::fromRatio($this->safari, $this->getTotal());
}
public function getEdgePercentage(): Percentage
{
return Percentage::fromRatio($this->edge, $this->getTotal());
}
/**
* @return array<string, int>
*/
public function toArray(): array
{
return [
'Chrome' => $this->chrome,
'Firefox' => $this->firefox,
'Safari' => $this->safari,
'Edge' => $this->edge,
];
}
/**
* Legacy format for backward compatibility
* @return array<string, mixed>
*/
public function toAnalyticsArray(): array
{
return [
'Chrome' => $this->chrome,
'Firefox' => $this->firefox,
'Safari' => $this->safari,
'Edge' => $this->edge,
'chrome_percentage' => $this->getChromePercentage()->format(),
'firefox_percentage' => $this->getFirefoxPercentage()->format(),
'safari_percentage' => $this->getSafariPercentage()->format(),
'edge_percentage' => $this->getEdgePercentage()->format(),
'total' => $this->getTotal(),
];
}
}