<commit_before><?php
namespace Chamilo\Libraries\Calendar\Renderer\Type;

use Chamilo\Libraries\Calendar\Event\RecurrenceRules\VObjectRecurrenceRulesFormatter;
use Chamilo\Libraries\Calendar\Renderer\Interfaces\CalendarRendererProviderInterface;
use Chamilo\Libraries\Calendar\Renderer\Renderer;
use Chamilo\Libraries\Calendar\TimeZone\TimeZoneCalendarWrapper;
use Chamilo\Libraries\Format\Response\Response;
use Sabre\VObject\Component\VCalendar;

/**
 *
 * @package Chamilo\Libraries\Calendar\Renderer\Type
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 */
class ICalRenderer extends Renderer
{
    const TIMEZONE_START = 100;
    const TIMEZONE_END = 2145916799;

    /**
     *
     * @var \Sabre\VObject\Component\VCalendar
     */
    private $calendar;

    /**
     *
     * @param CalendarRendererProviderInterface $dataProvider
     */
    public function __construct(CalendarRendererProviderInterface $dataProvider)
    {
        parent :: __construct($dataProvider);

        $this->calendar = new VCalendar();
    }

    /**
     *
     * @return \Sabre\VObject\Component\VCalendar
     */
    public function getCalendar()
    {
        return $this->calendar;
    }

    /**
     *
     * @param \Sabre\VObject\Component\VCalendar $calendar
     */
    public function setCalendar(VCalendar $calendar)
    {
        $this->calendar = $calendar;
    }

    /**
     *
     * @see \Chamilo\Libraries\Calendar\Renderer\Renderer::render()
     */
    public function render()
    {
        $this->addTimeZone();
        $this->addEvents();
        return $this->getCalendar()->serialize();
    }

    private function addEvents()
    {
        $providedEvents = $this->getDataProvider()->getInternalEvents();

        foreach ($providedEvents as $providedEvent)
        {
            $this->addEvent($providedEvent);
        }
    }

    public function renderAndSend()
    {
        $this->sendResponse($this->render());
    }

    private function sendResponse($serializedCalendar)
    {
        $response = new Response($serializedCalendar);
        $response->headers->set('Content-Type', 'text/calendar');
        $response->headers->set('Content-Disposition', 'attachment; filename="myCalendar.ics"');
        $response->send();
    }

    /**
     * Add the correct timezone information
     */
    private function addTimeZone()
    {
        \iCalUtilityFunctions :: createTimezone(
            new TimeZoneCalendarWrapper($this->getCalendar()),
            date_default_timezone_get(),
            array()/*,
            self :: TIMEZONE_START,
            self :: TIMEZONE_END*/);
    }

    /**
     *
     * @param \Chamilo\Libraries\Calendar\Event\Event $providedEvent
     */
    private function addEvent(\Chamilo\Libraries\Calendar\Event\Event $providedEvent)
    {
        $event = $this->getCalendar()->add('VEVENT');

        $event->add(
            'DTSTART',
            new \DateTime(
                date('Y-m-d\TH:i:s', $providedEvent->getStartDate()),
                new \DateTimeZone(date_default_timezone_get())));

        $event->add(
            'DTEND',
            new \DateTime(
                date('Y-m-d\TH:i:s', $providedEvent->getEndDate()),
                new \DateTimeZone(date_default_timezone_get())));

        $description = trim(strip_tags($providedEvent->getContent()));

        $event->add('LOCATION', trim($providedEvent->getLocation()));
        $event->add('SUMMARY', trim($providedEvent->getTitle()));
        $event->add('DESCRIPTION', $description);

        $event->add('CREATED', date('Y-m-d\TH:i:s', time()));
        $event->add('DTSTAMP', date('Y-m-d\TH:i:s', time()));

        $uniqueIdentifiers = array(
            $providedEvent->getSource(),
            $providedEvent->getId(),
            $providedEvent->getStartDate(),
            $providedEvent->getEndDate());

        $event->add('UID', md5(serialize($uniqueIdentifiers)));
<commit_msg>Fix for ICS calendar rendering for Outlook.<EMAIL><commit_after><?php
namespace Chamilo\Libraries\Calendar\Renderer\Type;

use Chamilo\Libraries\Calendar\Event\RecurrenceRules\VObjectRecurrenceRulesFormatter;
use Chamilo\Libraries\Calendar\Renderer\Interfaces\CalendarRendererProviderInterface;
use Chamilo\Libraries\Calendar\Renderer\Renderer;
use Chamilo\Libraries\Calendar\TimeZone\TimeZoneCalendarWrapper;
use Chamilo\Libraries\Format\Response\Response;
use Sabre\VObject\Component\VCalendar;

/**
 *
 * @package Chamilo\Libraries\Calendar\Renderer\Type
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 */
class ICalRenderer extends Renderer
{
    const TIMEZONE_START = 100;
    const TIMEZONE_END = 2145916799;

    /**
     *
     * @var \Sabre\VObject\Component\VCalendar
     */
    private $calendar;

    /**
     *
     * @param CalendarRendererProviderInterface $dataProvider
     */
    public function __construct(CalendarRendererProviderInterface $dataProvider)
    {
        parent :: __construct($dataProvider);

        $this->calendar = new VCalendar();
    }

    /**
     *
     * @return \Sabre\VObject\Component\VCalendar
     */
    public function getCalendar()
    {
        return $this->calendar;
    }

    /**
     *
     * @param \Sabre\VObject\Component\VCalendar $calendar
     */
    public function setCalendar(VCalendar $calendar)
    {
        $this->calendar = $calendar;
    }

    /**
     *
     * @see \Chamilo\Libraries\Calendar\Renderer\Renderer::render()
     */
    public function render()
    {
        $this->addTimeZone();
        $this->addEvents();
        return $this->getCalendar()->serialize();
    }

    private function addEvents()
    {
        $providedEvents = $this->getDataProvider()->getInternalEvents();

        foreach ($providedEvents as $providedEvent)
        {
            $this->addEvent($providedEvent);
        }
    }

    public function renderAndSend()
    {
        $this->sendResponse($this->render());
    }

    private function sendResponse($serializedCalendar)
    {
        $response = new Response($serializedCalendar);
        $response->headers->set('Content-Type', 'text/calendar');
        $response->headers->set('Content-Disposition', 'attachment; filename="myCalendar.ics"');
        $response->send();
    }

    /**
     * Add the correct timezone information
     */
    private function addTimeZone()
    {
        \iCalUtilityFunctions :: createTimezone(
            new TimeZoneCalendarWrapper($this->getCalendar()),
            date_default_timezone_get(),
            array()/*,
            self :: TIMEZONE_START,
            self :: TIMEZONE_END*/);
    }

    /**
     *
     * @param \Chamilo\Libraries\Calendar\Event\Event $providedEvent
     */
    private function addEvent(\Chamilo\Libraries\Calendar\Event\Event $providedEvent)
    {
        $event = $this->getCalendar()->add('VEVENT');

        $event->add(
            'DTSTART',
            new \DateTime(
                date('Y-m-d\TH:i:s', $providedEvent->getStartDate()),
                new \DateTimeZone(date_default_timezone_get())));

        $event->add(
            'DTEND',
            new \DateTime(
                date('Y-m-d\TH:i:s', $providedEvent->getEndDate()),
                new \DateTimeZone(date_default_timezone_get())));

        $description = trim(strip_tags($providedEvent->getContent()));

        $event->add('LOCATION', trim($providedEvent->getLocation()));
        $event->add('SUMMARY', trim($providedEvent->getTitle()));
        $event->add('DESCRIPTION', $description);

        $event->add(
            'CREATED',
            new \DateTime(date('Y-m-d\TH:i:s', time()), new \DateTimeZone(date_default_timezone_get())));
        $event->add(
            'DTSTAMP',
            new \DateTime(date('Y-m-d\TH:i:s', time()), new \DateTimeZone(date_default_timezone_get())));

        $uniqueIdentifiers = array(
            $providedEvent->getSource(),
            $providedEvent->getId(),
            $providedEvent->getStartDate(),
            $providedEvent->getEndDate());

        $event->add('UID', md5(serialize($uniqueIdentifiers)));

{'fraction_non_alphanumeric': 0.14640442532267978, 'fraction_numerical': 0.0034419176398279043, 'mean_word_length': 2.5936395759717317, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3833400', 'n_tokens_mistral': 2410, 'n_tokens_neox': 2312, 'n_words': 350}