diff --git a/src/schedule-2.0/config/routes.yaml b/src/schedule-2.0/config/routes.yaml
index 1833a6e..114088d 100644
--- a/src/schedule-2.0/config/routes.yaml
+++ b/src/schedule-2.0/config/routes.yaml
@@ -40,6 +40,7 @@ app_logoutcas:
path: /logoutcas
defaults: { _controller: App\Controller\SecurityController:logoutcas }
+
#== Crop =========================================================================================================
app_crop01:
path: /user/crop01
@@ -350,4 +351,9 @@ app_customer_report:
app_customer_planning:
path: /customer/planning/{key}
- defaults: { _controller: App\Controller\ReportController:planning, access: 'customer' }
\ No newline at end of file
+ defaults: { _controller: App\Controller\ReportController:planning, access: 'customer' }
+
+#== API ===========================================================================================================
+app_api:
+ path: /api/{key}
+ defaults: { _controller: App\Controller\ApiController:api }
\ No newline at end of file
diff --git a/src/schedule-2.0/config/services.yaml b/src/schedule-2.0/config/services.yaml
index 7ab60c4..1ac6453 100644
--- a/src/schedule-2.0/config/services.yaml
+++ b/src/schedule-2.0/config/services.yaml
@@ -41,6 +41,10 @@ services:
public: true
class: App\Service\passwordEncoder
+ app.ics.service:
+ public: true
+ class: App\Service\icsService
+
app.upload.listener:
public: true
class: App\Service\uploadListener
diff --git a/src/schedule-2.0/src/Controller/ApiController.php b/src/schedule-2.0/src/Controller/ApiController.php
new file mode 100755
index 0000000..b0289e7
--- /dev/null
+++ b/src/schedule-2.0/src/Controller/ApiController.php
@@ -0,0 +1,53 @@
+getDoctrine()->getManager();
+
+ $user=$em->getRepository("App:User")->findBy(["apikey"=>$key]);
+ if(!$user) {
+ return new Response("Accès refusé", 403);
+ }
+
+ $ics = new icsService();
+ $ics->debug(false);
+
+
+ $content=$ics->writeheader();
+
+ $events=$em->getRepository("App:Event")->findBy(["user"=>$user]);
+ foreach($events as $event) {
+ $task=$event->getTask();
+ $project=$task->getProject();
+ $customer=$project->getCustomer();
+
+ $ics->set(
+ [
+ 'allday' => $event->getAllday(),
+ 'description' => $event->getDescription(),
+ 'dtstart' => $event->getStart()->format("Y-m-d H:i:s"),
+ 'dtend' => $event->getEnd()->format("Y-m-d H:i:s"),
+ 'summary' => $customer->getName()."-".$project->getName()."-".$task->getName(),
+ 'uid' => "schedule".$event->getId()
+ ]
+ );
+
+ $content.=$ics->writeevent();
+ }
+
+ $content.=$ics->writefooter();
+
+ return new Response($content);
+ }
+}
diff --git a/src/schedule-2.0/src/Form/UserType.php b/src/schedule-2.0/src/Form/UserType.php
index 51dc34d..5264e4a 100644
--- a/src/schedule-2.0/src/Form/UserType.php
+++ b/src/schedule-2.0/src/Form/UserType.php
@@ -116,6 +116,13 @@ class UserType extends AbstractType
]
);
+ $builder->add('apikey',
+ TextType::class, [
+ "label" =>"Clé Accès",
+ "required" => false
+ ]
+ );
+
$builder->add('avatar',HiddenType::class, array("empty_data" => "noavatar.png"));
}
diff --git a/src/schedule-2.0/src/Service/icsService.php b/src/schedule-2.0/src/Service/icsService.php
new file mode 100644
index 0000000..14788c1
--- /dev/null
+++ b/src/schedule-2.0/src/Service/icsService.php
@@ -0,0 +1,133 @@
+fgdebug=$fgdebug;
+ }
+
+ public function set($key, $val = false) {
+ if (is_array($key)) {
+ foreach ($key as $k => $v) {
+ if(is_null($v)||$v=="") unset( $this->properties[$k]);
+ else $this->set($k, $v);
+ }
+ }
+ else {
+ if (in_array($key, $this->available_properties)) {
+ if($key=="allday")
+ $this->properties[$key] = $this->sanitize_val($val, $key, false);
+ else
+ $this->properties[$key] = $this->sanitize_val($val, $key,$this->properties["allday"]);
+ }
+ }
+ }
+
+ public function writeheader() {
+ // Build ICS properties - add header
+ $header = array(
+ 'BEGIN:VCALENDAR',
+ 'VERSION:2.0',
+ 'PRODID:-//hacksw/handcal//NONSGML v1.0//EN',
+ 'CALSCALE:GREGORIAN',
+ 'X-WR-TIMEZONE:Europe/Paris'
+ );
+
+ return $this->exportformat($header);
+ }
+
+ public function writefooter() {
+ // Build ICS properties - add footer
+ $footer[] = 'END:VCALENDAR';
+
+ return $this->exportformat($footer);
+ }
+
+ public function writeevent() {
+ $event[]='BEGIN:VEVENT';
+
+ // Build ICS properties - add header
+ $props = array();
+ foreach($this->properties as $k => $v) {
+ if($k === 'url')
+ $props[strtoupper($k . ';VALUE=URI')] = $v;
+ elseif(($k=='dtstart'||$k=='dtend')&&$this->properties['allday'])
+ $props[strtoupper($k . ';VALUE=DATE')] = $v;
+ else
+ $props[strtoupper($k)] = $v;
+ }
+
+ // Set some default values
+ $props['DTSTAMP'] = $this->format_timestamp('now');
+ if(!isset($props['UID'])) $props['UID'] = uniqid();
+
+ // Append properties
+ foreach ($props as $k => $v) {
+ $event[] = "$k:$v";
+ }
+
+ // Build ICS properties - add footer
+ $event[] = 'END:VEVENT';
+
+ return $this->exportformat($event);
+ }
+
+ private function sanitize_val($val, $key = false, $allday) {
+ switch($key) {
+ case 'dtstamp':
+ $val = $this->format_timestamp($val);
+ break;
+
+ case 'dtend':
+ case 'dtstart':
+ if($allday)
+ $val = $this->format_daystamp($val);
+ else
+ $val = $this->format_timestamp($val);
+ break;
+
+ default:
+ $val = $this->escape_string($val);
+ }
+
+ return $val;
+ }
+
+ private function format_daystamp($timestamp) {
+ $dt = new \DateTime($timestamp, new \DateTimeZone('Europe/Paris'));
+ return $dt->format(self::DT_FORMATDAY);
+ }
+
+ private function format_timestamp($timestamp) {
+ $dt = new \DateTime($timestamp, new \DateTimeZone('Europe/Paris'));
+ return $dt->format(self::DT_FORMAT);
+ }
+
+ private function escape_string($str) {
+ return preg_replace('/([\,;])/','\\\$1', $str);
+ }
+
+ private function exportformat($string) {
+ return implode(($this->fgdebug?"
":"\r\n"), $string).($this->fgdebug?"
":"\r\n");
+ }
+}