From 0bb24a13864e9913e7c0ca40025ab27d97524fd0 Mon Sep 17 00:00:00 2001 From: Andy Heathershaw Date: Sun, 11 Mar 2018 21:03:39 +0000 Subject: [PATCH] Added an export routine to export back from Drupal to ICS --- export.php | 86 +++++++++++++++++++ import.php | 16 ++-- includes/DrupalConfigFileReader.php | 2 +- includes/DrupalDatabaseEventReader.php | 77 +++++++++++++++++ includes/DrupalDatabaseEventWriter.php | 6 +- includes/Event.php | 23 ++++- includes/FileReader.php | 2 +- includes/ICSEchoWriter.php | 62 +++++++++++++ includes/ICSFileReader.php | 6 +- includes/IEventReader.php | 8 ++ includes/IEventWriter.php | 4 +- ...ysqlEventWriter.php => MysqlConnector.php} | 11 +-- 12 files changed, 280 insertions(+), 23 deletions(-) create mode 100644 export.php create mode 100644 includes/DrupalDatabaseEventReader.php create mode 100644 includes/ICSEchoWriter.php create mode 100644 includes/IEventReader.php rename includes/{MysqlEventWriter.php => MysqlConnector.php} (90%) diff --git a/export.php b/export.php new file mode 100644 index 0000000..f92c5c1 --- /dev/null +++ b/export.php @@ -0,0 +1,86 @@ +open(); + + $events = $drupalEventReader->getEvents(); + usort($events, function(Event $x, Event $y) + { + if ($x->getStartDate() == $y->getStartDate()) + { + return 0; + } + else if ($x->getStartDate() < $y->getStartDate()) + { + return -1; + } + else + { + return 1; + } + }); + + $drupalEventReader->close(); + + header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK', true, 200); + header('Content-Type: text/plain'); + + $icsWriter = new ICSEchoWriter(); + $icsWriter->open(); + + /** @var Event $event */ + foreach ($events as $event) + { + if ($event->getStartDate() > new \DateTime()) + { + $icsWriter->write($event); + } + } + + $icsWriter->close(); +} +catch (\Exception $e) +{ + if (defined('DEBUG') && DEBUG) + { + echo sprintf('Caught exception: %s' . PHP_EOL, $e->getMessage()); + echo $e->getTraceAsString(); + } + else + { + echo 'An error occurred'; + } + + header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); +} diff --git a/import.php b/import.php index 186588d..0843824 100644 --- a/import.php +++ b/import.php @@ -1,23 +1,23 @@ upload($event); + $target->write($event); echo 'OK' . PHP_EOL; } catch (\Exception $e) diff --git a/includes/DrupalConfigFileReader.php b/includes/DrupalConfigFileReader.php index 65bbb00..712fb09 100644 --- a/includes/DrupalConfigFileReader.php +++ b/includes/DrupalConfigFileReader.php @@ -1,6 +1,6 @@ config = $configFileReader->getDatabaseConfig(); + + $defaultOptions = [ + 'body_format' => 'content_editor_html', + 'calendar_bundle' => 'private_event', + 'end_date_field_name' => 'end_date', + 'start_date_field_name' => 'start_date' + ]; + + $this->options = array_merge($defaultOptions, $options); + } + + public function getEvents() + { + $events = []; + + $results = $this->executeQueryResult( + 'SELECT n.nid, n.uuid, MAX(nr.vid) AS vid FROM `node` n INNER JOIN `node_revision` nr ON nr.nid = n.nid WHERE (n.`type` = ? OR n.`type` = ?) GROUP BY n.nid, n.uuid', + ['s', 's'], + ['private_event', 'public_event'] + ); + + $startDateTableName = sprintf('node_revision__field_%s', $this->options['start_date_field_name']); + $startDateFieldName = sprintf('field_%s_value', $this->options['start_date_field_name']); + + $endDateTableName = sprintf('node_revision__field_%s', $this->options['end_date_field_name']); + $endDateFieldName = sprintf('field_%s_value', $this->options['end_date_field_name']); + + foreach ($results as $result) + { + $nodeResults = $this->executeQueryResult( + sprintf( + 'SELECT * ' . + 'FROM `node_field_data` n ' . + 'LEFT OUTER JOIN `%s` ns ON ns.`entity_id` = n.`nid` AND ns.`revision_id` = n.`vid` ' . + 'LEFT OUTER JOIN `%s` ne ON ne.`entity_id` = n.`nid` AND ne.`revision_id` = n.`vid` ' . + 'LEFT OUTER JOIN `node_revision__body` nb ON nb.`entity_id` = n.`nid` AND nb.`revision_id` = n.`vid` ' . + 'WHERE n.`nid` = ? AND n.`vid` = ?', + $startDateTableName, + $endDateTableName + ), + ['i', 'i'], + [$result['nid'], $result['vid']] + ); + + $event = new Event(); + $event->setTitle($nodeResults[0]['title']); + $event->setDescription(trim($nodeResults[0]['body_value'])); + + if (!empty($nodeResults[0][$startDateFieldName])) + { + $event->setStartDate(new \DateTime($nodeResults[0][$startDateFieldName])); + } + + if (!empty($nodeResults[0][$endDateFieldName])) + { + $event->setEndDate(new \DateTime($nodeResults[0][$endDateFieldName])); + } + + $event->setUid($result['uuid']); + + $events[] = $event; + } + + return $events; + } +} \ No newline at end of file diff --git a/includes/DrupalDatabaseEventWriter.php b/includes/DrupalDatabaseEventWriter.php index 8b131a0..972dd73 100644 --- a/includes/DrupalDatabaseEventWriter.php +++ b/includes/DrupalDatabaseEventWriter.php @@ -1,8 +1,8 @@ options = array_merge($defaultOptions, $options); } - public function upload(Event $event) + public function write(Event $event) { // First insert the `node` record $this->executeQuery( diff --git a/includes/Event.php b/includes/Event.php index b9926a2..9bf6fb9 100644 --- a/includes/Event.php +++ b/includes/Event.php @@ -1,6 +1,6 @@ description = $description; } + /** + * @return \DateTime + */ + public function getEndDate() + { + return $this->endDate; + } + + /** + * @param \DateTime $endDate + */ + public function setEndDate($endDate) + { + $this->endDate = $endDate; + } + /** * @return \DateTime */ diff --git a/includes/FileReader.php b/includes/FileReader.php index 027243d..87491a5 100644 --- a/includes/FileReader.php +++ b/includes/FileReader.php @@ -1,6 +1,6 @@ getTitle()); + + if (!empty($event->getDescription())) + { + $matches = []; + preg_match_all('/

(.+)<\/p>/', $event->getDescription(), $matches); + + $isDescriptionStarted = false; + foreach ($matches[1] as $match) + { + if (strlen(trim($match)) > 0) + { + if ($isDescriptionStarted) + { + echo $match . PHP_EOL; + } + else + { + echo sprintf('%s%s' . PHP_EOL, ICSFileReader::HEADER_DESCRIPTION, $match); + $isDescriptionStarted = true; + } + } + } + } + + if (!is_null($event->getStartDate())) + { + $date = $event->getStartDate()->format('Ymd\\THis\\Z'); + + echo sprintf('%s%s' . PHP_EOL, ICSFileReader::HEADER_DATE, $date); + } + + if (!is_null($event->getEndDate())) + { + $date = $event->getEndDate()->format('Ymd\\THis\\Z'); + + echo sprintf('%s%s' . PHP_EOL, ICSFileReader::HEADER_DATE_END, $date); + } + + echo ICSFileReader::HEADER_VEVENT_END . PHP_EOL; + } +} \ No newline at end of file diff --git a/includes/ICSFileReader.php b/includes/ICSFileReader.php index cce1620..e882509 100644 --- a/includes/ICSFileReader.php +++ b/includes/ICSFileReader.php @@ -1,13 +1,15 @@ config['database'], $this->config['host'], $this->config['port']); + if (defined('DEBUG') && DEBUG) + { + echo sprintf('Connecting to Drupal database called "%s" on "%s:%d"' . PHP_EOL, $this->config['database'], $this->config['host'], $this->config['port']); + } $this->connection = new \mysqli( $this->config['host'], @@ -37,8 +40,6 @@ abstract class MysqlEventWriter implements IEventWriter } } - abstract function upload(Event $event); - protected function executeQuery($sql, array $paramTypes = [], array $paramValues = []) { $statement = $this->prepareQueryStatement($sql, $paramTypes, $paramValues);