xref: /dokuwiki/vendor/splitbrain/lesserphp/src/Utils/Util.php (revision e6380ba37d6b3f7dd03146b3c03030ccc8c1b297)
1*e6380ba3SAndreas Gohr<?php
2*e6380ba3SAndreas Gohr
3*e6380ba3SAndreas Gohrnamespace LesserPHP\Utils;
4*e6380ba3SAndreas Gohr
5*e6380ba3SAndreas Gohruse Exception;
6*e6380ba3SAndreas Gohruse LesserPHP\Constants;
7*e6380ba3SAndreas Gohr
8*e6380ba3SAndreas Gohr/**
9*e6380ba3SAndreas Gohr * Miscelaneous utility methods
10*e6380ba3SAndreas Gohr */
11*e6380ba3SAndreas Gohrclass Util
12*e6380ba3SAndreas Gohr{
13*e6380ba3SAndreas Gohr    /**
14*e6380ba3SAndreas Gohr     * Clamps a value between a minimum and maximum value.
15*e6380ba3SAndreas Gohr     *
16*e6380ba3SAndreas Gohr     * This function takes a value and two boundary values (maximum and minimum).
17*e6380ba3SAndreas Gohr     * It ensures that the provided value does not exceed the boundaries.
18*e6380ba3SAndreas Gohr     * If the value is less than the minimum, the minimum is returned.
19*e6380ba3SAndreas Gohr     * If the value is greater than the maximum, the maximum is returned.
20*e6380ba3SAndreas Gohr     * Otherwise, the original value is returned.
21*e6380ba3SAndreas Gohr     */
22*e6380ba3SAndreas Gohr    public static function clamp(float $v, float $max = 1, float $min = 0): float
23*e6380ba3SAndreas Gohr    {
24*e6380ba3SAndreas Gohr        return min($max, max($min, $v));
25*e6380ba3SAndreas Gohr    }
26*e6380ba3SAndreas Gohr
27*e6380ba3SAndreas Gohr    /**
28*e6380ba3SAndreas Gohr     * Quote a string for use in a regular expression
29*e6380ba3SAndreas Gohr     */
30*e6380ba3SAndreas Gohr    public static function pregQuote(string $what): string
31*e6380ba3SAndreas Gohr    {
32*e6380ba3SAndreas Gohr        return preg_quote($what, '/');
33*e6380ba3SAndreas Gohr    }
34*e6380ba3SAndreas Gohr
35*e6380ba3SAndreas Gohr    /**
36*e6380ba3SAndreas Gohr     * Return a boolean type
37*e6380ba3SAndreas Gohr     *
38*e6380ba3SAndreas Gohr     * @param mixed $a
39*e6380ba3SAndreas Gohr     */
40*e6380ba3SAndreas Gohr    public static function toBool($a): array
41*e6380ba3SAndreas Gohr    {
42*e6380ba3SAndreas Gohr        if ($a) return Constants::TRUE;
43*e6380ba3SAndreas Gohr        return Constants::FALSE;
44*e6380ba3SAndreas Gohr    }
45*e6380ba3SAndreas Gohr
46*e6380ba3SAndreas Gohr    /**
47*e6380ba3SAndreas Gohr     * Converts numbers between different types of units
48*e6380ba3SAndreas Gohr     *
49*e6380ba3SAndreas Gohr     * @throws Exception
50*e6380ba3SAndreas Gohr     */
51*e6380ba3SAndreas Gohr    public static function convert($number, $to): array
52*e6380ba3SAndreas Gohr    {
53*e6380ba3SAndreas Gohr        $value = Asserts::assertNumber($number);
54*e6380ba3SAndreas Gohr        $from = $number[2];
55*e6380ba3SAndreas Gohr
56*e6380ba3SAndreas Gohr        // easy out
57*e6380ba3SAndreas Gohr        if ($from == $to)
58*e6380ba3SAndreas Gohr            return $number;
59*e6380ba3SAndreas Gohr
60*e6380ba3SAndreas Gohr        // check if the from value is a length
61*e6380ba3SAndreas Gohr        if (($from_index = array_search($from, Constants::LENGTH_UNITS)) !== false) {
62*e6380ba3SAndreas Gohr            // make sure to value is too
63*e6380ba3SAndreas Gohr            if (in_array($to, Constants::LENGTH_UNITS)) {
64*e6380ba3SAndreas Gohr                // do the actual conversion
65*e6380ba3SAndreas Gohr                $to_index = array_search($to, Constants::LENGTH_UNITS);
66*e6380ba3SAndreas Gohr                $px = $value * Constants::LENGTH_BASES[$from_index];
67*e6380ba3SAndreas Gohr                $result = $px * (1 / Constants::LENGTH_BASES[$to_index]);
68*e6380ba3SAndreas Gohr
69*e6380ba3SAndreas Gohr                $result = round($result, 8);
70*e6380ba3SAndreas Gohr                return ['number', $result, $to];
71*e6380ba3SAndreas Gohr            }
72*e6380ba3SAndreas Gohr        }
73*e6380ba3SAndreas Gohr
74*e6380ba3SAndreas Gohr        // do the same check for times
75*e6380ba3SAndreas Gohr        if (in_array($from, Constants::TIME_UNITS)) {
76*e6380ba3SAndreas Gohr            if (in_array($to, Constants::TIME_UNITS)) {
77*e6380ba3SAndreas Gohr                // currently only ms and s are valid
78*e6380ba3SAndreas Gohr                if ($to == 'ms')
79*e6380ba3SAndreas Gohr                    $result = $value * 1000;
80*e6380ba3SAndreas Gohr                else $result = $value / 1000;
81*e6380ba3SAndreas Gohr
82*e6380ba3SAndreas Gohr                $result = round($result, 8);
83*e6380ba3SAndreas Gohr                return ['number', $result, $to];
84*e6380ba3SAndreas Gohr            }
85*e6380ba3SAndreas Gohr        }
86*e6380ba3SAndreas Gohr
87*e6380ba3SAndreas Gohr        // lastly check for an angle
88*e6380ba3SAndreas Gohr        if (in_array($from, Constants::ANGLE_UNITS)) {
89*e6380ba3SAndreas Gohr            // convert whatever angle it is into degrees
90*e6380ba3SAndreas Gohr            switch ($from) {
91*e6380ba3SAndreas Gohr                case 'rad':
92*e6380ba3SAndreas Gohr                    $deg = rad2deg($value);
93*e6380ba3SAndreas Gohr                    break;
94*e6380ba3SAndreas Gohr                case 'turn':
95*e6380ba3SAndreas Gohr                    $deg = $value * 360;
96*e6380ba3SAndreas Gohr                    break;
97*e6380ba3SAndreas Gohr                case 'grad':
98*e6380ba3SAndreas Gohr                    $deg = $value / (400 / 360);
99*e6380ba3SAndreas Gohr                    break;
100*e6380ba3SAndreas Gohr                default:
101*e6380ba3SAndreas Gohr                    $deg = $value;
102*e6380ba3SAndreas Gohr                    break;
103*e6380ba3SAndreas Gohr            }
104*e6380ba3SAndreas Gohr
105*e6380ba3SAndreas Gohr            // Then convert it from degrees into desired unit
106*e6380ba3SAndreas Gohr            switch ($to) {
107*e6380ba3SAndreas Gohr                case 'rad':
108*e6380ba3SAndreas Gohr                    $result = deg2rad($deg);
109*e6380ba3SAndreas Gohr                    break;
110*e6380ba3SAndreas Gohr                case 'turn':
111*e6380ba3SAndreas Gohr                    $result = $deg / 360;
112*e6380ba3SAndreas Gohr                    break;
113*e6380ba3SAndreas Gohr                case 'grad':
114*e6380ba3SAndreas Gohr                    $result = $deg * (400 / 360);
115*e6380ba3SAndreas Gohr                    break;
116*e6380ba3SAndreas Gohr                default:
117*e6380ba3SAndreas Gohr                    $result = $deg;
118*e6380ba3SAndreas Gohr                    break;
119*e6380ba3SAndreas Gohr            }
120*e6380ba3SAndreas Gohr
121*e6380ba3SAndreas Gohr            $result = round($result, 8);
122*e6380ba3SAndreas Gohr            return ['number', $result, $to];
123*e6380ba3SAndreas Gohr        }
124*e6380ba3SAndreas Gohr
125*e6380ba3SAndreas Gohr        // we don't know how to convert these
126*e6380ba3SAndreas Gohr        throw new Exception("Cannot convert $from to $to");
127*e6380ba3SAndreas Gohr    }
128*e6380ba3SAndreas Gohr}
129