Added an export routine to export back from Drupal to ICS
This commit is contained in:
parent
2c5b7642f1
commit
0bb24a1386
86
export.php
Normal file
86
export.php
Normal 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);
|
||||||
|
}
|
16
import.php
16
import.php
@ -1,23 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter;
|
namespace Pandy06269\iCalDrupal;
|
||||||
|
|
||||||
use Pandy06269\iCalImporter\includes\DrupalConfigFileReader;
|
use Pandy06269\iCalDrupal\includes\DrupalConfigFileReader;
|
||||||
use Pandy06269\iCalImporter\includes\DrupalDatabaseEventWriter;
|
use Pandy06269\iCalDrupal\includes\DrupalDatabaseEventWriter;
|
||||||
use Pandy06269\iCalImporter\includes\Event;
|
use Pandy06269\iCalDrupal\includes\Event;
|
||||||
use Pandy06269\iCalImporter\includes\ICSFileReader;
|
use Pandy06269\iCalDrupal\includes\ICSFileReader;
|
||||||
|
|
||||||
//define('DEBUG', true);
|
//define('DEBUG', true);
|
||||||
|
|
||||||
function autoload_include_file($class)
|
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));
|
$filePath = sprintf('%s/%s.php', __DIR__, str_replace('\\', DIRECTORY_SEPARATOR, $class));
|
||||||
require_once $filePath;
|
require_once $filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_autoload_register('\Pandy06269\iCalImporter\autoload_include_file');
|
spl_autoload_register('\Pandy06269\iCalDrupal\autoload_include_file');
|
||||||
|
|
||||||
if ($argc !== 3)
|
if ($argc !== 3)
|
||||||
{
|
{
|
||||||
@ -87,7 +87,7 @@ try
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$target->upload($event);
|
$target->write($event);
|
||||||
echo 'OK' . PHP_EOL;
|
echo 'OK' . PHP_EOL;
|
||||||
}
|
}
|
||||||
catch (\Exception $e)
|
catch (\Exception $e)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter\includes;
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
class DrupalConfigFileReader extends FileReader
|
class DrupalConfigFileReader extends FileReader
|
||||||
{
|
{
|
||||||
|
77
includes/DrupalDatabaseEventReader.php
Normal file
77
includes/DrupalDatabaseEventReader.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter\includes;
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
class DrupalDatabaseEventWriter extends MysqlEventWriter
|
class DrupalDatabaseEventWriter extends MysqlConnector implements IEventWriter
|
||||||
{
|
{
|
||||||
private $options = [];
|
private $options = [];
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ class DrupalDatabaseEventWriter extends MysqlEventWriter
|
|||||||
$this->options = array_merge($defaultOptions, $options);
|
$this->options = array_merge($defaultOptions, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function upload(Event $event)
|
public function write(Event $event)
|
||||||
{
|
{
|
||||||
// First insert the `node` record
|
// First insert the `node` record
|
||||||
$this->executeQuery(
|
$this->executeQuery(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter\includes;
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
class Event
|
class Event
|
||||||
{
|
{
|
||||||
@ -9,6 +9,11 @@ class Event
|
|||||||
*/
|
*/
|
||||||
private $description;
|
private $description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \DateTime
|
||||||
|
*/
|
||||||
|
private $endDate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \DateTime
|
* @var \DateTime
|
||||||
*/
|
*/
|
||||||
@ -40,6 +45,22 @@ class Event
|
|||||||
$this->description = $description;
|
$this->description = $description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \DateTime
|
||||||
|
*/
|
||||||
|
public function getEndDate()
|
||||||
|
{
|
||||||
|
return $this->endDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DateTime $endDate
|
||||||
|
*/
|
||||||
|
public function setEndDate($endDate)
|
||||||
|
{
|
||||||
|
$this->endDate = $endDate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \DateTime
|
* @return \DateTime
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter\includes;
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
class FileReader
|
class FileReader
|
||||||
{
|
{
|
||||||
|
62
includes/ICSEchoWriter.php
Normal file
62
includes/ICSEchoWriter.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,15 @@
|
|||||||
<?php
|
<?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_BEGIN = 'BEGIN:VCALENDAR';
|
||||||
|
const HEADER_VCALENDAR_END = 'END:VCALENDAR';
|
||||||
const HEADER_VEVENT_BEGIN = 'BEGIN:VEVENT';
|
const HEADER_VEVENT_BEGIN = 'BEGIN:VEVENT';
|
||||||
const HEADER_VEVENT_END = 'END:VEVENT';
|
const HEADER_VEVENT_END = 'END:VEVENT';
|
||||||
const HEADER_DATE = 'DTSTART:';
|
const HEADER_DATE = 'DTSTART:';
|
||||||
|
const HEADER_DATE_END = 'DTEND:';
|
||||||
const HEADER_DESCRIPTION = 'DESCRIPTION:';
|
const HEADER_DESCRIPTION = 'DESCRIPTION:';
|
||||||
const HEADER_TITLE = 'SUMMARY:';
|
const HEADER_TITLE = 'SUMMARY:';
|
||||||
const HEADER_UID = 'UID:';
|
const HEADER_UID = 'UID:';
|
||||||
|
8
includes/IEventReader.php
Normal file
8
includes/IEventReader.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
|
interface IEventReader
|
||||||
|
{
|
||||||
|
function getEvents();
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter\includes;
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
interface IEventWriter
|
interface IEventWriter
|
||||||
{
|
{
|
||||||
function close();
|
function close();
|
||||||
function open();
|
function open();
|
||||||
function upload(Event $event);
|
function write(Event $event);
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Pandy06269\iCalImporter\includes;
|
namespace Pandy06269\iCalDrupal\includes;
|
||||||
|
|
||||||
abstract class MysqlEventWriter implements IEventWriter
|
class MysqlConnector
|
||||||
{
|
{
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
@ -20,8 +20,11 @@ abstract class MysqlEventWriter implements IEventWriter
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function open()
|
public function open()
|
||||||
|
{
|
||||||
|
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']);
|
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->connection = new \mysqli(
|
||||||
$this->config['host'],
|
$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 = [])
|
protected function executeQuery($sql, array $paramTypes = [], array $paramValues = [])
|
||||||
{
|
{
|
||||||
$statement = $this->prepareQueryStatement($sql, $paramTypes, $paramValues);
|
$statement = $this->prepareQueryStatement($sql, $paramTypes, $paramValues);
|
Reference in New Issue
Block a user