GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

TextStatistics::fleschKincaidGradeLevel()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 28

Duplication

Lines 28
Ratio 100 %

Code Coverage

Tests 12
CRAP Score 2.0116

Importance

Changes 0
Metric Value
dl 28
loc 28
ccs 12
cts 14
cp 0.8571
rs 9.472
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.0116
1
<?php
2
3
namespace DaveChild\TextStatistics;
4
5
/*
6
7
    TextStatistics Project
8
    https://github.com/DaveChild/Text-Statistics
9
10
    Released under New BSD license
11
    http://www.opensource.org/licenses/bsd-license.php
12
13
    Calculates following readability scores (formulae can be found in Wikipedia):
14
      * Flesch Kincaid Reading Ease
15
      * Flesch Kincaid Grade Level
16
      * Gunning Fog Score
17
      * Coleman Liau Index
18
      * SMOG Index
19
      * Automated Reability Index
20
      * Dale-Chall Readability Score
21
      * Spache Readability Score
22
23
    Will also give:
24
      * String length
25
      * Letter count
26
      * Syllable count
27
      * Sentence count
28
      * Average words per sentence
29
      * Average syllables per word
30
31
    Sample Code
32
    ----------------
33
    $statistics = new DaveChild\TextStatistics\TextStatistics;
34
    $text = 'The quick brown fox jumped over the lazy dog.';
35
    echo 'Flesch-Kincaid Reading Ease: ' . $statistics->flesch_kincaid_reading_ease($text);
36
37
*/
38
39
class TextStatistics
40
{
41
    /**
42
     * @var string $strEncoding Used to hold character encoding to be used
43
     * by object, if set
44
     */
45
    protected $strEncoding = '';
46
    
47
    /**
48
     * @var Maximum grade level to be reported. Calculated grades above 
49
     * this level will be returned as this value.
50
     */
51
    protected $maxGradeLevel = 12;
52
53
    /**
54
     * @var bool $normalise Should the result be normalised?
55
     */
56
    public $normalise = true;
57
58
    /**
59
     * @var int $dps How many decimal places should results be given to?
60
     */
61
    public $dps = 1;
62
63
    /**
64
     * @var string $strText Holds the last text checked. If no text passed to
65
     * function, it will use this text instead.
66
     */
67
    private static $strText = false;
68
69 44
    /**
70
     * Constructor.
71 44
     *
72
     * @param  string  $strEncoding Optional character encoding.
73
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
74
     */
75 44
    public function __construct($strEncoding = '')
76
    {
77
        if ($strEncoding != '') {
78
            // Encoding is given. Use it!
79
            $this->strEncoding = $strEncoding;
80
        }
81
    }
82 38
83
    /**
84
     * Set the text to measure the readability of.
85
     * @param   string|boolean  $strText         Text to be checked
86 38
     * @return  string                   Cleaned text
87 38
     */
88 38
    public function setText($strText)
89
    {
90 38
91
        // If text passed in, clean it up and store it for subsequent queries
92
        if ($strText !== false) {
93
            self::$strText = Text::cleanText($strText);
94
        }
95
96
        return self::$strText;
97
    }
98
99
    /**
100
     * Set the encoding of the text being measured.
101
     * @param   string  $strEncoding New encoding
102
     * @return  boolean
103
     */
104
    public function setEncoding($strEncoding)
105
    {
106
        $this->strEncoding = $strEncoding;
107
        return true;
108
    }
109 3
    
110
    /**
111 3
     * Set the maximum grade level for grade-level type indexes
112
     * (Flesch-Kincaid Grade Level, Gunning-Fog, Coleman-Liau, SMOG, Automated Readability)
113 3
     * @param	integer	$maxGradeLevel	Grade level to use
114 3
     * @return	boolean	Success
115 3
     */
116 3
    public function setMaxGradeLevel($maxGradeLevel)
117 3
    {
118 3
        $maxGradeLevel = (integer) $maxGradeLevel;
119 3
        if( $maxGradeLevel )
120 3
        {
121 3
        	$this->maxGradeLevel = $maxGradeLevel;
0 ignored issues
show
Documentation Bug introduced by
It seems like $maxGradeLevel of type integer is incompatible with the declared type object<DaveChild\TextStatistics\Maximum> of property $maxGradeLevel.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
122 3
        	return true;
123 3
        }
124 3
        return false;
125 3
    }
126 3
127 3
    /**
128 3
     * Gives the Flesch-Kincaid Reading Ease of text entered rounded to one digit
129 3
     * @param   boolean|string  $strText         Text to be checked
130
     * @return  int|float
131 3
     */
132 View Code Duplication
    public function fleschKincaidReadingEase($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
133
    {
134 3
        $strText = $this->setText($strText);
135
136
        $score = Maths::bcCalc(
137
            Maths::bcCalc(
138
                206.835,
139
                '-',
140
                Maths::bcCalc(
141
                    1.015,
142
                    '*',
143 3
                    Text::averageWordsPerSentence($strText, $this->strEncoding)
144
                )
145 3
            ),
146
            '-',
147 3
            Maths::bcCalc(
148 3
                84.6,
149 3
                '*',
150 3
                Syllables::averageSyllablesPerWord($strText, $this->strEncoding)
151 3
            )
152 3
        );
153 3
154 3
        if ($this->normalise) {
155 3
            return Maths::normaliseScore($score, 0, 100, $this->dps);
156 3
        } else {
157 3
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
158 3
        }
159 3
    }
160 3
161
    /**
162 3
     * Gives the Flesch-Kincaid Grade level of text entered rounded to one digit
163 3
     * @param   boolean|string  $strText         Text to be checked
164
     * @return  int|float
165 3
     */
166 View Code Duplication
    public function fleschKincaidGradeLevel($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
167
    {
168 3
        $strText = $this->setText($strText);
169
170
        $score = Maths::bcCalc(
171
            Maths::bcCalc(
172
                0.39,
173
                '*',
174
                Text::averageWordsPerSentence($strText, $this->strEncoding)
175
            ),
176
            '+',
177 3
            Maths::bcCalc(
178
                Maths::bcCalc(
179 3
                    11.8,
180
                    '*',
181 3
                    Syllables::averageSyllablesPerWord($strText, $this->strEncoding)
182 3
                ),
183 3
                '-',
184 3
                15.59
185 3
            )
186 3
        );
187 3
188
        if ($this->normalise) {
189 3
            return Maths::normaliseScore($score, 0, $this->maxGradeLevel, $this->dps);
190
        } else {
191 3
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
192
        }
193
    }
194 3
195
    /**
196
     * Gives the Gunning-Fog score of text entered rounded to one digit
197
     * @param   boolean|string  $strText         Text to be checked
198
     * @return  int|float
199
     */
200
    public function gunningFogScore($strText = false)
201
    {
202
        $strText = $this->setText($strText);
203 3
204
        $score = Maths::bcCalc(
205 3
            Maths::bcCalc(
206
                Text::averageWordsPerSentence($strText, $this->strEncoding),
207 3
                '+',
208 3
                Syllables::percentageWordsWithThreeSyllables($strText, false, $this->strEncoding)
209 3
            ),
210 3
            '*',
211 3
            '0.4'
212 3
        );
213 3
214 3
        if ($this->normalise) {
215 3
            return Maths::normaliseScore($score, 0, 19, $this->dps);
216 3
        } else {
217 3
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
218 3
        }
219 3
    }
220 3
221 3
    /**
222 3
     * Gives the Coleman-Liau Index of text entered rounded to one digit
223 3
     * @param   boolean|string  $strText         Text to be checked
224 3
     * @return  int|float
225 3
     */
226 3 View Code Duplication
    public function colemanLiauIndex($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
227 3
    {
228 3
        $strText = $this->setText($strText);
229 3
230
        $score = Maths::bcCalc(
231 3
            Maths::bcCalc(
232
                Maths::bcCalc(
233 3
                    5.89,
234
                    '*',
235
                    Maths::bcCalc(
236 3
                        Text::letterCount($strText, $this->strEncoding),
237
                        '/',
238
                        Text::wordCount($strText, $this->strEncoding)
239
                    )
240
                ),
241
                '-',
242
                Maths::bcCalc(
243
                    0.3,
244
                    '*',
245 3
                    Maths::bcCalc(
246
                        Text::sentenceCount($strText, $this->strEncoding),
247 3
                        '/',
248
                        Text::wordCount($strText, $this->strEncoding)
249 3
                    )
250 3
                )
251 3
            ),
252 3
            '-',
253 3
            15.8
254 3
        );
255 3
256 3
        if ($this->normalise) {
257 3
            return Maths::normaliseScore($score, 0, $this->maxGradeLevel, $this->dps);
258 3
        } else {
259 3
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
260 3
        }
261 3
    }
262 3
263 3
    /**
264
     * Gives the SMOG Index of text entered rounded to one digit
265 3
     * @param   boolean|string  $strText         Text to be checked
266 3
     * @return  int|float
267
     */
268 3 View Code Duplication
    public function smogIndex($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269 3
    {
270
        $strText = $this->setText($strText);
271 3
272
        $score = Maths::bcCalc(
273
            1.043,
274 3
            '*',
275
            Maths::bcCalc(
276
                Maths::bcCalc(
277
                    Maths::bcCalc(
278
                        Syllables::wordsWithThreeSyllables($strText, true, $this->strEncoding),
279
                        '*',
280
                        Maths::bcCalc(
281
                            30,
282
                            '/',
283 3
                            Text::sentenceCount($strText, $this->strEncoding)
284
                        )
285 3
                    ),
286
                    'sqrt',
287 3
                    0
288 3
                ),
289 3
                '+',
290 3
                3.1291
291 3
            )
292 3
        );
293 3
294 3
        if ($this->normalise) {
295 3
            return Maths::normaliseScore($score, 0, $this->maxGradeLevel, $this->dps);
296 3
        } else {
297 3
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
298 3
        }
299 3
    }
300 3
301 3
    /**
302 3
     * Gives the Automated Readability Index of text entered rounded to one digit
303 3
     * @param   boolean|string  $strText         Text to be checked
304 3
     * @return  int|float
305 3
     */
306 3 View Code Duplication
    public function automatedReadabilityIndex($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
307 3
    {
308 3
        $strText = $this->setText($strText);
309
310 3
        $score = Maths::bcCalc(
311 3
            Maths::bcCalc(
312
                4.71,
313 3
                '*',
314
                Maths::bcCalc(
315
                    Text::letterCount($strText, $this->strEncoding),
316 3
                    '/',
317
                    Text::wordCount($strText, $this->strEncoding)
318
                )
319
            ),
320
            '+',
321
            Maths::bcCalc(
322
                Maths::bcCalc(
323
                    0.5,
324
                    '*',
325
                    Maths::bcCalc(
326
                        Text::wordCount($strText, $this->strEncoding),
327
                        '/',
328
                        Text::sentenceCount($strText, $this->strEncoding)
329
                    )
330
                ),
331
                '-',
332
                21.43
333
            )
334
        );
335
336
        if ($this->normalise) {
337
            return Maths::normaliseScore($score, 0, $this->maxGradeLevel, $this->dps);
338
        } else {
339
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
340
        }
341
    }
342
343
    /**
344
     * Gives the Dale-Chall readability score of text entered rounded to one digit
345
     * @param   boolean|string  $strText         Text to be checked
346
     * @return  int|float
347
     */
348 View Code Duplication
    public function daleChallReadabilityScore($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
349
    {
350
        $strText = $this->setText($strText);
351
352
        $score = Maths::bcCalc(
353
            Maths::bcCalc(
354
                0.1579,
355
                '*',
356
                Maths::bcCalc(
357
                    100,
358
                    '*',
359
                    Maths::bcCalc(
360
                        $this->daleChallDifficultWordCount($strText),
361
                        '/',
362
                        Text::wordCount($strText, $this->strEncoding)
363
                    )
364
                )
365
            ),
366
            '+',
367
            Maths::bcCalc(
368
                0.0496,
369
                '*',
370
                Maths::bcCalc(
371
                    Text::wordCount($strText, $this->strEncoding),
372
                    '/',
373
                    Text::sentenceCount($strText, $this->strEncoding)
374
                )
375
            )
376
        );
377
378
        if ($this->normalise) {
379
            return Maths::normaliseScore($score, 0, 10, $this->dps);
380
        } else {
381
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
382
        }
383
    }
384
385
    /**
386
     * Gives the Spache readability score of text entered rounded to one digit
387
     * @param   boolean|string  $strText         Text to be checked
388
     * @return  int|float
389
     */
390 View Code Duplication
    public function spacheReadabilityScore($strText = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
391
    {
392
        $strText = $this->setText($strText);
393
394
        $score = Maths::bcCalc(
395
            Maths::bcCalc(
396
                Maths::bcCalc(
397
                    0.121,
398
                    '*',
399
                    Maths::bcCalc(
400
                        Text::wordCount($strText, $this->strEncoding),
401
                        '/',
402
                        Text::sentenceCount($strText, $this->strEncoding)
403
                    )
404
                ),
405
                '+',
406
                Maths::bcCalc(
407
                    0.082,
408
                    '*',
409
                    $this->spacheDifficultWordCount($strText)
410
                )
411
            ),
412
            '+',
413
            0.659
414
        );
415
416
        if ($this->normalise) {
417
            return Maths::normaliseScore($score, 0, 5, $this->dps); // Not really suitable for measuring readability above grade 4
418
        } else {
419
            return Maths::bcCalc($score, '+', 0, true, $this->dps);
420
        }
421
    }
422
423
    /**
424
     * Returns the number of words NOT on the Dale-Chall easy word list
425
     * @param   boolean|string  $strText                  Text to be measured
426
     * @return  int
427
     */
428
    public function daleChallDifficultWordCount($strText = false)
429
    {
430
        $strText = $this->setText($strText);
431
        $intDifficultWords = 0;
432
        $arrWords = explode(' ', Text::lowerCase(preg_replace('`[^A-za-z\' ]`', '', $strText), $this->strEncoding));
433
434
        // Fetch Dale-Chall Words
435
        $arrDaleChall = Resource::fetchDaleChallWordList();
436
437
        for ($i = 0, $intWordCount = count($arrWords); $i < $intWordCount; $i++) {
438
            // Single letters are counted as easy
439
            if (strlen(trim($arrWords[$i])) < 2) {
440
                continue;
441
            }
442
            if ((!in_array(Pluralise::getPlural($arrWords[$i]), $arrDaleChall)) && (!in_array(Pluralise::getSingular($arrWords[$i]), $arrDaleChall))) {
443
                $intDifficultWords++;
444
            }
445
        }
446
447
        return $intDifficultWords;
448
    }
449
450
    /**
451
     * Returns the number of unique words NOT on the Spache easy word list
452
     * @param   boolean|string  $strText                  Text to be measured
453
     * @return  int
454
     */
455
    public function spacheDifficultWordCount($strText = false)
456
    {
457
        $strText = $this->setText($strText);
458
        $intDifficultWords = 0;
459
        $arrWords = explode(' ', strtolower(preg_replace('`[^A-za-z\' ]`', '', $strText)));
460
        // Fetch Spache Words
461
        $wordsCounted = array();
462
463
        // Get the Spache word list
464
        $arrSpache = Resource::fetchSpacheWordList();
465 4
466
        for ($i = 0, $intWordCount = count($arrWords); $i < $intWordCount; $i++) {
467 4
            // Single letters are counted as easy
468
            if (strlen(trim($arrWords[$i])) < 2) {
469 4
                continue;
470
            }
471
            $singularWord = Pluralise::getSingular($arrWords[$i]);
472
            if ((!in_array(Pluralise::getPlural($arrWords[$i]), $arrSpache)) && (!in_array($singularWord, $arrSpache))) {
473
                if (!in_array($singularWord, $wordsCounted)) {
474
                    $intDifficultWords++;
475
                    $wordsCounted[] = $singularWord;
476
                }
477 3
            }
478
        }
479 3
480
        return $intDifficultWords;
481 3
    }
482
483
    /**
484
     * Returns letter count for text.
485
     * @param   boolean|string  $strText      Text to be measured
486
     * @return  int
487
     */
488
    public function letterCount($strText = false)
489 3
    {
490
        $strText = $this->setText($strText);
491 3
492
        return Text::letterCount($strText, $this->strEncoding);
493 3
    }
494
495
    /**
496
     * Returns sentence count for text.
497
     * @param   boolean|string  $strText      Text to be measured
498
     * @return  int
499
     */
500
    public function sentenceCount($strText = false)
501 1
    {
502
        $strText = $this->setText($strText);
503 1
504
        return Text::sentenceCount($strText, $this->strEncoding);
505 1
    }
506
507
    /**
508
     * Returns word count for text.
509
     * @param   boolean|string  $strText      Text to be measured
510
     * @return  int
511
     */
512
    public function wordCount($strText = false)
513 5
    {
514
        $strText = $this->setText($strText);
515 5
516
        return Text::wordCount($strText, $this->strEncoding);
517 5
    }
518
519
    /**
520
     * Returns average words per sentence for text.
521
     * @param   boolean|string  $strText      Text to be measured
522
     * @return  int|float
523
     */
524
    public function averageWordsPerSentence($strText = false)
525 1
    {
526
        $strText = $this->setText($strText);
527 1
528
        return Text::averageWordsPerSentence($strText, $this->strEncoding);
529 1
    }
530
531
    /**
532
     * Returns number of syllables in a word
533
     * @param   boolean|string  $strText      Text to be measured
534
     * @return  int
535
     */
536
    public function syllableCount($strText = false)
537 1
    {
538
        $strText = $this->setText($strText);
539 1
540
        return Syllables::syllableCount($strText, $this->strEncoding);
541 1
    }
542
543
    /**
544
     * Returns total syllable count for text.
545
     * @param   boolean|string  $strText      Text to be measured
546
     * @return  int
547
     */
548
    public function totalSyllables($strText = false)
549
    {
550 1
        $strText = $this->setText($strText);
551
552 1
        return Syllables::totalSyllables($strText, $this->strEncoding);
553
    }
554 1
555
    /**
556
     * Returns average syllables per word for text.
557
     * @param   boolean|string  $strText      Text to be measured
558
     * @return  int|float
559
     */
560
    public function averageSyllablesPerWord($strText = false)
561
    {
562
        $strText = $this->setText($strText);
563 1
564
        return Syllables::averageSyllablesPerWord($strText, $this->strEncoding);
565 1
    }
566
567 1
    /**
568
     * Returns the number of words with more than three syllables
569
     * @param   boolean|string  $strText                  Text to be measured
570
     * @param   bool    $blnCountProperNouns      Boolean - should proper nouns be included in words count
571
     * @return  int
572
     */
573
    public function wordsWithThreeSyllables($strText = false, $blnCountProperNouns = true)
574 3
    {
575
        $strText = $this->setText($strText);
576 3
577
        return Syllables::wordsWithThreeSyllables($strText, $blnCountProperNouns, $this->strEncoding);
578
    }
579 3
580
    /**
581 3
     * Returns the percentage of words with more than three syllables
582
     * @param   boolean|string  $strText      Text to be measured
583
     * @param   bool    $blnCountProperNouns      Boolean - should proper nouns be included in words count
584 3
     * @return  int|float
585
     */
586 3
    public function percentageWordsWithThreeSyllables($strText = false, $blnCountProperNouns = true)
587
    {
588
        $strText = $this->setText($strText);
589 3
590
        return Syllables::percentageWordsWithThreeSyllables($strText, $blnCountProperNouns, $this->strEncoding);
591 3
    }
592
593
    /**
594 3
     * We switched to camel-case but we'll leave these aliases in for
595
     * convenience for anyone switching from the previous version.
596 3
     */
597
    public function flesch_kincaid_reading_ease($strText = false)
598
    {
599 3
        return $this->fleschKincaidReadingEase($strText);
600
    }
601 3
602
    public function flesch_kincaid_grade_level($strText = false)
603
    {
604
        return $this->fleschKincaidGradeLevel($strText);
605
    }
606
607
    public function gunning_fog_score($strText = false)
608
    {
609
        return $this->gunningFogScore($strText);
610
    }
611
612
    public function coleman_liau_index($strText = false)
613
    {
614
        return $this->colemanLiauIndex($strText);
615
    }
616
617
    public function smog_index($strText = false)
618
    {
619
        return $this->smogIndex($strText);
620
    }
621
622
    public function automated_readability_index($strText = false)
623
    {
624
        return $this->automatedReadabilityIndex($strText);
625
    }
626
627
    public function dale_chall_readability_score($strText = false)
628
    {
629
        return $this->daleChallReadabilityScore($strText);
630
    }
631
632
    public function spache_readability_score($strText = false)
633
    {
634
        return $this->spacheReadabilityScore($strText);
635
    }
636
}
637