mirror of
				https://github.com/BookStackApp/BookStack.git
				synced 2025-11-03 02:13:16 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			82 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace BookStack\Actions;
 | 
						|
 | 
						|
class IpFormatter
 | 
						|
{
 | 
						|
    protected string $ip;
 | 
						|
    protected int $precision;
 | 
						|
 | 
						|
    public function __construct(string $ip, int $precision)
 | 
						|
    {
 | 
						|
        $this->ip = trim($ip);
 | 
						|
        $this->precision = max(0, min($precision, 4));
 | 
						|
    }
 | 
						|
 | 
						|
    public function format(): string
 | 
						|
    {
 | 
						|
        if (empty($this->ip) || $this->precision === 4) {
 | 
						|
            return $this->ip;
 | 
						|
        }
 | 
						|
 | 
						|
        return $this->isIpv6() ? $this->maskIpv6() : $this->maskIpv4();
 | 
						|
    }
 | 
						|
 | 
						|
    protected function maskIpv4(): string
 | 
						|
    {
 | 
						|
        $exploded = $this->explodeAndExpandIp('.', 4);
 | 
						|
        $maskGroupCount = min(4 - $this->precision, count($exploded));
 | 
						|
 | 
						|
        for ($i = 0; $i < $maskGroupCount; $i++) {
 | 
						|
            $exploded[3 - $i] = 'x';
 | 
						|
        }
 | 
						|
 | 
						|
        return implode('.', $exploded);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function maskIpv6(): string
 | 
						|
    {
 | 
						|
        $exploded = $this->explodeAndExpandIp(':', 8);
 | 
						|
        $maskGroupCount = min(8 - ($this->precision * 2), count($exploded));
 | 
						|
 | 
						|
        for ($i = 0; $i < $maskGroupCount; $i++) {
 | 
						|
            $exploded[7 - $i] = 'x';
 | 
						|
        }
 | 
						|
 | 
						|
        return implode(':', $exploded);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function isIpv6(): bool
 | 
						|
    {
 | 
						|
        return strpos($this->ip, ':') !== false;
 | 
						|
    }
 | 
						|
 | 
						|
    protected function explodeAndExpandIp(string $separator, int $targetLength): array
 | 
						|
    {
 | 
						|
        $exploded = explode($separator, $this->ip);
 | 
						|
 | 
						|
        while (count($exploded) < $targetLength) {
 | 
						|
            $emptyIndex = array_search('', $exploded) ?: count($exploded) - 1;
 | 
						|
            array_splice($exploded, $emptyIndex, 0, '0');
 | 
						|
        }
 | 
						|
 | 
						|
        $emptyIndex = array_search('', $exploded);
 | 
						|
        if ($emptyIndex !== false) {
 | 
						|
            $exploded[$emptyIndex] = '0';
 | 
						|
        }
 | 
						|
 | 
						|
        return $exploded;
 | 
						|
    }
 | 
						|
 | 
						|
    public static function fromCurrentRequest(): self
 | 
						|
    {
 | 
						|
        $ip = request()->ip() ?? '';
 | 
						|
 | 
						|
        if (config('app.env') === 'demo') {
 | 
						|
            $ip = '127.0.0.1';
 | 
						|
        }
 | 
						|
 | 
						|
        return new self($ip, config('app.ip_address_precision'));
 | 
						|
    }
 | 
						|
}
 |