Completed
Push — master ( 5c6970...94a889 )
by Sebastian
02:32
created

Number::evaluateStringPluralism()   C

Complexity

Conditions 9
Paths 6

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 15
nc 6
nop 1
dl 0
loc 24
rs 5.3563
c 0
b 0
f 0
1
<?php
2
/*
3
 * citeproc-php
4
 *
5
 * @link        http://github.com/seboettg/citeproc-php for the source repository
6
 * @copyright   Copyright (c) 2016 Sebastian Böttger.
7
 * @license     https://opensource.org/licenses/MIT
8
 */
9
10
namespace Seboettg\CiteProc\Util;
11
12
/**
13
 * Class Number
14
 * @package Seboettg\CiteProc\Util
15
 *
16
 * @author Sebastian Böttger <[email protected]>
17
 */
18
class Number
19
{
20
21
    const PATTERN_ORDINAL = "/\d+(st|nd|rd|th)?\.?$/";
22
23
    const PATTERN_ROMAN = "/^[ivxlcdm]+\.?$/i";
24
25
    const PATTERN_AFFIXES = "/^[a-z]?\d+[a-z]?$/i";
26
27
    const PATTERN_COMMA_AMPERSAND_RANGE = "/\d*([\s?\-&+,;\s])+\d+/";
28
29
    const ROMAN_NUMERALS = [
30
        ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"],
31
        ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"],
32
        ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"],
33
        ["", "m", "mm", "mmm", "mmmm", "mmmmm"]
34
    ];
35
36
    const ROMAN_DIGITS = [
37
        "M" => 1000,
38
        "D" => 500,
39
        "C" => 100,
40
        "L" => 50,
41
        "X" => 10,
42
        "V" => 5,
43
        "I" => 1
44
    ];
45
46
    /**
47
     * @return \Closure
48
     */
49
    public static function getCompareNumber()
50
    {
51
        return function($numA, $numB, $order) {
52
            if (is_numeric($numA) && is_numeric($numB)) {
53
                $ret = $numA - $numB;
54
            } else {
55
                $ret = strcasecmp($numA, $numB);
56
            }
57
            if ("descending" === $order) {
58
                return $ret > 0 ? -1 : 1;
59
            }
60
            return $ret > 0 ? 1 : -1;
61
        };
62
    }
63
64
    /**
65
     * @param $num
66
     * @return string
67
     */
68
    public static function dec2roman($num)
69
    {
70
        $ret = "";
71
        if ($num < 6000) {
72
73
            $numStr = strrev($num);
74
            $len = strlen($numStr);
75
            for ($pos = 0; $pos < $len; $pos++) {
76
                $n = $numStr[$pos];
77
                $ret = self::ROMAN_NUMERALS[$pos][$n] . $ret;
78
            }
79
        }
80
        return $ret;
81
    }
82
83
    /**
84
     * @param $romanNumber
85
     * @return int|mixed
86
     */
87
    public static function roman2Dec($romanNumber)
88
    {
89
        if (is_numeric($romanNumber)) {
90
            return 0;
91
        }
92
93
        $values = [];
94
        // Convert the string to an array of roman values:
95
        for ($i = 0; $i < strlen($romanNumber); ++$i) {
96
            $char = strtoupper($romanNumber{$i});
97
            if (isset(self::ROMAN_DIGITS[$char])) {
98
                $values[] = self::ROMAN_DIGITS[$char];
99
            }
100
        }
101
102
        $sum = 0;
103
        while ($current = current($values)) {
104
            $next = next($values);
105
            $next > $current ? $sum += $next - $current + 0 * next($values) : $sum += $current;
106
        }
107
108
        // Return the value:
109
        return $sum;
110
    }
111
112
    public static function isRomanNumber($str)
113
    {
114
        for ($i = 0; $i < strlen($str); ++$i) {
115
            $char = strtoupper($str{$i});
116
            if (!in_array($char, array_keys(self::ROMAN_DIGITS))) {
117
                return false;
118
            }
119
        }
120
        return true;
121
    }
122
123
    /**
124
     * @param $str
125
     * @return string
126
     */
127
    public static function evaluateStringPluralism($str)
128
    {
129
        $plural = 'single';
130
        if (!empty($str)) {
131
            $ranges = preg_split("/[-–&,]/", $str);
132
            if (count($ranges) > 1) {
133
134
                $range = 1;
135
                foreach ($ranges as $range) {
136
                    if (Number::isRomanNumber($range) || is_numeric($range)) {
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
137
                        $range &= 1;
138
                    }
139
                }
140
                if ($range == 1) {
141
                    return 'multiple';
142
                }
143
            } else {
144
                if (is_numeric($str)) {
145
                    return $str > 1 ? 'multiple' : 'single';
146
                }
147
            }
148
        }
149
        return $plural;
150
    }
151
}