@@ -69,14 +69,23 @@ public function __construct($base)
6969 public function add ($ line )
7070 {
7171 $ array = preg_split ('/\s+/ ' , $ line , 2 );
72+ $ parts = array_map ('trim ' , explode ('/ ' , $ array [0 ]));
73+ if (count ($ parts ) != 2 ) {
74+ return false ;
75+ }
76+ $ unit = strtolower (substr (preg_replace ('/[^A-Za-z]/ ' , '' , filter_var ($ parts [1 ], FILTER_SANITIZE_STRING )), 0 , 1 ));
77+ $ multiplier = isset ($ this ->units [$ unit ]) ? $ this ->units [$ unit ] : 1 ;
78+
79+ $ rate = (int )abs (filter_var ($ parts [0 ], FILTER_SANITIZE_NUMBER_INT ));
80+ $ time = $ multiplier * (int )abs (filter_var ($ parts [1 ], FILTER_SANITIZE_NUMBER_INT ));
81+
7282 $ result = [
73- 'rate ' => $ this ->draftParseRate ($ array [0 ]),
83+ 'rate ' => $ time / $ rate ,
84+ 'ratio ' => $ this ->getRatio ($ rate , $ time ),
7485 'from ' => null ,
7586 'to ' => null ,
7687 ];
77- if ($ result ['rate ' ] === false ) {
78- return false ;
79- } elseif (!empty ($ array [1 ]) &&
88+ if (!empty ($ array [1 ]) &&
8089 ($ times = $ this ->draftParseTime ($ array [1 ])) !== false
8190 ) {
8291 $ result = array_merge ($ result , $ times );
@@ -86,23 +95,44 @@ public function add($line)
8695 }
8796
8897 /**
89- * Client rate as specified in the `Robot exclusion standard` version 2.0 draft
90- * rate = numDocuments / timeUnit
91- * @link http://www.conman.org/people/spc/robots2.html#format.directives.request-rate
98+ * Get ratio string
9299 *
93- * @param string $string
94- * @return float|int|false
100+ * @param int $rate
101+ * @param int $time
102+ * @return string
95103 */
96- private function draftParseRate ( $ string )
104+ private function getRatio ( $ rate , $ time )
97105 {
98- $ parts = array_map ('trim ' , explode ('/ ' , $ string ));
99- if (count ($ parts ) != 2 ) {
100- return false ;
106+ $ gcd = $ this ->getGCD ($ rate , $ time );
107+ $ requests = $ rate / $ gcd ;
108+ $ time = $ time / $ gcd ;
109+ $ suffix = 's ' ;
110+ foreach ($ this ->units as $ unit => $ sec ) {
111+ if ($ time % $ sec === 0 ) {
112+ $ suffix = $ unit ;
113+ $ time /= $ sec ;
114+ break ;
115+ }
101116 }
102- $ unit = strtolower (substr (preg_replace ('/[^A-Za-z]/ ' , '' , filter_var ($ parts [1 ], FILTER_SANITIZE_STRING )), 0 , 1 ));
103- $ multiplier = isset ($ this ->units [$ unit ]) ? $ this ->units [$ unit ] : 1 ;
104- $ rate = abs (filter_var ($ parts [1 ], FILTER_SANITIZE_NUMBER_FLOAT , FILTER_FLAG_ALLOW_FRACTION )) * $ multiplier / abs (filter_var ($ parts [0 ], FILTER_SANITIZE_NUMBER_INT ));
105- return $ rate > 0 ? $ rate : false ;
117+ return $ requests . '/ ' . $ time . $ suffix ;
118+ }
119+
120+ /**
121+ * Returns the greatest common divisor of two integers using the Euclidean algorithm.
122+ *
123+ * @param int $a
124+ * @param int $b
125+ * @return int
126+ */
127+ private function getGCD ($ a , $ b )
128+ {
129+ if (extension_loaded ('gmp ' )) {
130+ return gmp_intval (gmp_gcd ((string )$ a , (string )$ b ));
131+ }
132+ $ large = $ a > $ b ? $ a : $ b ;
133+ $ small = $ a > $ b ? $ b : $ a ;
134+ $ remainder = $ large % $ small ;
135+ return 0 === $ remainder ? $ small : $ this ->getGCD ($ small , $ remainder );
106136 }
107137
108138 /**
@@ -145,58 +175,14 @@ public function render(RenderHandler $handler)
145175 {
146176 $ this ->sort ();
147177 foreach ($ this ->requestRates as $ array ) {
148- $ multiplyFactor = $ this ->decimalMultiplier ($ array ['rate ' ]);
149- $ multipliedRate = $ array ['rate ' ] * $ multiplyFactor ;
150- $ gcd = $ this ->getGCD ($ multiplyFactor , $ multipliedRate );
151- $ requests = $ multiplyFactor / $ gcd ;
152- $ time = $ multipliedRate / $ gcd ;
153- $ suffix = 's ' ;
154- foreach ($ this ->units as $ unit => $ sec ) {
155- if ($ time % $ sec === 0 ) {
156- $ suffix = $ unit ;
157- $ time /= $ sec ;
158- break ;
159- }
160- }
178+ $ time = '' ;
161179 if (isset ($ array ['from ' ]) &&
162180 isset ($ array ['to ' ])
163181 ) {
164- $ suffix .= ' ' . $ array ['from ' ] . '- ' . $ array ['to ' ];
182+ $ time .= ' ' . $ array ['from ' ] . '- ' . $ array ['to ' ];
165183 }
166- $ handler ->add (self ::DIRECTIVE_REQUEST_RATE , $ requests . ' / ' . $ time . $ suffix );
184+ $ handler ->add (self ::DIRECTIVE_REQUEST_RATE , $ array [ ' ratio ' ] . $ time );
167185 }
168186 return true ;
169187 }
170-
171- /**
172- * @param int|float $value
173- * @return int
174- */
175- private function decimalMultiplier ($ value )
176- {
177- $ multiplier = 1 ;
178- while (fmod ($ value , 1 ) != 0 ) {
179- $ value *= 10 ;
180- $ multiplier *= 10 ;
181- }
182- return $ multiplier ;
183- }
184-
185- /**
186- * Returns the greatest common divisor of two integers using the Euclidean algorithm.
187- *
188- * @param int $a
189- * @param int $b
190- * @return int
191- */
192- private function getGCD ($ a , $ b )
193- {
194- if (extension_loaded ('gmp ' )) {
195- return gmp_intval (gmp_gcd ((string )$ a , (string )$ b ));
196- }
197- $ large = $ a > $ b ? $ a : $ b ;
198- $ small = $ a > $ b ? $ b : $ a ;
199- $ remainder = $ large % $ small ;
200- return 0 === $ remainder ? $ small : $ this ->getGCD ($ small , $ remainder );
201- }
202188}
0 commit comments