Browse Source

Added an export routine to export back from Drupal to ICS

master
Andy Heathershaw 1 year ago
parent
commit
0bb24a1386
12 changed files with 280 additions and 23 deletions
  1. +86
    -0
      export.php
  2. +8
    -8
      import.php
  3. +1
    -1
      includes/DrupalConfigFileReader.php
  4. +77
    -0
      includes/DrupalDatabaseEventReader.php
  5. +3
    -3
      includes/DrupalDatabaseEventWriter.php
  6. +22
    -1
      includes/Event.php
  7. +1
    -1
      includes/FileReader.php
  8. +62
    -0
      includes/ICSEchoWriter.php
  9. +4
    -2
      includes/ICSFileReader.php
  10. +8
    -0
      includes/IEventReader.php
  11. +2
    -2
      includes/IEventWriter.php
  12. +6
    -5
      includes/MysqlConnector.php

+ 86
- 0
export.php View File

@@ -0,0 +1,86 @@
<?php

namespace Pandy06269\iCalDrupal;

use Pandy06269\iCalDrupal\includes\DrupalConfigFileReader;
use Pandy06269\iCalDrupal\includes\DrupalDatabaseEventReader;
use Pandy06269\iCalDrupal\includes\DrupalDatabaseEventWriter;
use Pandy06269\iCalDrupal\includes\Event;
use Pandy06269\iCalDrupal\includes\ICSEchoWriter;
use Pandy06269\iCalDrupal\includes\ICSFileReader;

//define('DEBUG', true);
define('DRUPAL_CONFIG_FILE', '../sites/default/settings.php');

function autoload_include_file($class)
{
$class = substr($class, strlen('Pandy06269\\iCalDrupal\\'));

$filePath = sprintf('%s/%s.php', __DIR__, str_replace('\\', DIRECTORY_SEPARATOR, $class));
require_once $filePath;
}

spl_autoload_register('\Pandy06269\iCalDrupal\autoload_include_file');

if (defined('DEBUG') && DEBUG)
{
ini_set('display_errors', 'on');
}

try
{
$drupalConfigReader = new DrupalConfigFileReader(DRUPAL_CONFIG_FILE);

$drupalEventReader = new DrupalDatabaseEventReader($drupalConfigReader);
$drupalEventReader->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);
}

+ 8
- 8
import.php View File

@@ -1,23 +1,23 @@
<?php

namespace Pandy06269\iCalImporter;
namespace Pandy06269\iCalDrupal;

use Pandy06269\iCalImporter\includes\DrupalConfigFileReader;
use Pandy06269\iCalImporter\includes\DrupalDatabaseEventWriter;
use Pandy06269\iCalImporter\includes\Event;
use Pandy06269\iCalImporter\includes\ICSFileReader;
use Pandy06269\iCalDrupal\includes\DrupalConfigFileReader;
use Pandy06269\iCalDrupal\includes\DrupalDatabaseEventWriter;
use Pandy06269\iCalDrupal\includes\Event;
use Pandy06269\iCalDrupal\includes\ICSFileReader;

//define('DEBUG', true);

function autoload_include_file($class)
{
$class = substr($class, strlen('Pandy06269\\iCalImporter\\'));
$class = substr($class, strlen('Pandy06269\\iCalDrupal\\'));

$filePath = sprintf('%s/%s.php', __DIR__, str_replace('\\', DIRECTORY_SEPARATOR, $class));
require_once $filePath;
}

spl_autoload_register('\Pandy06269\iCalImporter\autoload_include_file');
spl_autoload_register('\Pandy06269\iCalDrupal\autoload_include_file');

if ($argc !== 3)
{
@@ -87,7 +87,7 @@ try

try
{
$target->upload($event);
$target->write($event);
echo 'OK' . PHP_EOL;
}
catch (\Exception $e)

+ 1
- 1
includes/DrupalConfigFileReader.php View File

@@ -1,6 +1,6 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

class DrupalConfigFileReader extends FileReader
{

+ 77
- 0
includes/DrupalDatabaseEventReader.php View File

@@ -0,0 +1,77 @@
<?php

namespace Pandy06269\iCalDrupal\includes;

class DrupalDatabaseEventReader extends MysqlConnector implements IEventReader
{
private $options = [];

public function __construct(DrupalConfigFileReader $configFileReader, array $options = [])
{
$this->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;
}
}

+ 3
- 3
includes/DrupalDatabaseEventWriter.php View File

@@ -1,8 +1,8 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

class DrupalDatabaseEventWriter extends MysqlEventWriter
class DrupalDatabaseEventWriter extends MysqlConnector implements IEventWriter
{
private $options = [];

@@ -20,7 +20,7 @@ class DrupalDatabaseEventWriter extends MysqlEventWriter
$this->options = array_merge($defaultOptions, $options);
}

public function upload(Event $event)
public function write(Event $event)
{
// First insert the `node` record
$this->executeQuery(

+ 22
- 1
includes/Event.php View File

@@ -1,6 +1,6 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

class Event
{
@@ -9,6 +9,11 @@ class Event
*/
private $description;

/**
* @var \DateTime
*/
private $endDate;

/**
* @var \DateTime
*/
@@ -40,6 +45,22 @@ class Event
$this->description = $description;
}

/**
* @return \DateTime
*/
public function getEndDate()
{
return $this->endDate;
}

/**
* @param \DateTime $endDate
*/
public function setEndDate($endDate)
{
$this->endDate = $endDate;
}

/**
* @return \DateTime
*/

+ 1
- 1
includes/FileReader.php View File

@@ -1,6 +1,6 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

class FileReader
{

+ 62
- 0
includes/ICSEchoWriter.php View File

@@ -0,0 +1,62 @@
<?php

namespace Pandy06269\iCalDrupal\includes;

class ICSEchoWriter implements IEventWriter
{
public function close()
{
echo ICSFileReader::HEADER_VCALENDAR_END . PHP_EOL;
}

public function open()
{
echo ICSFileReader::HEADER_VCALENDAR_BEGIN . PHP_EOL;
}

public function write(Event $event)
{
echo ICSFileReader::HEADER_VEVENT_BEGIN . PHP_EOL;

echo sprintf('%s%s' . PHP_EOL, ICSFileReader::HEADER_TITLE, $event->getTitle());

if (!empty($event->getDescription()))
{
$matches = [];
preg_match_all('/<p>(.+)<\/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;
}
}

+ 4
- 2
includes/ICSFileReader.php View File

@@ -1,13 +1,15 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

class ICSFileReader extends FileReader
class ICSFileReader extends FileReader implements IEventReader
{
const HEADER_VCALENDAR_BEGIN = 'BEGIN:VCALENDAR';
const HEADER_VCALENDAR_END = 'END:VCALENDAR';
const HEADER_VEVENT_BEGIN = 'BEGIN:VEVENT';
const HEADER_VEVENT_END = 'END:VEVENT';
const HEADER_DATE = 'DTSTART:';
const HEADER_DATE_END = 'DTEND:';
const HEADER_DESCRIPTION = 'DESCRIPTION:';
const HEADER_TITLE = 'SUMMARY:';
const HEADER_UID = 'UID:';

+ 8
- 0
includes/IEventReader.php View File

@@ -0,0 +1,8 @@
<?php

namespace Pandy06269\iCalDrupal\includes;

interface IEventReader
{
function getEvents();
}

+ 2
- 2
includes/IEventWriter.php View File

@@ -1,10 +1,10 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

interface IEventWriter
{
function close();
function open();
function upload(Event $event);
function write(Event $event);
}

includes/MysqlEventWriter.php → includes/MysqlConnector.php View File

@@ -1,8 +1,8 @@
<?php

namespace Pandy06269\iCalImporter\includes;
namespace Pandy06269\iCalDrupal\includes;

abstract class MysqlEventWriter implements IEventWriter
class MysqlConnector
{
protected $config;

@@ -21,7 +21,10 @@ abstract class MysqlEventWriter implements IEventWriter

public function open()
{
echo sprintf('Connecting to Drupal database called "%s" on "%s:%d"' . PHP_EOL, $this->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);

Loading…
Cancel
Save