Issues (134)

src/services/Convert.php (21 issues)

1
<?php
2
/**
3
 * iCalendar plugin for Craft CMS 3.x
0 ignored issues
show
Doc comment short description must start with a capital letter
Loading history...
4
 *
5
 * Tools for parsing & formatting the RFC 2445 iCalendar (.ics) specification
6
 *
7
 * @link      https://nystudio107.com
0 ignored issues
show
The tag in position 1 should be the @copyright tag
Loading history...
8
 * @copyright Copyright (c) 2018 nystudio107
0 ignored issues
show
@copyright tag must contain a year and the name of the copyright holder
Loading history...
9
 */
0 ignored issues
show
PHP version not specified
Loading history...
Missing @category tag in file comment
Loading history...
Missing @package tag in file comment
Loading history...
Missing @author tag in file comment
Loading history...
Missing @license tag in file comment
Loading history...
10
11
namespace nystudio107\icalendar\services;
12
13
use craft\base\Component;
14
15
/**
0 ignored issues
show
Missing short description in doc comment
Loading history...
16
 * @author    nystudio107
0 ignored issues
show
The tag in position 1 should be the @package tag
Loading history...
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
Tag value for @author tag indented incorrectly; expected 2 spaces but found 4
Loading history...
17
 * @package   ICalendar
0 ignored issues
show
Tag value for @package tag indented incorrectly; expected 1 spaces but found 3
Loading history...
18
 * @since     1.0.0
0 ignored issues
show
The tag in position 3 should be the @author tag
Loading history...
Tag value for @since tag indented incorrectly; expected 3 spaces but found 5
Loading history...
19
 */
0 ignored issues
show
Missing @category tag in class comment
Loading history...
Missing @license tag in class comment
Loading history...
Missing @link tag in class comment
Loading history...
20
class Convert extends Component
21
{
22
    // Constants
23
    // =========================================================================
24
25
    protected const RFC2455_EOL = "\r\n";
26
    protected const RFC2455_TAB = "\t";
27
    protected const RFC2455_LITERAL_NEWLINE = '\n';
28
    protected const MAX_OCTETS = 75;
29
30
    // Public Methods
31
    // =========================================================================
32
33
    /**
34
     * Format the passed in $text as per the iCalendar RFC 2445 spec:
35
     * https://icalendar.org/validator.html
36
     *
37
     * @param string $text
0 ignored issues
show
Missing parameter comment
Loading history...
38
     *
39
     * @return string
40
     */
41
    public function rfc2445(string $text): string
42
    {
43
        $result = '';
44
        // Normalize the line breaks
45
        $text = str_replace(["\n", "\r\r\n"], self::RFC2455_EOL, $text);
46
        // Handle rich text field output, such as from Redactor, which may have line or paragraph breaks
47
        $text = str_replace(["</p>\r", "</P>\r"], self::RFC2455_LITERAL_NEWLINE . self::RFC2455_LITERAL_NEWLINE, $text);
48
        $text = str_replace(["<br>\r", "<BR>\r", "<br />\r", "<BR />\r"], self::RFC2455_LITERAL_NEWLINE, $text);
49
        // Split the text into separate lines
50
        $lines = explode(self::RFC2455_EOL, $text);
51
        foreach ($lines as $key => $line) {
52
            $result .= $this->icalSplit('', $line) . self::RFC2455_EOL;
53
        }
54
55
        return $result;
56
    }
57
58
    // Protected Methods
59
    // =========================================================================
60
61
    /**
62
     * Split the lines into RFC 2445 compatible line breaks so that no line
63
     * is longer than 75 octets
64
     * Adapted from: https://gist.github.com/hugowetterberg/81747
65
     *
66
     * @param string $preamble
0 ignored issues
show
Missing parameter comment
Loading history...
67
     * @param string $value
0 ignored issues
show
Missing parameter comment
Loading history...
68
     *
69
     * @return string
70
     */
71
    protected function icalSplit(string $preamble, string $value): string
72
    {
73
        $value = trim($value);
74
        $value = strip_tags($value);
75
        $value = html_entity_decode($value);
76
        $value = preg_replace('/\n+/', ' ', $value);
77
        $value = preg_replace('/\s{2,}/', ' ', $value);
78
        $preamble_len = mb_strlen($preamble);
79
        $lines = [];
80
        while (mb_strlen($value) > (self::MAX_OCTETS - $preamble_len)) {
81
            $space = (self::MAX_OCTETS - $preamble_len);
82
            $mbcc = $space;
83
            while ($mbcc) {
84
                $line = mb_substr($value, 0, $mbcc);
85
                $oct = mb_strlen($line);
86
                if ($oct > $space) {
87
                    $mbcc -= $oct - $space;
88
                } else {
89
                    $lines[] = $line;
90
                    $preamble_len = 1; // Still take the tab into account
91
                    $value = mb_substr($value, $mbcc);
92
                    break;
93
                }
94
            }
95
        }
96
        if (!empty($value)) {
97
            $lines[] = $value;
98
        }
99
100
        return implode(self::RFC2455_EOL . self::RFC2455_TAB, $lines);
101
    }
102
}
103