Passed
Push — Showing-Posts ( 1e63c5...22ac26 )
by Stone
02:02
created

StringFunctions::completeDom()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 16
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Core\Traits;
4
5
use Core\Constant;
6
use Twig\Error\Error;
7
8
/**
9
 * a trait with some string related helpers
10
 * Trait StringFunctions
11
 * @package Core\Traits
12
 */
13
trait StringFunctions
14
{
15
    /**
16
     * does a haystack start with a needle ?
17
     * @param $haystack string the string to search in
18
     * @param $needle string the string to search for
19
     * @return bool
20
     */
21
    public function startsWith(string $haystack, string $needle): bool
22
    {
23
        $length = strlen($needle);
24
        return (substr($haystack, 0, $length) === $needle);
25
    }
26
27
    /**
28
     * Does a haystack end with a needle
29
     * @param $haystack string the string to search in
30
     * @param $needle string the string to search for
31
     * @return bool
32
     */
33
    public function endsWith(string $haystack, string $needle): bool
34
    {
35
        $length = strlen($needle);
36
        if ($length == 0) {
37
            return true;
38
        }
39
40
        return (substr($haystack, -$length) === $needle);
41
    }
42
43
    /**
44
     * Remove the tail of a string
45
     * @param $string string to slice apart
46
     * @param $tail string the string to remove
47
     * @return string
48
     */
49
    public function removeFromEnd(string $string, string $tail): string
50
    {
51
        if ($this->endsWith($string, $tail)) {
52
            $string = substr($string, 0, -strlen($tail));
53
        }
54
        return $string;
55
    }
56
57
    /**
58
     * remove some characters from the front of the string
59
     * @param string $string the string to be decapitated
60
     * @param string $head the head to be cut off ("OFF WITH HIS HEAD")
61
     * @return string
62
     */
63
    public function removeFromBeginning(string $string, string $head): string
64
    {
65
        if ($this->startsWith($string, $head)) {
66
            $string = substr($string, strlen($head));
67
        }
68
        return $string;
69
    }
70
71
    /**
72
     * create an excerpt, shortening the text to a specific number of words
73
     * @param string $text the text to shorten
74
     * @param int $count number of words
75
     * @return string the shortend text
76
     * @throws \ErrorException
77
     */
78
    public function getExcerpt(string $text, int $count = Constant::EXCERPT_WORD_COUNT)
79
    {
80
        if ($count < 1) {
81
            throw new \ErrorException('excerpt length too low');
82
        }
83
        $text = str_replace("  ", " ", $text);
84
85
        //Searching for the page break tag
86
        $breakTagPosition = strpos($text, "<!-- EndOfExcerptBlogOc -->");
87
        if($breakTagPosition > 0){
88
            return $this->completeDom(substr($text, 0, $breakTagPosition));
89
        }
90
91
        //exploding on space except for in img, p and span.
92
        $string = preg_split('/(<img[^>]+\>)|(<p[^>]+\>)|(<span[^>]+\>)|\s/', $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
93
        if (count($string) <= $count) {
0 ignored issues
show
Bug introduced by
It seems like $string can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
        if (count(/** @scrutinizer ignore-type */ $string) <= $count) {
Loading history...
94
            return $text;
95
        }
96
        $trimed = '';
97
        for ($wordCounter = 0; $wordCounter < $count; $wordCounter++) {
98
            $trimed .= $string[$wordCounter];
99
            if ($wordCounter < $count - 1) {
100
                $trimed .= " ";
101
            } else {
102
                $trimed .= "[...]";
103
            }
104
        }
105
106
        return $this->completeDom($trimed);
107
    }
108
109
    /**
110
     * Close the dom in given $text
111
     * @param string $text unclean html
112
     * @return string cleaned up html
113
     */
114
    private function completeDom(string $text): string
115
    {
116
        //grabbed from https://gist.github.com/JayWood/348752b568ecd63ae5ce#gistcomment-2310550
117
        libxml_use_internal_errors(true);
118
119
        $dom = new \DOMDocument;
120
        $dom->loadHTML($text);
121
122
        // Strip wrapping <html> and <body> tags
123
        $mock = new \DOMDocument;
124
        $body = $dom->getElementsByTagName('body')->item(0);
125
        foreach ($body->childNodes as $child) {
126
            $mock->appendChild($mock->importNode($child, true));
127
        }
128
129
        return trim($mock->saveHTML());
130
    }
131
132
    /**
133
     * check passed string, returns true if the string contains alphaNum or _ or -. use for checking database tables, column names or slugs
134
     * @param string $string the string to analyse
135
     * @return bool
136
     */
137
    public function isAlphaNum(string $string): bool
138
    {
139
        if (preg_match("/^[A-Za-z0-9_-]+$/", $string)) {
140
            return true;
141
        }
142
        return false;
143
    }
144
}