Passed
Push — master ( 8fb280...5e82f4 )
by Akpé Aurelle Emmanuel Moïse
31s
created

similar_text::similarButNotEqual()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 4
nc 6
nop 2
1
<?php
2
/**
3
*
4
* @Name : similar-text
5
* @Programmer : Akpé Aurelle Emmanuel Moïse Zinsou
6
* @Date : 2019-04-01
7
* @Released under : https://github.com/manuwhat/similar-text/blob/master/LICENSE
8
* @Repository : https://github.com/manuwhat/similar
9
*
10
**/
11
12
13
namespace EZAMA{
14
        
15
    class similar_text
16
    {
17
        private function __construct()
18
        {
19
        }
20
        public static function similarText($a, $b, $round = 2, $insensitive = true, &$stats = false, $getParts = false, $checkposition = false)
21
        {
22
            if (!is_string($a) || !is_string($b)) {
23
                return false;
24
            }
25
            if ($insensitive) {
26
                $a = self::strtolower($a);
27
                $b = self::strtolower($b);
28
            } else {
29
                $a = self::split($a);
30
                $b = self::split($b);
31
            }
32
            /* prevent bad types and useless memory usage due to for example array instead of simple boolean */
33
            unset($insensitive);
34
            $getParts = (bool) $getParts;
35
            /*  ******************************************************************************************** */
36
            $ca = count($a);
37
            $cb = count($b);
38
            if ($ca < $cb) {
39
                $stats = self::getStats($cb, $a, self::_check($a, $b, $getParts, $round, $checkposition), $getParts, $round);
40
            } else {
41
                $stats = self::getStats($ca, $b, self::_check($b, $a, $getParts, $round, $checkposition), $getParts, $round);
42
            }
43
            return $stats['similar'];
44
        }
45
        
46
        protected static function _check($a, $b, $getParts, $round, $checkposition = false)
47
        {
48
            $diff = array();
49
            if ($getParts) {
50
                $diff[] = array_diff($a, $b);
51
                $diff[] = array_diff($b, $a);
52
            }
53
            $diff[] = $checkposition ?array_intersect_assoc($a, $b) : array_intersect($a, $b);
54
            $diff[] = round(count(array_intersect(self::getParts($a, $c), self::getParts($b))) / $c * 100, $round);
55
            $diff[] = $a === $b;
56
            return $diff;
57
        }
58
        
59
        protected static function getStats($ca, $b, $diff, $getParts, $round)
60
        {
61
            $stats = array();
62
            if ($getParts) {
63
                $stats['similar'] = round(count($diff[2]) * 100 / $ca, $round);
64
                $stats['substr'] = $diff[3];
65
                $stats['contain'] = ($diff[2] === $b) ?true:false;
66
                $stats['equal'] = $diff[4];
67
                $stats['a-b'] = $diff[0];
68
                $stats['b-a'] = $diff[1];
69
                $stats['a&b'] = $diff[2];
70
            } else {
71
                $stats['similar'] = round(count($diff[0]) * 100 / $ca, $round);
72
                $stats['substr'] = $diff[1];
73
                $stats['contain'] = ($diff[0] === $b) ?true:false;
74
                $stats['equal'] = $diff[2];
75
            }
76
            return $stats;
77
        }
78
79
        protected static function getParts($b, &$c = 0)
80
        {
81
            $parts = array();
82
            $tmp = '';
83
            $c = 0;
84
            foreach ($b as $k=>$v) {
85
                if (ctype_space($v) || ctype_punct($v)) {
86
                    $parts[] = $tmp;
87
                    $parts[] = $v;
88
                    $c += 2;
89
                    $tmp = '';
90
                    continue;
91
                }
92
                $tmp .= $v;
93
            }
94
            if (!empty($tmp)) {
95
                $parts[] = $tmp;
96
                $c++;
97
            }
98
            return $parts;
99
        }
100
        
101
        
102
        
103
        protected static function is_ascii($str)
104
        {
105
            if ('' === $str) {
106
                return true;
107
            }
108
109
            return !preg_match('/[^\x09\x10\x13\x0A\x0D\x20-\x7E]/', $str);
110
        }
111
        
112
        protected static function strtolower($str)
113
        {
114
            $split = self::split($str);
115
            if (is_array($split)) {
116
                return
117
                    array_map(
118
                        function($val) {
119
                            if (self::is_ascii($val)) {
120
                                return strtolower($val);
121
                            }
122
                            return $val;
123
                        },
124
                        $split
125
                )
126
        
127
                            ;
128
            } else {
129
                return array();
130
            }
131
        }
132
        
133
        protected static function split($str)
134
        {
135
            if (!is_string($str)) {
136
                return array();
137
            }
138
            static $split = [];
139
            static $old = '';
140
            if ($old === $str) {
141
                return $split;
142
            } else {
143
                $old = $str;
144
                $split = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
145
                return $split;
146
            }
147
        }
148
    }
149
    
150
}
151