PluginProbe
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar / 2.1.21
Booking Manager – Sync WP Booking Calendar – Import Events, Export Bookings to ICS Calendar v2.1.21
2.1.22 2.1.21 2.1.20 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 trunk 1.1 2.0 2.0.1 2.0.10.2 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.18 2.0.2 2.0.20 2.0.21 All 56 releases
← All changes | assets/libs/icalendar/includes/ical.php +78 -17 2.1.7 → 2.1.21 View file →
@@ -288,8 +288,81 @@
288 288 $level -= 1;
289 289 return $html;
290 290 }
291 291
292 +
293 + // FixIn: 2025-08-11. 12:52
294 + /**
295 + * Find a safe byte index to cut $s at, not exceeding $maxBytes.
296 + * - Prefer last ' ' or ',' or ';' <= $maxBytes
297 + * - Avoid cutting immediately after a backslash (to keep escapes like "\n" intact)
298 + * - Ensure we don't split a UTF-8 code point
299 + * Returns byte length to keep.
300 + */
301 + private static function _utf8_safe_cut_pos( $s, $maxBytes ) {
302 + $len = strlen( $s );
303 + if ( $len <= $maxBytes ) {
304 + return $len;
305 + }
306 +
307 + // Start with hard limit
308 + $cut = $maxBytes;
309 +
310 + // Prefer last breakable char within the current window
311 + $window = substr( $s, 0, $cut );
312 + $lastSpace = strrpos( $window, ' ' );
313 + $lastComma = strrpos( $window, ',' );
314 + $lastSemi = strrpos( $window, ';' );
315 + $pref = max( $lastSpace === false ? - 1 : $lastSpace, $lastComma === false ? - 1
316 + : $lastComma, $lastSemi === false ? - 1 : $lastSemi );
317 +
318 + if ( $pref >= 0 ) {
319 + $cut = $pref + 1; // cut *after* the delimiter/space so it stays on line
320 + }
321 +
322 + // Avoid cutting right after backslash (don’t break "\n", "\,", "\;", "\\")
323 + if ( $cut > 0 && $s[ $cut - 1 ] === '\\' ) {
324 + $cut -= 1;
325 + if ( $cut <= 0 ) {
326 + $cut = $maxBytes;
327 + } // fallback
328 + }
329 +
330 + // Ensure we don't chop inside a UTF-8 multibyte char
331 + // Move back until at start of a UTF-8 code point
332 + while ( $cut > 0 && ( ord( $s[ $cut ] ) & 0xC0 ) === 0x80 ) {
333 + $cut --;
334 + }
335 + if ( $cut <= 0 ) {
336 + $cut = $maxBytes;
337 + } // ultimate fallback
338 +
339 + return $cut;
340 + }
341 +
342 + /**
343 + * Fold one logical line into RFC 5545 physical lines.
344 + * $firstWidth = 75 octets, $contWidth = 74 octets.
345 + */
346 + private static function _fold_ical_line( $line, $firstWidth = 75, $contWidth = 74 ) {
347 + $out = '';
348 + $first = true;
349 + while ( strlen( $line ) > 0 ) {
350 + $width = $first ? $firstWidth : $contWidth;
351 + $cut = self::_utf8_safe_cut_pos( $line, $width );
352 + $chunk = substr( $line, 0, $cut );
353 + $line = substr( $line, $cut );
354 + if ( ! $first ) {
355 + $out .= ' ';
356 + }
357 + $out .= $chunk . "\r\n";
358 + $first = false;
359 + }
360 +
361 + return $out;
362 + }
363 +
364 +
292 365 /**
293 366 * export tree to icalendar format
294 367 *
295 368 * @param object $node Top level node to export
@@ -317,27 +390,15 @@
317 390 $p .= ";" . strtoupper($key) . "=" . $value;
318 391 }
319 392 }
320 393 $values = $d->getValues();
321 - // don't think we need this, Sunbird does not like it in the EXDATE field
322 - //$values = str_replace(",", "\\,", $values);
323 394
324 395 $line = $d->getName() . $p . ":" . $values;
325 - $line = str_replace(array("<br>","<BR>","<br/>","<BR/"),"\\n",$line);
326 - $line = str_replace(array("\r\n","\n\r","\n","\r"),'\n',$line);
327 - //$line = str_replace(array(',',';','\\'), array('\\,','\\;','\\\\'),$line);
328 - //$line =strip_tags($line);
329 - $linecount = 0;
330 - while (strlen($line) > 0) {
331 - $linewidth = ($linecount == 0? 75 : 74);
332 - $linesize = (strlen($line) > $linewidth? $linewidth: strlen($line));
333 - if($linecount > 0)
334 - $txtstr .= " ";
335 - $txtstr .= substr($line,0,$linesize) . "\r\n";
336 - $linecount += 1;
337 - $line = substr($line,$linewidth);
338 - }
339 - //echo $line . "\n";
396 + $line = str_replace( array( "<br>", "<BR>", "<br/>", "<BR/" ), "\\n", $line );
397 + $line = str_replace( array( "\r\n", "\n\r", "\n", "\r" ), '\n', $line );
398 +
399 + // FixIn: 2025-08-11 12:53.
400 + $txtstr .= self::_fold_ical_line( $line );
340 401 }
341 402 foreach ($node->child as $c){
342 403 $txtstr .= $node->export($c,$level + 1);
343 404 }