1 | <?php |
||
2 | /** |
||
3 | * iCalendar plugin for Craft CMS 3.x |
||
0 ignored issues
–
show
Coding Style
introduced
by
![]() |
|||
4 | * |
||
5 | * Tools for parsing & formatting the RFC 2445 iCalendar (.ics) specification |
||
6 | * |
||
7 | * @link https://nystudio107.com |
||
0 ignored issues
–
show
|
|||
8 | * @copyright Copyright (c) 2018 nystudio107 |
||
0 ignored issues
–
show
|
|||
9 | */ |
||
0 ignored issues
–
show
|
|||
10 | |||
11 | namespace nystudio107\icalendar\services; |
||
12 | |||
13 | use craft\base\Component; |
||
14 | |||
15 | /** |
||
0 ignored issues
–
show
|
|||
16 | * @author nystudio107 |
||
0 ignored issues
–
show
Content of the @author tag must be in the form "Display Name <[email protected]>"
![]() |
|||
17 | * @package ICalendar |
||
0 ignored issues
–
show
|
|||
18 | * @since 1.0.0 |
||
0 ignored issues
–
show
|
|||
19 | */ |
||
0 ignored issues
–
show
|
|||
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
|
|||
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
|
|||
67 | * @param string $value |
||
0 ignored issues
–
show
|
|||
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 |