ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
EstimatedReadingTime.php
Go to the documentation of this file.
1 <?php declare(strict_types=1);
2 /* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 namespace ILIAS\Refinery\String;
5 
9 
11 {
14 
16  private $wordsPerMinute = 275;
17 
20 
22  private $withImages = false;
23 
28  public function __construct(bool $withImages)
29  {
30  $this->withImages = $withImages;
31  }
32 
36  public function transform($from)
37  {
38  if (!is_string($from)) {
39  throw new \InvalidArgumentException(__METHOD__ . " the argument is not a string.");
40  }
41 
42  return $this->calculate($from);
43  }
44 
49  private function calculate(string $text) : int
50  {
51  $text = mb_convert_encoding(
52  '<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>' . $text . '</body></html>',
53  'HTML-ENTITIES',
54  'UTF-8'
55  );
56 
57  $document = new \DOMDocument();
58  if (!@$document->loadHTML($text)) {
59  throw new \InvalidArgumentException(__METHOD__ . " the argument is not a XHTML string.");
60  }
61 
62  $numberOfWords = 0;
63 
64  $xpath = new \DOMXPath($document);
65  $textNodes = $xpath->query('//text()');
66  if ($textNodes->length > 0) {
67  foreach ($textNodes as $textNode) {
69  if ($textNode instanceof \DOMCdataSection) {
70  continue;
71  }
72 
73  $wordsInContent = array_filter(preg_split('/\s+/', $textNode->textContent));
74 
75  $wordsInContent = array_filter($wordsInContent, function (string $word) {
76  return preg_replace('/^\pP$/', '', $word) !== '';
77  });
78 
79  $numberOfWords += count($wordsInContent);
80  }
81  }
82 
83  if ($this->withImages) {
84  $imageNodes = $document->getElementsByTagName('img');
85  $numberOfWords += $this->calculateWordsForImages($imageNodes->length);
86  }
87 
88  $readingTime = ceil($numberOfWords / $this->wordsPerMinute);
89 
90  return (int) $readingTime;
91  }
92 
98  private function calculateWordsForImages(int $numberOfImages) : float
99  {
100  $time = 0.0;
101 
102  for ($i = 1; $i <= $numberOfImages; $i++) {
103  if ($i >= 10) {
104  $time += 3 * ((int) $this->wordsPerMinute / 60);
105  } else {
106  $time += (12 - ($i - 1)) * ((int) $this->wordsPerMinute / 60);
107  }
108  }
109 
110  return $time;
111  }
112 }
transform($from)
Perform the transformation.Please use this for transformations. It&#39;s more performant than calling inv...
__construct(bool $withImages)
ReadingTime constructor.
A transformation is a function from one datatype to another.
$i
Definition: metadata.php:24