Remove dependency on Core.
This library still is way too much of a UI/widget-y class and not enough
of a standalone library.
* did not receive this file, see http://www.horde.org/licenses/asl.php.
*/
-function _cleanup()
+function _cleanupData()
{
- global $import_step;
- $import_step = 1;
- return IMPORT_FILE;
+ $GLOBALS['import_step'] = 1;
+ return Horde_Data::IMPORT_FILE;
}
@define('FIMA_BASE', dirname(__FILE__));
require_once FIMA_BASE . '/lib/base.php';
-require_once 'Horde/Data.php';
$ledger = Fima::getActiveLedger();
/* Templates for the different import steps. */
$templates = array(
- IMPORT_CSV => array($registry->get('templates', 'horde') . '/data/csvinfo.inc'),
- IMPORT_TSV => array($registry->get('templates', 'horde') . '/data/tsvinfo.inc'),
- IMPORT_MAPPED => array($registry->get('templates', 'horde') . '/data/csvmap.inc'),
- IMPORT_DATETIME => array($registry->get('templates', 'horde') . '/data/datemap.inc'),
- IMPORT_FILE => array(FIMA_TEMPLATES . '/data/import.inc', FIMA_TEMPLATES . '/data/export.inc'),
+ Horde_Data::IMPORT_CSV => array($registry->get('templates', 'horde') . '/data/csvinfo.inc'),
+ Horde_Data::IMPORT_TSV => array($registry->get('templates', 'horde') . '/data/tsvinfo.inc'),
+ Horde_Data::IMPORT_MAPPED => array($registry->get('templates', 'horde') . '/data/csvmap.inc'),
+ Horde_Data::IMPORT_DATETIME => array($registry->get('templates', 'horde') . '/data/datemap.inc'),
+ Horde_Data::IMPORT_FILE => array(FIMA_TEMPLATES . '/data/import.inc', FIMA_TEMPLATES . '/data/export.inc'),
);
/* Field/clear name mapping. */
'file_types' => $file_types);
$import_format = Horde_Util::getFormData('import_format', '');
$import_step = Horde_Util::getFormData('import_step', 0) + 1;
-$next_step = IMPORT_FILE;
+$next_step = Horde_Data::IMPORT_FILE;
$actionID = Horde_Util::getFormData('actionID');
$error = false;
switch ($actionID) {
case 'export':
$data = array();
-
+
/* Create a Fima storage instance. */
$storage = &Fima_Driver::singleton($ledger);
if (is_a($storage, 'PEAR_Error')) {
break;
}
$params = $storage->getParams();
-
+
$filters = array(array('type', $prefs->getValue('active_postingtype')));
/* Get accounts and postings. */
$accounts = Fima::listAccounts();
$postings = Fima::listPostings($filters);
-
+
foreach ($postings as $postingId => $posting) {
$row = array();
foreach ($posting as $key => $value) {
switch (Horde_Util::getFormData('exportID')) {
case EXPORT_CSV:
- $csv = &Horde_Data::singleton('csv');
- $csv->exportFile(_("postings.csv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Csv', array('cleanup' => '_cleanupData'))->exportFile(_("postings.csv"), $data, true);
exit;
case EXPORT_TSV:
- $tsv = &Horde_Data::singleton('tsv');
- $tsv->exportFile(_("postings.tsv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Tsv', array('cleanup' => '_cleanupData'))->exportFile(_("postings.tsv"), $data, true);
exit;
}
break;
-case IMPORT_FILE:
+case Horde_Data::IMPORT_FILE:
$storage = &Fima_Driver::singleton($ledger);
if (is_a($storage, 'PEAR_Error')) {
$notification->push(sprintf(_("Failed to access the ledger: %s"), $storage->getMessage()), 'horde.error');
}
if (!$error) {
- $data = &Horde_Data::singleton($import_format);
- if (is_a($data, 'PEAR_Error')) {
- $notification->push(_("This file format is not supported."), 'horde.error');
- $next_step = IMPORT_FILE;
- } else {
+ try {
+ $data = $injector->getInstance('Horde_Data')->getOb($import_format, array('cleanup' => '_cleanupData'));
$next_step = $data->nextStep($actionID, $param);
- if (is_a($next_step, 'PEAR_Error')) {
- $notification->push($next_step->getMessage(), 'horde.error');
+ } catch (Horde_Data_Exception $e) {
+ if ($data) {
+ $notification->push($e, 'horde.error');
$next_step = $data->cleanup();
+ } else {
+ $notification->push(_("This file format is not supported."), 'horde.error');
+ $next_step = Horde_Data::IMPORT_FILE;
}
}
}
if (!count($next_step)) {
$notification->push(sprintf(_("The %s file didn't contain any postings."),
$file_types[$_SESSION['import_data']['format']]), 'horde.error');
- } elseif (is_a($result, 'PEAR_Error')) {
- $notification->push(sprintf(_("There was an error importing the data: %s"),
- $result->getMessage()), 'horde.error');
} else {
$notification->push(sprintf(_("%s successfully imported"),
$file_types[$_SESSION['import_data']['format']]), 'horde.success');
require FIMA_TEMPLATES . '/common-header.inc';
require FIMA_TEMPLATES . '/menu.inc';
-if ($next_step == IMPORT_FILE) {
+if ($next_step == Horde_Data::IMPORT_FILE) {
/* Build the charset options. */
$charsets = Horde_Nls::$config['encodings'];
$all_charsets = Horde_Nls::$config['charsets'];
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Core
+ */
+class Horde_Core_Binder_Data implements Horde_Injector_Binder
+{
+ public function create(Horde_Injector $injector)
+ {
+ return new Horde_Core_Factory_Data($injector);
+ }
+
+ public function equals(Horde_Injector_Binder $binder)
+ {
+ return false;
+ }
+}
--- /dev/null
+<?php
+/**
+ * A Horde_Injector:: based Horde_Data:: factory.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Core
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Core
+ */
+
+/**
+ * A Horde_Injector:: based Horde_Data:: factory.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package Core
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Core
+ */
+class Horde_Core_Factory_Data
+{
+ /**
+ * The injector.
+ *
+ * @var Horde_Injector
+ */
+ private $_injector;
+
+ /**
+ * Constructor.
+ *
+ * @param Horde_Injector $injector The injector to use.
+ */
+ public function __construct(Horde_Injector $injector)
+ {
+ $this->_injector = $injector;
+ }
+
+ /**
+ * Return the Horde_Data:: instance.
+ *
+ * @param string $driver The driver.
+ * @param string $params Driver parameters.
+ *
+ * @return Horde_Data_Driver The instance.
+ * @throws Horde_Data_Exception
+ */
+ public function getOb($driver, array $params = array())
+ {
+ $params['browser'] = $this->_injector->getInstance('Horde_Browser');
+ $params['vars'] = Horde_Variables::getDefaultVariables();
+
+ return Horde_Data::factory($driver, $params);
+ }
+
+}
'Horde_Alarm' => new Horde_Core_Binder_Alarm(),
// 'Horde_Browser' - initialized below
'Horde_Cache' => new Horde_Core_Binder_Cache(),
+ 'Horde_Data' => new Horde_Core_Binder_Data(),
'Horde_Db_Adapter_Base' => new Horde_Core_Binder_Db(),
'Horde_Db_Pear' => new Horde_Core_Binder_DbPear(),
'Horde_Editor' => new Horde_Core_Binder_Editor(),
<dir name="Binder">
<file name="Alarm.php" role="php" />
<file name="Cache.php" role="php" />
+ <file name="Data.php" role="php" />
<file name="Db.php" role="php" />
<file name="DbPear.php" role="php" />
<file name="Dns.php" role="php" />
</dir> <!-- /lib/Horde/Core/Binder -->
<dir name="Factory">
<file name="DbPear.php" role="php" />
+ <file name="Data.php" role="php" />
<file name="Editor.php" role="php" />
<file name="Identity.php" role="php" />
<file name="KolabServer.php" role="php" />
<install name="lib/Horde/Core/Autoloader/Callback/Mime.php" as="Horde/Core/Autoloader/Callback/Mime.php" />
<install name="lib/Horde/Core/Binder/Alarm.php" as="Horde/Core/Binder/Alarm.php" />
<install name="lib/Horde/Core/Binder/Cache.php" as="Horde/Core/Binder/Cache.php" />
+ <install name="lib/Horde/Core/Binder/Data.php" as="Horde/Core/Binder/Data.php" />
<install name="lib/Horde/Core/Binder/Db.php" as="Horde/Core/Binder/Db.php" />
<install name="lib/Horde/Core/Binder/DbPear.php" as="Horde/Core/Binder/DbPear.php" />
<install name="lib/Horde/Core/Binder/Dns.php" as="Horde/Core/Binder/Dns.php" />
<install name="lib/Horde/Core/Binder/Vfs.php" as="Horde/Core/Binder/Vfs.php" />
<install name="lib/Horde/Core/Binder/Facebook.php" as="Horde/Core/Binder/Facebook.php" />
<install name="lib/Horde/Core/Factory/DbPear.php" as="Horde/Core/Factory/DbPear.php" />
+ <install name="lib/Horde/Core/Factory/Data.php" as="Horde/Core/Factory/Data.php" />
<install name="lib/Horde/Core/Factory/Editor.php" as="Horde/Core/Factory/Editor.php" />
<install name="lib/Horde/Core/Factory/Identity.php" as="Horde/Core/Factory/Identity.php" />
<install name="lib/Horde/Core/Factory/KolabServer.php" as="Horde/Core/Factory/KolabServer.php" />
+++ /dev/null
-<?php
-/**
- * Abstract class to handle different kinds of Data formats and to
- * help data exchange between Horde applications and external sources.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Data
- */
-class Horde_Data extends PEAR {
-
-// Import constants
-/** Import already mapped csv data. */ const IMPORT_MAPPED = 1;
-/** Map date and time entries of csv data. */ const IMPORT_DATETIME = 2;
-/** Import generic CSV data. */ const IMPORT_CSV = 3;
-/** Import MS Outlook data. */ const IMPORT_OUTLOOK = 4;
-/** Import vCalendar/iCalendar data. */ const IMPORT_ICALENDAR = 5;
-/** Import vCards. */ const IMPORT_VCARD = 6;
-/** Import generic tsv data. */ const IMPORT_TSV = 7;
-/** Import Mulberry address book data */ const IMPORT_MULBERRY = 8;
-/** Import Pine address book data. */ const IMPORT_PINE = 9;
-/** Import file. */ const IMPORT_FILE = 11;
-/** Import data. */ const IMPORT_DATA = 12;
-
-// Export constants
-/** Export generic CSV data. */ const EXPORT_CSV = 100;
-/** Export iCalendar data. */ const EXPORT_ICALENDAR = 101;
-/** Export vCards. */ const EXPORT_VCARD = 102;
-/** Export TSV data. */ const EXPORT_TSV = 103;
-/** Export Outlook CSV data. */ const EXPORT_OUTLOOKCSV = 104;
-
- /**
- * File extension.
- *
- * @var string
- */
- var $_extension;
-
- /**
- * MIME content type.
- *
- * @var string
- */
- var $_contentType = 'text/plain';
-
- /**
- * A list of warnings raised during the last operation.
- *
- * @var array
- */
- var $_warnings = array();
-
- /**
- * Stub to import passed data.
- */
- function importData()
- {
- }
-
- /**
- * Stub to return exported data.
- */
- function exportData()
- {
- }
-
- /**
- * Stub to import a file.
- */
- function importFile($filename, $header = false)
- {
- $data = file_get_contents($filename);
- return $this->importData($data, $header);
- }
-
- /**
- * Stub to export data to a file.
- */
- function exportFile()
- {
- }
-
- /**
- * Tries to determine the expected newline character based on the
- * platform information passed by the browser's agent header.
- *
- * @return string The guessed expected newline characters, either \n, \r
- * or \r\n.
- */
- function getNewline()
- {
- switch ($GLOBALS['browser']->getPlatform()) {
- case 'win':
- return "\r\n";
-
- case 'mac':
- return "\r";
-
- case 'unix':
- default:
- return "\n";
- }
- }
-
- /**
- * Returns the full filename including the basename and extension.
- *
- * @param string $basename Basename for the file.
- *
- * @return string The file name.
- */
- function getFilename($basename)
- {
- return $basename . '.' . $this->_extension;
- }
-
- /**
- * Returns the content type.
- *
- * @return string The content type.
- */
- function getContentType()
- {
- return $this->_contentType;
- }
-
- /**
- * Returns a list of warnings that have been raised during the last
- * operation.
- *
- * @return array A (possibly empty) list of warnings.
- */
- function warnings()
- {
- return $this->_warnings;
- }
-
- /**
- * Attempts to return a concrete Horde_Data instance based on $format.
- *
- * @param mixed $format The type of concrete Horde_Data subclass to
- * return. If $format is an array, then we will look
- * in $format[0]/lib/Data/ for the subclass
- * implementation named $format[1].php.
- *
- * @return Horde_Data The newly created concrete Horde_Data instance, or
- * false on an error.
- */
- function &factory($format)
- {
- if (is_array($format)) {
- $app = $format[0];
- $format = $format[1];
- }
-
- $format = basename($format);
-
- if (empty($format) || (strcmp($format, 'none') == 0)) {
- $data = new Horde_Data();
- return $data;
- }
-
- if (!empty($app)) {
- require_once $GLOBALS['registry']->get('fileroot', $app) . '/lib/Data/' . $format . '.php';
- } else {
- require_once 'Horde/Data/' . $format . '.php';
- }
- $class = 'Horde_Data_' . $format;
- if (class_exists($class)) {
- $data = new $class();
- } else {
- $data = PEAR::raiseError('Class definition of ' . $class . ' not found.');
- }
-
- return $data;
- }
-
- /**
- * Attempts to return a reference to a concrete Horde_Data instance
- * based on $format. It will only create a new instance if no Horde_Data
- * instance with the same parameters currently exists.
- *
- * This should be used if multiple data sources (and, thus, multiple
- * Horde_Data instances) are required.
- *
- * This method must be invoked as: $var = &Horde_Data::singleton()
- *
- * @param string $format The type of concrete Horde_Data subclass to
- * return.
- *
- * @return Horde_Data The concrete Horde_Data reference, or false on an
- * error.
- */
- function &singleton($format)
- {
- static $instances = array();
-
- $signature = serialize($format);
- if (!isset($instances[$signature])) {
- $instances[$signature] = &Horde_Data::factory($format);
- }
-
- return $instances[$signature];
- }
-
- /**
- * Maps a date/time string to an associative array.
- *
- * The method signature has changed in Horde 3.1.3.
- *
- * @access private
- *
- * @param string $date The date.
- * @param string $type One of 'date', 'time' or 'datetime'.
- * @param array $params Two-dimensional array with additional information
- * about the formatting. Possible keys are:
- * - delimiter - The character that seperates the
- * different date/time parts.
- * - format - If 'ampm' and $date contains a time we
- * assume that it is in AM/PM format.
- * - order - If $type is 'datetime' the order of the
- * day and time parts: -1 (timestamp), 0
- * (day/time), 1 (time/day).
- * @param integer $key The key to use for $params.
- *
- * @return string The date or time in ISO format.
- */
- function mapDate($date, $type, $params, $key)
- {
- switch ($type) {
- case 'date':
- case 'monthday':
- case 'monthdayyear':
- $dates = explode($params['delimiter'][$key], $date);
- if (count($dates) != 3) {
- return $date;
- }
- $index = array_flip(explode('/', $params['format'][$key]));
- return $dates[$index['year']] . '-' . $dates[$index['month']] . '-' . $dates[$index['mday']];
-
- case 'time':
- $dates = explode($params['delimiter'][$key], $date);
- if (count($dates) < 2 || count($dates) > 3) {
- return $date;
- }
- if ($params['format'][$key] == 'ampm') {
- if (strpos(strtolower($dates[count($dates)-1]), 'pm') !== false) {
- if ($dates[0] !== '12') {
- $dates[0] += 12;
- }
- } elseif ($dates[0] == '12') {
- $dates[0] = '0';
- }
- $dates[count($dates) - 1] = sprintf('%02d', $dates[count($dates)-1]);
- }
- return $dates[0] . ':' . $dates[1] . (count($dates) == 3 ? (':' . $dates[2]) : ':00');
-
- case 'datetime':
- switch ($params['order'][$key]) {
- case -1:
- return (string)(int)$date == $date
- ? date('Y-m-d H:i:s', $date)
- : $date;
- case 0:
- list($day, $time) = explode(' ', $date, 2);
- break;
- case 1:
- list($time, $day) = explode(' ', $date, 2);
- break;
- }
- $date = $this->mapDate($day, 'date',
- array('delimiter' => $params['day_delimiter'],
- 'format' => $params['day_format']),
- $key);
- $time = $this->mapDate($time, 'time',
- array('delimiter' => $params['time_delimiter'],
- 'format' => $params['time_format']),
- $key);
- return $date . ' ' . $time;
-
- }
- }
-
- /**
- * Takes all necessary actions for the given import step, parameters and
- * form values and returns the next necessary step.
- *
- * @param integer $action The current step. One of the IMPORT_* constants.
- * @param array $param An associative array containing needed
- * parameters for the current step.
- *
- * @return mixed Either the next step as an integer constant or imported
- * data set after the final step.
- */
- function nextStep($action, $param = array())
- {
- /* First step. */
- if (is_null($action)) {
- $_SESSION['import_data'] = array();
- return self::IMPORT_FILE;
- }
-
- switch ($action) {
- case self::IMPORT_FILE:
- /* Sanitize uploaded file. */
- $import_format = Horde_Util::getFormData('import_format');
- try {
- $GLOBALS['browser']->wasFileUploaded('import_file', $param['file_types'][$import_format]);
- } catch (Horde_Exception $e) {
- PEAR::raiseError($e->getMessage());
- }
- if ($_FILES['import_file']['size'] <= 0) {
- return PEAR::raiseError(_("The file contained no data."));
- }
- $_SESSION['import_data']['format'] = $import_format;
- break;
-
- case self::IMPORT_MAPPED:
- $dataKeys = Horde_Util::getFormData('dataKeys', '');
- $appKeys = Horde_Util::getFormData('appKeys', '');
- if (empty($dataKeys) || empty($appKeys)) {
- global $registry;
- return PEAR::raiseError(sprintf(_("You didn't map any fields from the imported file to the corresponding fields in %s."),
- $registry->get('name')));
- }
- $dataKeys = explode("\t", $dataKeys);
- $appKeys = explode("\t", $appKeys);
- $map = array();
- $dates = array();
- foreach ($appKeys as $key => $app) {
- $map[$dataKeys[$key]] = $app;
- if (isset($param['time_fields']) &&
- isset($param['time_fields'][$app])) {
- $dates[$dataKeys[$key]]['type'] = $param['time_fields'][$app];
- $dates[$dataKeys[$key]]['values'] = array();
- $i = 0;
- /* Build an example array of up to 10 date/time fields. */
- while ($i < count($_SESSION['import_data']['data']) && count($dates[$dataKeys[$key]]['values']) < 10) {
- if (!empty($_SESSION['import_data']['data'][$i][$dataKeys[$key]])) {
- $dates[$dataKeys[$key]]['values'][] = $_SESSION['import_data']['data'][$i][$dataKeys[$key]];
- }
- $i++;
- }
- }
- }
- $_SESSION['import_data']['map'] = $map;
- if (count($dates) > 0) {
- foreach ($dates as $key => $data) {
- if (count($data['values'])) {
- $_SESSION['import_data']['dates'] = $dates;
- return self::IMPORT_DATETIME;
- }
- }
- }
- return $this->nextStep(self::IMPORT_DATA, $param);
-
- case self::IMPORT_DATETIME:
- case self::IMPORT_DATA:
- if ($action == self::IMPORT_DATETIME) {
- $params = array('delimiter' => Horde_Util::getFormData('delimiter'),
- 'format' => Horde_Util::getFormData('format'),
- 'order' => Horde_Util::getFormData('order'),
- 'day_delimiter' => Horde_Util::getFormData('day_delimiter'),
- 'day_format' => Horde_Util::getFormData('day_format'),
- 'time_delimiter' => Horde_Util::getFormData('time_delimiter'),
- 'time_format' => Horde_Util::getFormData('time_format'));
- }
- if (!isset($_SESSION['import_data']['data'])) {
- return PEAR::raiseError(_("The uploaded data was lost since the previous step."));
- }
- /* Build the result data set as an associative array. */
- $data = array();
- foreach ($_SESSION['import_data']['data'] as $row) {
- $data_row = array();
- foreach ($row as $key => $val) {
- if (isset($_SESSION['import_data']['map'][$key])) {
- $mapped_key = $_SESSION['import_data']['map'][$key];
- if ($action == self::IMPORT_DATETIME &&
- !empty($val) &&
- isset($param['time_fields']) &&
- isset($param['time_fields'][$mapped_key])) {
- $val = $this->mapDate($val, $param['time_fields'][$mapped_key], $params, $key);
- }
- $data_row[$_SESSION['import_data']['map'][$key]] = $val;
- }
- }
- $data[] = $data_row;
- }
- return $data;
- }
- }
-
- /**
- * Cleans the session data up and removes any uploaded and moved
- * files. If a function called "_cleanup()" exists, this gets
- * called too.
- *
- * @return mixed If _cleanup() was called, the return value of this call.
- * This should be the value of the first import step.
- */
- function cleanup()
- {
- if (isset($_SESSION['import_data']['file_name'])) {
- @unlink($_SESSION['import_data']['file_name']);
- }
- $_SESSION['import_data'] = array();
- if (function_exists('_cleanup')) {
- return _cleanup();
- }
- }
-
-}
+++ /dev/null
-<?php
-/**
- * @package Horde_Data
- */
-
-/**
- * Horde_Data implementation for comma-separated data (CSV).
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_csv extends Horde_Data {
-
- var $_extension = 'csv';
- var $_contentType = 'text/comma-separated-values';
-
- /**
- * Tries to discover the CSV file's parameters.
- *
- * @param string $filename The name of the file to investigate.
- *
- * @return array An associative array with the following possible keys:
- * <pre>
- * 'sep': The field separator
- * 'quote': The quoting character
- * 'fields': The number of fields (columns)
- * </pre>
- */
- function discoverFormat($filename)
- {
- return Horde_File_Csv::discoverFormat($filename);
- }
-
- /**
- * Imports and parses a CSV file.
- *
- * @param string $filename The name of the file to parse.
- * @param boolean $header Does the first line contain the field/column
- * names?
- * @param string $sep The field/column separator.
- * @param string $quote The quoting character.
- * @param integer $fields The number or fields/columns.
- * @param string $charset The file's charset. @since Horde 3.1.
- * @param string $crlf The file's linefeed characters. @since Horde 3.1.
- *
- * @return array A two-dimensional array of all imported data rows. If
- * $header was true the rows are associative arrays with the
- * field/column names as the keys.
- *@throws Horde_File_Csv_Exception
- */
- function importFile($filename, $header = false, $sep = '', $quote = '',
- $fields = null, $import_mapping = array(),
- $charset = null, $crlf = null)
- {
- /* Horde_File_Csv is a bit picky at what parameters it expects. */
- $conf = array();
- if ($fields) {
- $conf['fields'] = $fields;
- } else {
- return array();
- }
- if (!empty($quote)) {
- $conf['quote'] = $quote;
- }
- if (empty($sep)) {
- $conf['sep'] = ',';
- } else {
- $conf['sep'] = $sep;
- }
- if (!empty($crlf)) {
- $conf['crlf'] = $crlf;
- }
-
- /* Strip and keep the first line if it contains the field
- * names. */
- if ($header) {
- $head = Horde_File_Csv::read($filename, $conf);
- if (!empty($charset)) {
- $head = Horde_String::convertCharset($head, $charset, Horde_Nls::getCharset());
- }
- }
-
- $data = array();
- while ($line = Horde_File_Csv::read($filename, $conf)) {
- if (!empty($charset)) {
- $line = Horde_String::convertCharset($line, $charset, Horde_Nls::getCharset());
- }
- if (!isset($head)) {
- $data[] = $line;
- } else {
- $newline = array();
- for ($i = 0; $i < count($head); $i++) {
- if (isset($import_mapping[$head[$i]])) {
- $head[$i] = $import_mapping[$head[$i]];
- }
- $cell = $line[$i];
- $cell = preg_replace("/\"\"/", "\"", $cell);
- $newline[$head[$i]] = empty($cell) ? '' : $cell;
- }
- $data[] = $newline;
- }
- }
-
- $fp = Horde_File_Csv::getPointer($filename, $conf);
- if ($fp) {
- rewind($fp);
- }
-
- $this->_warnings = Horde_File_Csv::warning();
- return $data;
- }
-
- /**
- * Builds a CSV file from a given data structure and returns it as a
- * string.
- *
- * @param array $data A two-dimensional array containing the data set.
- * @param boolean $header If true, the rows of $data are associative
- * arrays with field names as their keys.
- *
- * @return string The CSV data.
- */
- function exportData($data, $header = false, $export_mapping = array())
- {
- if (!is_array($data) || count($data) == 0) {
- return '';
- }
-
- $export = '';
- $eol = "\n";
- $head = array_keys(current($data));
- if ($header) {
- foreach ($head as $key) {
- if (!empty($key)) {
- if (isset($export_mapping[$key])) {
- $key = $export_mapping[$key];
- }
- $export .= '"' . $key . '"';
- }
- $export .= ',';
- }
- $export = substr($export, 0, -1) . $eol;
- }
-
- foreach ($data as $row) {
- foreach ($head as $key) {
- $cell = $row[$key];
- if (!empty($cell) || $cell === 0) {
- $export .= '"' . $cell . '"';
- }
- $export .= ',';
- }
- $export = substr($export, 0, -1) . $eol;
- }
-
- return $export;
- }
-
- /**
- * Builds a CSV file from a given data structure and triggers its
- * download. It DOES NOT exit the current script but only outputs the
- * correct headers and data.
- *
- * @param string $filename The name of the file to be downloaded.
- * @param array $data A two-dimensional array containing the data
- * set.
- * @param boolean $header If true, the rows of $data are associative
- * arrays with field names as their keys.
- */
- function exportFile($filename, $data, $header = false,
- $export_mapping = array())
- {
- $export = $this->exportData($data, $header, $export_mapping);
- $GLOBALS['browser']->downloadHeaders($filename, 'application/csv', false, strlen($export));
- echo $export;
- }
-
- /**
- * Takes all necessary actions for the given import step, parameters and
- * form values and returns the next necessary step.
- *
- * @param integer $action The current step. One of the IMPORT_* constants.
- * @param array $param An associative array containing needed
- * parameters for the current step.
- *
- * @return mixed Either the next step as an integer constant or imported
- * data set after the final step.
- */
- function nextStep($action, $param = array())
- {
- switch ($action) {
- case self::IMPORT_FILE:
- $next_step = parent::nextStep($action, $param);
- if (is_a($next_step, 'PEAR_Error')) {
- return $next_step;
- }
-
- /* Move uploaded file so that we can read it again in the next
- step after the user gave some format details. */
- $file_name = Horde::getTempFile('import', false);
- if (!move_uploaded_file($_FILES['import_file']['tmp_name'], $file_name)) {
- return PEAR::raiseError(_("The uploaded file could not be saved."));
- }
- $_SESSION['import_data']['file_name'] = $file_name;
-
- /* Try to discover the file format ourselves. */
- $conf = $this->discoverFormat($file_name);
- if (!$conf) {
- $conf = array('sep' => ',');
- }
- $_SESSION['import_data'] = array_merge($_SESSION['import_data'], $conf);
-
- /* Check if charset was specified. */
- $_SESSION['import_data']['charset'] = Horde_Util::getFormData('charset');
-
- /* Read the file's first two lines to show them to the user. */
- $_SESSION['import_data']['first_lines'] = '';
- $fp = @fopen($file_name, 'r');
- if ($fp) {
- $line_no = 1;
- while ($line_no < 3 && $line = fgets($fp)) {
- if (!empty($_SESSION['import_data']['charset'])) {
- $line = Horde_String::convertCharset($line, $_SESSION['import_data']['charset'], Horde_Nls::getCharset());
- }
- $newline = Horde_String::length($line) > 100 ? "\n" : '';
- $_SESSION['import_data']['first_lines'] .= substr($line, 0, 100) . $newline;
- $line_no++;
- }
- }
- return self::IMPORT_CSV;
-
- case self::IMPORT_CSV:
- $_SESSION['import_data']['header'] = Horde_Util::getFormData('header');
- $import_mapping = array();
- if (isset($param['import_mapping'])) {
- $import_mapping = $param['import_mapping'];
- }
- $import_data = $this->importFile($_SESSION['import_data']['file_name'],
- $_SESSION['import_data']['header'],
- Horde_Util::getFormData('sep'),
- Horde_Util::getFormData('quote'),
- Horde_Util::getFormData('fields'),
- $import_mapping,
- $_SESSION['import_data']['charset'],
- $_SESSION['import_data']['crlf']);
- $_SESSION['import_data']['data'] = $import_data;
- unset($_SESSION['import_data']['map']);
- return self::IMPORT_MAPPED;
-
- default:
- return parent::nextStep($action, $param);
- }
- }
-
-}
+++ /dev/null
-<?php
-
-/** We rely on the Horde_Data_imc:: abstract class. */
-require_once dirname(__FILE__) . '/imc.php';
-
-/**
- * This is iCalendar (vCalendar).
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @author Karsten Fourmont <fourmont@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_icalendar extends Horde_Data_imc {
-
-}
+++ /dev/null
-<?php
-/**
- * Abstract implementation of the Horde_Data:: API for IMC data -
- * vCards and iCalendar data, etc. Provides a number of utility
- * methods that vCard and iCalendar implementation can share and rely
- * on.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_imc extends Horde_Data {
-
- var $_iCal = false;
-
- function importData($text)
- {
- $this->_iCal = new Horde_iCalendar();
- if (!$this->_iCal->parsevCalendar($text)) {
- return PEAR::raiseError(_("There was an error importing the iCalendar data."));
- }
-
- return $this->_iCal->getComponents();
- }
-
- /**
- * Builds an iCalendar file from a given data structure and
- * returns it as a string.
- *
- * @param array $data An array containing Horde_iCalendar_vevent
- * objects
- * @param string $method The iTip method to use.
- *
- * @return string The iCalendar data.
- */
- function exportData($data, $method = 'REQUEST')
- {
- $this->_iCal = new Horde_iCalendar();
- $this->_iCal->setAttribute('METHOD', $method);
-
- foreach ($data as $event) {
- $this->_iCal->addComponent($event);
- }
-
- return $this->_iCal->exportvCalendar();
- }
-
- /**
- * Builds an iCalendar file from a given data structure and
- * triggers its download. It DOES NOT exit the current script but
- * only outputs the correct headers and data.
- *
- * @param string $filename The name of the file to be downloaded.
- * @param array $data An array containing Horde_iCalendar_vevents
- */
- function exportFile($filename, $data)
- {
- $export = $this->exportData($data);
- $GLOBALS['browser']->downloadHeaders($filename, 'text/calendar', false, strlen($export));
- echo $export;
- }
-
- /**
- * Takes all necessary actions for the given import step,
- * parameters and form values and returns the next necessary step.
- *
- * @param integer $action The current step. One of the IMPORT_* constants.
- * @param array $param An associative array containing needed
- * parameters for the current step.
- * @return mixed Either the next step as an integer constant or imported
- * data set after the final step.
- */
- function nextStep($action, $param = array())
- {
- switch ($action) {
- case self::IMPORT_FILE:
- $next_step = parent::nextStep($action, $param);
- if (is_a($next_step, 'PEAR_Error')) {
- return $next_step;
- }
-
- $import_data = $this->importFile($_FILES['import_file']['tmp_name']);
- if (is_a($import_data, 'PEAR_Error')) {
- return $import_data;
- }
-
- return $this->_iCal->getComponents();
- break;
-
- default:
- return parent::nextStep($action, $param);
- break;
- }
- }
-
-}
+++ /dev/null
-<?php
-
-require_once 'Horde/Data/csv.php';
-
-/**
- * Horde_Data implementation for Outlook comma-separated data (CSV).
- *
- * @package Horde_Data
- */
-class Horde_Data_outlookcsv extends Horde_Data_csv {
-
- /**
- * Builds a CSV file from a given data structure and returns it as a
- * string.
- *
- * @param array $data A two-dimensional array containing the data
- * set.
- * @param boolean $header If true, the rows of $data are associative
- * arrays with field names as their keys.
- *
- * @return string The CSV data.
- */
- function exportData($data, $header = false, $export_mapping = array())
- {
- if (!is_array($data) || count($data) == 0) {
- return '';
- }
-
- $export = '';
- $eol = "\r\n";
- $head = array_keys(current($data));
- if ($header) {
- foreach ($head as $key) {
- if (!empty($key)) {
- if (isset($export_mapping[$key])) {
- $key = $export_mapping[$key];
- }
- $export .= '"' . $key . '"';
- }
- $export .= ',';
- }
- $export = substr($export, 0, -1) . $eol;
- }
-
- foreach ($data as $row) {
- foreach ($head as $key) {
- $cell = $row[$key];
- if (!empty($cell) || $cell === 0) {
- $cell = preg_replace("/\"/", "\"\"", $cell);
- $export .= '"' . $cell . '"';
- }
- $export .= ',';
- }
- $export = substr($export, 0, -1) . $eol;
- }
-
- return $export;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_Data implementation for tab-separated data (TSV).
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_tsv extends Horde_Data {
-
- var $_extension = 'tsv';
- var $_contentType = 'text/tab-separated-values';
-
- /**
- * Convert data file contents to list of data records.
- *
- * @param string $contents Data file contents.
- * @param boolean $header True if a header row is present.
- * @param string $delimiter Field delimiter.
- *
- * @return array List of data records.
- */
- function importData($contents, $header = false, $delimiter = "\t")
- {
- if ($_SESSION['import_data']['format'] == 'pine') {
- $contents = preg_replace('/\n +/', '', $contents);
- }
- $contents = explode("\n", $contents);
- $data = array();
- if ($header) {
- $head = explode($delimiter, array_shift($contents));
- }
- foreach ($contents as $line) {
- if (trim($line) == '') {
- continue;
- }
- $line = explode($delimiter, $line);
- if (!isset($head)) {
- $data[] = $line;
- } else {
- $newline = array();
- for ($i = 0; $i < count($head); $i++) {
- $newline[$head[$i]] = empty($line[$i]) ? '' : $line[$i];
- }
- $data[] = $newline;
- }
- }
- return $data;
- }
-
- /**
- * Builds a TSV file from a given data structure and returns it as a
- * string.
- *
- * @param array $data A two-dimensional array containing the data set.
- * @param boolean $header If true, the rows of $data are associative
- * arrays with field names as their keys.
- *
- * @return string The TSV data.
- */
- function exportData($data, $header = false)
- {
- if (!is_array($data) || count($data) == 0) {
- return '';
- }
- $export = '';
- $head = array_keys(current($data));
- if ($header) {
- $export = implode("\t", $head) . "\n";
- }
- foreach ($data as $row) {
- foreach ($head as $key) {
- $cell = $row[$key];
- if (!empty($cell) || $cell === 0) {
- $export .= $cell;
- }
- $export .= "\t";
- }
- $export = substr($export, 0, -1) . "\n";
- }
- return $export;
- }
-
- /**
- * Builds a TSV file from a given data structure and triggers its download.
- * It DOES NOT exit the current script but only outputs the correct headers
- * and data.
- *
- * @param string $filename The name of the file to be downloaded.
- * @param array $data A two-dimensional array containing the data
- * set.
- * @param boolean $header If true, the rows of $data are associative
- * arrays with field names as their keys.
- */
- function exportFile($filename, $data, $header = false)
- {
- $export = $this->exportData($data, $header);
- $GLOBALS['browser']->downloadHeaders($filename, 'text/tab-separated-values', false, strlen($export));
- echo $export;
- }
-
- /**
- * Takes all necessary actions for the given import step, parameters and
- * form values and returns the next necessary step.
- *
- * @param integer $action The current step. One of the IMPORT_* constants.
- * @param array $param An associative array containing needed
- * parameters for the current step.
- *
- * @return mixed Either the next step as an integer constant or imported
- * data set after the final step.
- */
- function nextStep($action, $param = array())
- {
- switch ($action) {
- case self::IMPORT_FILE:
- $next_step = parent::nextStep($action, $param);
- if (is_a($next_step, 'PEAR_Error')) {
- return $next_step;
- }
-
- if ($_SESSION['import_data']['format'] == 'mulberry' ||
- $_SESSION['import_data']['format'] == 'pine') {
- $_SESSION['import_data']['data'] = $this->importFile($_FILES['import_file']['tmp_name']);
- $format = $_SESSION['import_data']['format'];
- if ($format == 'mulberry') {
- $appKeys = array('alias', 'name', 'email', 'company', 'workAddress', 'workPhone', 'homePhone', 'fax', 'notes');
- $dataKeys = array(0, 1, 2, 3, 4, 5, 6, 7, 9);
- } elseif ($format == 'pine') {
- $appKeys = array('alias', 'name', 'email', 'notes');
- $dataKeys = array(0, 1, 2, 4);
- }
- foreach ($appKeys as $key => $app) {
- $map[$dataKeys[$key]] = $app;
- }
- $data = array();
- foreach ($_SESSION['import_data']['data'] as $row) {
- $hash = array();
- if ($format == 'mulberry') {
- if (preg_match("/^Grp:/", $row[0]) || empty($row[1])) {
- continue;
- }
- $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
- foreach ($dataKeys as $key) {
- if (array_key_exists($key, $row)) {
- $hash[$key] = stripslashes(preg_replace('/\\\\r/', "\n", $row[$key]));
- }
- }
- } elseif ($format == 'pine') {
- if (count($row) < 3 || preg_match("/^#DELETED/", $row[0]) || preg_match("/[()]/", $row[2])) {
- continue;
- }
- $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
- /* Address can be a full RFC822 address */
- try {
- $addr_arr = Horde_Mime_Address::parseAddressList($row[2]);
- } catch (Horde_Mime_Exception $e) {
- continue;
- }
- if (empty($addr_arr[0]->mailbox)) {
- continue;
- }
- $row[2] = $addr_arr[0]->mailbox . '@' . $addr_arr[0]->host;
- if (empty($row[1]) && !empty($addr_arr[0]->personal)) {
- $row[1] = $addr_arr[0]->personal;
- }
- foreach ($dataKeys as $key) {
- if (array_key_exists($key, $row)) {
- $hash[$key] = $row[$key];
- }
- }
- }
- $data[] = $hash;
- }
- $_SESSION['import_data']['data'] = $data;
- $_SESSION['import_data']['map'] = $map;
- $ret = $this->nextStep(self::IMPORT_DATA, $param);
- return $ret;
- }
-
- /* Move uploaded file so that we can read it again in the next step
- after the user gave some format details. */
- try {
- $GLOBALS['browser']->wasFileUploaded('import_file', _("TSV file"));
- } catch (Horde_Browser_Exception $e) {
- return PEAR::raiseError($e->getMessage());
- }
- $file_name = Horde::getTempFile('import', false);
- if (!move_uploaded_file($_FILES['import_file']['tmp_name'], $file_name)) {
- return PEAR::raiseError(_("The uploaded file could not be saved."));
- }
- $_SESSION['import_data']['file_name'] = $file_name;
-
- /* Read the file's first two lines to show them to the user. */
- $_SESSION['import_data']['first_lines'] = '';
- $fp = @fopen($file_name, 'r');
- if ($fp) {
- $line_no = 1;
- while ($line_no < 3 && $line = fgets($fp)) {
- $newline = Horde_String::length($line) > 100 ? "\n" : '';
- $_SESSION['import_data']['first_lines'] .= substr($line, 0, 100) . $newline;
- $line_no++;
- }
- }
- return self::IMPORT_TSV;
- break;
-
- case self::IMPORT_TSV:
- $_SESSION['import_data']['header'] = Horde_Util::getFormData('header');
- $import_data = $this->importFile($_SESSION['import_data']['file_name'],
- $_SESSION['import_data']['header']);
- $_SESSION['import_data']['data'] = $import_data;
- unset($_SESSION['import_data']['map']);
- return self::IMPORT_MAPPED;
- break;
-
- default:
- return parent::nextStep($action, $param);
- break;
- }
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implement the Horde_Data:: API for vCard data.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_vcard extends Horde_Data_imc {
-
- /**
- * Exports vcalendar data as a string. Unlike vEvent, vCard data
- * is not enclosed in BEGIN|END:vCalendar.
- *
- * @param array $data An array containing Horde_iCalendar_vcard
- * objects.
- * @param string $method The iTip method to use.
- *
- * @return string The iCalendar data.
- */
- function exportData($data, $method = 'REQUEST')
- {
- $s = '';
- foreach ($data as $vcard) {
- $s.= $vcard->exportvCalendar();
- }
- return $s;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implement the Horde_Data:: API for vNote data.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_vnote extends Horde_Data_imc {
-
- /**
- * Exports vcalendar data as a string. Unlike vEvent, vNote data
- * is not enclosed in BEGIN|END:vCalendar.
- *
- * @param array $data An array containing Horde_iCalendar_vnote
- * objects.
- * @param string $method The iTip method to use.
- *
- * @return string The iCalendar data.
- */
- function exportData($data, $method = 'REQUEST')
- {
- global $prefs;
-
- $this->_iCal = new Horde_iCalendar();
-
- $this->_iCal->setAttribute('METHOD', $method);
- $s = '';
- foreach ($data as $event) {
- $s.= $event->exportvCalendar();
- }
- return $s;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Implement the Horde_Data:: API for vTodo data.
- *
- * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Jan Schneider <jan@horde.org>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_Data
- */
-class Horde_Data_vtodo extends Horde_Data_imc {
-
-}
--- /dev/null
+<?php
+/**
+ * Abstract class to handle different kinds of Data formats and to
+ * help data exchange between Horde applications and external sources.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data
+{
+ /* Import already mapped csv data. */
+ const IMPORT_MAPPED = 1;
+ /* Map date and time entries of csv data. */
+ const IMPORT_DATETIME = 2;
+ /* Import generic CSV data. */
+ const IMPORT_CSV = 3;
+ /* Import MS Outlook data. */
+ const IMPORT_OUTLOOK = 4;
+ /* Import vCalendar/iCalendar data. */
+ const IMPORT_ICALENDAR = 5;
+ /* Import vCards. */
+ const IMPORT_VCARD = 6;
+ /* Import generic tsv data. */
+ const IMPORT_TSV = 7;
+ /* Import Mulberry address book data. */
+ const IMPORT_MULBERRY = 8;
+ /* Import Pine address book data. */
+ const IMPORT_PINE = 9;
+ /* Import file. */
+ const IMPORT_FILE = 11;
+ /* Import data. */
+ const IMPORT_DATA = 12;
+
+ /* Export generic CSV data. */
+ const EXPORT_CSV = 100;
+ /* Export iCalendar data. */
+ const EXPORT_ICALENDAR = 101;
+ /* Export vCards. */
+ const EXPORT_VCARD = 102;
+ /* Export TSV data. */
+ const EXPORT_TSV = 103;
+ /* Export Outlook CSV data. */
+ const EXPORT_OUTLOOKCSV = 104;
+
+ /**
+ * Attempts to return a concrete instance based on $format.
+ *
+ * @param string $format The type of concrete subclass to return.
+ * @param array $params Parameters to pass to the format driver.
+ *
+ * @return Horde_Data_Driver The newly created concrete instance.
+ * @throws Horde_Data_Exception
+ */
+ public function factory($format, array $params = array())
+ {
+ $format = ucfirst(strtolower(basename($format)));
+ $class = __CLASS__ . '_' . $format;
+
+ if (class_exists($class)) {
+ return new $class($params);
+ }
+
+ throw new Horde_Data_Exception('Driver not found: ' . $driver);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * @category Horde
+ * @package Data
+ */
+
+/**
+ * Horde_Data implementation for comma-separated data (CSV).
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Csv extends Horde_Data_Driver
+{
+ /**
+ * File extension.
+ *
+ * @var string
+ */
+ protected $_extension = 'csv';
+
+ /**
+ * MIME content type.
+ *
+ * @var string
+ */
+ protected $_contentType = 'text/comma-separated-values';
+
+ /**
+ * Tries to discover the CSV file's parameters.
+ *
+ * @param string $filename The name of the file to investigate.
+ *
+ * @return array An associative array with the following possible keys:
+ * <pre>
+ * 'sep': The field separator
+ * 'quote': The quoting character
+ * 'fields': The number of fields (columns)
+ * </pre>
+ */
+ public function discoverFormat($filename)
+ {
+ return Horde_File_Csv::discoverFormat($filename);
+ }
+
+ /**
+ * Imports and parses a CSV file.
+ *
+ * @param string $filename The name of the file to parse.
+ * @param boolean $header Does the first line contain the field/column
+ * names?
+ * @param string $sep The field/column separator.
+ * @param string $quote The quoting character.
+ * @param integer $fields The number or fields/columns.
+ * @param string $charset The file's charset.
+ * @param string $crlf The file's linefeed characters.
+ *
+ * @return array A two-dimensional array of all imported data rows. If
+ * $header was true the rows are associative arrays with the
+ * field/column names as the keys.
+ *@throws Horde_File_Csv_Exception
+ */
+ public function importFile($filename, $header = false, $sep = ',',
+ $quote = '', $fields = null,
+ $import_mapping = array(), $charset = null,
+ $crlf = null)
+ {
+ if (empty($fields)) {
+ return array();
+ }
+
+ $conf = array(
+ 'crlf' => $crlf,
+ 'fields' => $fields,
+ 'quote' => $quote,
+ 'sep' => $sep
+ );
+
+ /* Strip and keep the first line if it contains the field
+ * names. */
+ if ($header) {
+ $head = Horde_File_Csv::read($filename, $conf);
+ if (!empty($charset)) {
+ $head = Horde_String::convertCharset($head, $charset, Horde_Nls::getCharset());
+ }
+ }
+
+ $data = array();
+ while ($line = Horde_File_Csv::read($filename, $conf)) {
+ if (!empty($charset)) {
+ $line = Horde_String::convertCharset($line, $charset, Horde_Nls::getCharset());
+ }
+ if (!isset($head)) {
+ $data[] = $line;
+ } else {
+ $newline = array();
+ for ($i = 0; $i < count($head); $i++) {
+ if (isset($import_mapping[$head[$i]])) {
+ $head[$i] = $import_mapping[$head[$i]];
+ }
+ $cell = $line[$i];
+ $cell = preg_replace("/\"\"/", "\"", $cell);
+ $newline[$head[$i]] = empty($cell) ? '' : $cell;
+ }
+ $data[] = $newline;
+ }
+ }
+
+ $fp = Horde_File_Csv::getPointer($filename, $conf);
+ if ($fp) {
+ rewind($fp);
+ }
+
+ $this->_warnings = Horde_File_Csv::warning();
+
+ return $data;
+ }
+
+ /**
+ * Builds a CSV file from a given data structure and returns it as a
+ * string.
+ *
+ * @param array $data A two-dimensional array containing the data set.
+ * @param boolean $header If true, the rows of $data are associative
+ * arrays with field names as their keys.
+ *
+ * @return string The CSV data.
+ */
+ public function exportData($data, $header = false,
+ $export_mapping = array())
+ {
+ if (!is_array($data) || count($data) == 0) {
+ return '';
+ }
+
+ $export = '';
+ $eol = "\n";
+ $head = array_keys(current($data));
+ if ($header) {
+ foreach ($head as $key) {
+ if (!empty($key)) {
+ if (isset($export_mapping[$key])) {
+ $key = $export_mapping[$key];
+ }
+ $export .= '"' . $key . '"';
+ }
+ $export .= ',';
+ }
+ $export = substr($export, 0, -1) . $eol;
+ }
+
+ foreach ($data as $row) {
+ foreach ($head as $key) {
+ $cell = $row[$key];
+ if (!empty($cell) || $cell === 0) {
+ $export .= '"' . $cell . '"';
+ }
+ $export .= ',';
+ }
+ $export = substr($export, 0, -1) . $eol;
+ }
+
+ return $export;
+ }
+
+ /**
+ * Builds a CSV file from a given data structure and triggers its
+ * download. It DOES NOT exit the current script but only outputs the
+ * correct headers and data.
+ *
+ * @param string $filename The name of the file to be downloaded.
+ * @param array $data A two-dimensional array containing the data
+ * set.
+ * @param boolean $header If true, the rows of $data are associative
+ * arrays with field names as their keys.
+ */
+ public function exportFile($filename, $data, $header = false,
+ $export_mapping = array())
+ {
+ $export = $this->exportData($data, $header, $export_mapping);
+ $this->_browser->downloadHeaders($filename, 'application/csv', false, strlen($export));
+ echo $export;
+ }
+
+ /**
+ * Takes all necessary actions for the given import step, parameters and
+ * form values and returns the next necessary step.
+ *
+ * @param integer $action The current step. One of the IMPORT_* constants.
+ * @param array $param An associative array containing needed
+ * parameters for the current step.
+ *
+ * @return mixed Either the next step as an integer constant or imported
+ * data set after the final step.
+ * @throws Horde_Data_Exception
+ */
+ public function nextStep($action, $param = array())
+ {
+ switch ($action) {
+ case Horde_Data::IMPORT_FILE:
+ parent::nextStep($action, $param);
+
+ /* Move uploaded file so that we can read it again in the next
+ step after the user gave some format details. */
+ $file_name = Horde_Util::getTempFile('import', false);
+ if (!move_uploaded_file($_FILES['import_file']['tmp_name'], $file_name)) {
+ throw new Horde_Data_Exception('The uploaded file could not be saved.');
+ }
+ $_SESSION['import_data']['file_name'] = $file_name;
+
+ /* Try to discover the file format ourselves. */
+ $conf = $this->discoverFormat($file_name);
+ if (!$conf) {
+ $conf = array('sep' => ',');
+ }
+ $_SESSION['import_data'] = array_merge($_SESSION['import_data'], $conf);
+
+ /* Check if charset was specified. */
+ $_SESSION['import_data']['charset'] = $this->_vars->charset;
+
+ /* Read the file's first two lines to show them to the user. */
+ $_SESSION['import_data']['first_lines'] = '';
+ $fp = @fopen($file_name, 'r');
+ if ($fp) {
+ $line_no = 1;
+ while ($line_no < 3 && $line = fgets($fp)) {
+ if (!empty($_SESSION['import_data']['charset'])) {
+ $line = Horde_String::convertCharset($line, $_SESSION['import_data']['charset'], Horde_Nls::getCharset());
+ }
+ $newline = Horde_String::length($line) > 100 ? "\n" : '';
+ $_SESSION['import_data']['first_lines'] .= substr($line, 0, 100) . $newline;
+ $line_no++;
+ }
+ }
+ return Horde_Data::IMPORT_CSV;
+
+ case Horde_Data::IMPORT_CSV:
+ $_SESSION['import_data']['header'] = $this->_vars->header;
+ $import_mapping = array();
+ if (isset($param['import_mapping'])) {
+ $import_mapping = $param['import_mapping'];
+ }
+ $import_data = $this->importFile(
+ $_SESSION['import_data']['file_name'],
+ $_SESSION['import_data']['header'],
+ $this->_vars->sep,
+ $this->_vars->quote,
+ $this->_vars->fields,
+ $import_mapping,
+ $_SESSION['import_data']['charset'],
+ $_SESSION['import_data']['crlf']
+ );
+ $_SESSION['import_data']['data'] = $import_data;
+ unset($_SESSION['import_data']['map']);
+ return Horde_Data::IMPORT_MAPPED;
+
+ default:
+ return parent::nextStep($action, $param);
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Abstract class that Data drivers extend.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+abstract class Horde_Data
+{
+ /**
+ * Browser object.
+ *
+ * @var Horde_Browser
+ */
+ protected $_browser;
+
+ /**
+ * File extension.
+ *
+ * @var string
+ */
+ protected $_extension = '';
+
+ /**
+ * MIME content type.
+ *
+ * @var string
+ */
+ protected $_contentType = 'text/plain';
+
+ /**
+ * Cleanup callback function.
+ *
+ * @var callback
+ */
+ protected $_cleanupCallback;
+
+ /**
+ * Variables object.
+ *
+ * @var Horde_Variables
+ */
+ protected $_vars;
+
+ /**
+ * A list of warnings raised during the last operation.
+ *
+ * @var array
+ */
+ protected $_warnings = array();
+
+ /**
+ * Constructor.
+ *
+ * @param array $params Optional parameters:
+ * <pre>
+ * 'browser' - (Horde_Browser) A Horde_Browser object.
+ * 'cleanup' - (callback) A callback to call at cleanup time.
+ * </pre>
+ *
+ * @throws Horde_Data_Exception
+ */
+ public function __construct(array $params = array())
+ {
+ if (!isset($params['browser'])) {
+ throw new Horde_Data_Exception('Missing browser parameter.');
+ }
+ $this->_browser = $params['browser'];
+
+ if (isset($params['cleanup']) &&
+ is_callable($params['cleanup'])) {
+ $this->_cleanupCallback = $params['cleanup'];
+ }
+
+ $this->_vars = isset($params['vars'])
+ ? $params['vars']
+ : Horde_Variables::getDefaultVariables();
+ }
+
+ /**
+ * Stub to import passed data.
+ */
+ abstract public function importData();
+
+ /**
+ * Stub to return exported data.
+ */
+ abstract public function exportData();
+
+ /**
+ * Stub to import a file.
+ */
+ public function importFile($filename, $header = false)
+ {
+ $data = file_get_contents($filename);
+ return $this->importData($data, $header);
+ }
+
+ /**
+ * Stub to export data to a file.
+ */
+ abstract public function exportFile();
+
+ /**
+ * Tries to determine the expected newline character based on the
+ * platform information passed by the browser's agent header.
+ *
+ * @return string The guessed expected newline characters, either \n, \r
+ * or \r\n.
+ */
+ public function getNewline()
+ {
+ switch ($this->_browser->getPlatform()) {
+ case 'win':
+ return "\r\n";
+
+ case 'mac':
+ return "\r";
+
+ case 'unix':
+ default:
+ return "\n";
+ }
+ }
+
+ /**
+ * Returns the full filename including the basename and extension.
+ *
+ * @param string $basename Basename for the file.
+ *
+ * @return string The file name.
+ */
+ public function getFilename($basename)
+ {
+ return $basename . '.' . $this->_extension;
+ }
+
+ /**
+ * Returns the content type.
+ *
+ * @return string The content type.
+ */
+ public function getContentType()
+ {
+ return $this->_contentType;
+ }
+
+ /**
+ * Returns a list of warnings that have been raised during the last
+ * operation.
+ *
+ * @return array A (possibly empty) list of warnings.
+ */
+ public function warnings()
+ {
+ return $this->_warnings;
+ }
+
+ /**
+ * Maps a date/time string to an associative array.
+ *
+ * @param string $date The date.
+ * @param string $type One of 'date', 'time' or 'datetime'.
+ * @param array $params Two-dimensional array with additional information
+ * about the formatting. Possible keys are:
+ * - delimiter - The character that seperates the
+ * different date/time parts.
+ * - format - If 'ampm' and $date contains a time we
+ * assume that it is in AM/PM format.
+ * - order - If $type is 'datetime' the order of the
+ * day and time parts: -1 (timestamp), 0
+ * (day/time), 1 (time/day).
+ * @param integer $key The key to use for $params.
+ *
+ * @return string The date or time in ISO format.
+ */
+ protected function _mapDate($date, $type, $params, $key)
+ {
+ switch ($type) {
+ case 'date':
+ case 'monthday':
+ case 'monthdayyear':
+ $dates = explode($params['delimiter'][$key], $date);
+ if (count($dates) != 3) {
+ return $date;
+ }
+ $index = array_flip(explode('/', $params['format'][$key]));
+ return $dates[$index['year']] . '-' . $dates[$index['month']] . '-' . $dates[$index['mday']];
+
+ case 'time':
+ $dates = explode($params['delimiter'][$key], $date);
+ if (count($dates) < 2 || count($dates) > 3) {
+ return $date;
+ }
+ if ($params['format'][$key] == 'ampm') {
+ if (strpos(strtolower($dates[count($dates)-1]), 'pm') !== false) {
+ if ($dates[0] !== '12') {
+ $dates[0] += 12;
+ }
+ } elseif ($dates[0] == '12') {
+ $dates[0] = '0';
+ }
+ $dates[count($dates) - 1] = sprintf('%02d', $dates[count($dates)-1]);
+ }
+ return $dates[0] . ':' . $dates[1] . (count($dates) == 3 ? (':' . $dates[2]) : ':00');
+
+ case 'datetime':
+ switch ($params['order'][$key]) {
+ case -1:
+ return (string)(int)$date == $date
+ ? date('Y-m-d H:i:s', $date)
+ : $date;
+ case 0:
+ list($day, $time) = explode(' ', $date, 2);
+ break;
+ case 1:
+ list($time, $day) = explode(' ', $date, 2);
+ break;
+ }
+ $date = $this->mapDate($day, 'date',
+ array('delimiter' => $params['day_delimiter'],
+ 'format' => $params['day_format']),
+ $key);
+ $time = $this->mapDate($time, 'time',
+ array('delimiter' => $params['time_delimiter'],
+ 'format' => $params['time_format']),
+ $key);
+ return $date . ' ' . $time;
+
+ }
+ }
+
+ /**
+ * Takes all necessary actions for the given import step, parameters and
+ * form values and returns the next necessary step.
+ *
+ * @param integer $action The current step. One of the IMPORT_* constants.
+ * @param array $param An associative array containing needed
+ * parameters for the current step.
+ *
+ * @return mixed Either the next step as an integer constant or imported
+ * data set after the final step.
+ * @throws Horde_Data_Exception
+ */
+ public function nextStep($action, $param = array())
+ {
+ /* First step. */
+ if (is_null($action)) {
+ $_SESSION['import_data'] = array();
+ return Horde_Data::IMPORT_FILE;
+ }
+
+ switch ($action) {
+ case Horde_Data::IMPORT_FILE:
+ /* Sanitize uploaded file. */
+ try {
+ $this->_browser->wasFileUploaded('import_file', $param['file_types'][$this->_vars->import_format]);
+ } catch (Horde_Exception $e) {
+ throw new Horde_Data_Exception($e);
+ }
+ if ($_FILES['import_file']['size'] <= 0) {
+ return PEAR::raiseError(_("The file contained no data."));
+ }
+ $_SESSION['import_data']['format'] = $this->_vars->import_format;
+ break;
+
+ case Horde_Data::IMPORT_MAPPED:
+ if (!$this->_vars->dataKeys || !$this->_vars->appKeys) {
+ throw new Horde_Data_Exception('You didn\'t map any fields from the imported file to the corresponding fields.');
+ }
+ $dataKeys = explode("\t", $this->_vars->dataKeys);
+ $appKeys = explode("\t", $this->_vars->appKeys);
+ $map = array();
+ $dates = array();
+ foreach ($appKeys as $key => $app) {
+ $map[$dataKeys[$key]] = $app;
+ if (isset($param['time_fields']) &&
+ isset($param['time_fields'][$app])) {
+ $dates[$dataKeys[$key]]['type'] = $param['time_fields'][$app];
+ $dates[$dataKeys[$key]]['values'] = array();
+ $i = 0;
+ /* Build an example array of up to 10 date/time fields. */
+ while ($i < count($_SESSION['import_data']['data']) && count($dates[$dataKeys[$key]]['values']) < 10) {
+ if (!empty($_SESSION['import_data']['data'][$i][$dataKeys[$key]])) {
+ $dates[$dataKeys[$key]]['values'][] = $_SESSION['import_data']['data'][$i][$dataKeys[$key]];
+ }
+ $i++;
+ }
+ }
+ }
+ $_SESSION['import_data']['map'] = $map;
+ if (count($dates) > 0) {
+ foreach ($dates as $key => $data) {
+ if (count($data['values'])) {
+ $_SESSION['import_data']['dates'] = $dates;
+ return Horde_Data::IMPORT_DATETIME;
+ }
+ }
+ }
+ return $this->nextStep(Horde_Data::IMPORT_DATA, $param);
+
+ case Horde_Data::IMPORT_DATETIME:
+ case Horde_Data::IMPORT_DATA:
+ if ($action == Horde_Data::IMPORT_DATETIME) {
+ $params = array(
+ 'delimiter' => $this->_vars->delimiter,
+ 'format' => $this->_vars->format,
+ 'order' => $this->_vars->order,
+ 'day_delimiter' => $this->_vars->day_delimiter,
+ 'day_format' => $this->_vars->day_format,
+ 'time_delimiter' => $this->_vars->time_delimiter,
+ 'time_format' => $this->_vars->time_format
+ );
+ }
+
+ if (!isset($_SESSION['import_data']['data'])) {
+ throw new Horde_Data_Exception('The uploaded data was lost since the previous step.');
+ }
+
+ /* Build the result data set as an associative array. */
+ $data = array();
+ foreach ($_SESSION['import_data']['data'] as $row) {
+ $data_row = array();
+ foreach ($row as $key => $val) {
+ if (isset($_SESSION['import_data']['map'][$key])) {
+ $mapped_key = $_SESSION['import_data']['map'][$key];
+ if ($action == Horde_Data::IMPORT_DATETIME &&
+ !empty($val) &&
+ isset($param['time_fields']) &&
+ isset($param['time_fields'][$mapped_key])) {
+ $val = $this->mapDate($val, $param['time_fields'][$mapped_key], $params, $key);
+ }
+ $data_row[$_SESSION['import_data']['map'][$key]] = $val;
+ }
+ }
+ $data[] = $data_row;
+ }
+ return $data;
+ }
+ }
+
+ /**
+ * Cleans the session data up and removes any uploaded and moved
+ * files.
+ *
+ * @return mixed If callback called, the return value of this call.
+ * This should be the value of the first import step.
+ */
+ public function cleanup()
+ {
+ if (isset($_SESSION['import_data']['file_name'])) {
+ @unlink($_SESSION['import_data']['file_name']);
+ }
+ $_SESSION['import_data'] = array();
+
+ if ($this->_cleanupCallback) {
+ return call_user_func($this->_cleanupCallback);
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Exception handler for the Horde_Data package.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Exception extends Horde_Exception_Prior
+{
+}
--- /dev/null
+<?php
+/**
+ * This is iCalendar (vCalendar).
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Karsten Fourmont <fourmont@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Icalendar extends Horde_Data_Imc {}
--- /dev/null
+<?php
+/**
+ * Abstract implementation of the Horde_Data:: API for IMC data -
+ * vCards and iCalendar data, etc. Provides a number of utility
+ * methods that vCard and iCalendar implementation can share and rely
+ * on.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Imc extends Horde_Data_Driver
+{
+ /**
+ * @var
+ */
+ protected $_iCal = false;
+
+ /**
+ *
+ * @throws Horde_Data_Exception
+ */
+ public function importData($text)
+ {
+ $this->_iCal = new Horde_iCalendar();
+ if (!$this->_iCal->parsevCalendar($text)) {
+ throw new Horde_Data_Exception('There was an error importing the iCalendar data.');
+ }
+
+ return $this->_iCal->getComponents();
+ }
+
+ /**
+ * Builds an iCalendar file from a given data structure and
+ * returns it as a string.
+ *
+ * @param array $data An array containing Horde_iCalendar_vevent
+ * objects
+ * @param string $method The iTip method to use.
+ *
+ * @return string The iCalendar data.
+ */
+ public function exportData($data, $method = 'REQUEST')
+ {
+ $this->_iCal = new Horde_iCalendar();
+ $this->_iCal->setAttribute('METHOD', $method);
+
+ foreach ($data as $event) {
+ $this->_iCal->addComponent($event);
+ }
+
+ return $this->_iCal->exportvCalendar();
+ }
+
+ /**
+ * Builds an iCalendar file from a given data structure and
+ * triggers its download. It DOES NOT exit the current script but
+ * only outputs the correct headers and data.
+ *
+ * @param string $filename The name of the file to be downloaded.
+ * @param array $data An array containing Horde_iCalendar_vevents
+ */
+ public function exportFile($filename, $data)
+ {
+ $export = $this->exportData($data);
+ $this->_browser->downloadHeaders($filename, 'text/calendar', false, strlen($export));
+ echo $export;
+ }
+
+ /**
+ * Takes all necessary actions for the given import step,
+ * parameters and form values and returns the next necessary step.
+ *
+ * @param integer $action The current step. One of the IMPORT_* constants.
+ * @param array $param An associative array containing needed
+ * parameters for the current step.
+ *
+ * @return mixed Either the next step as an integer constant or imported
+ * data set after the final step.
+ * @throws Horde_Data_Exception
+ */
+ public function nextStep($action, $param = array())
+ {
+ switch ($action) {
+ case Horde_Data::IMPORT_FILE:
+ parent::nextStep($action, $param);
+ $this->importFile($_FILES['import_file']['tmp_name']);
+ return $this->_iCal->getComponents();
+ }
+
+ return parent::nextStep($action, $param);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_Data implementation for Outlook comma-separated data (CSV).
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Outlookcsv extends Horde_Data_Csv
+{
+ /**
+ * Builds a CSV file from a given data structure and returns it as a
+ * string.
+ *
+ * @param array $data A two-dimensional array containing the data
+ * set.
+ * @param boolean $header If true, the rows of $data are associative
+ * arrays with field names as their keys.
+ *
+ * @return string The CSV data.
+ */
+ public function exportData($data, $header = false,
+ $export_mapping = array())
+ {
+ if (!is_array($data) || (count($data) == 0)) {
+ return '';
+ }
+
+ $export = '';
+ $eol = "\r\n";
+ $head = array_keys(current($data));
+
+ if ($header) {
+ foreach ($head as $key) {
+ if (!empty($key)) {
+ if (isset($export_mapping[$key])) {
+ $key = $export_mapping[$key];
+ }
+ $export .= '"' . $key . '"';
+ }
+ $export .= ',';
+ }
+ $export = substr($export, 0, -1) . $eol;
+ }
+
+ foreach ($data as $row) {
+ foreach ($head as $key) {
+ $cell = $row[$key];
+ if (!empty($cell) || $cell === 0) {
+ $cell = preg_replace("/\"/", "\"\"", $cell);
+ $export .= '"' . $cell . '"';
+ }
+ $export .= ',';
+ }
+ $export = substr($export, 0, -1) . $eol;
+ }
+
+ return $export;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_Data implementation for tab-separated data (TSV).
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Tsv extends Horde_Data_Driver
+{
+ /**
+ * File extension.
+ *
+ * @var string
+ */
+ protected $_extension = 'tsv';
+
+ /**
+ * MIME content type.
+ *
+ * @var string
+ */
+ protected $_contentType = 'text/tab-separated-values';
+
+ /**
+ * Convert data file contents to list of data records.
+ *
+ * @param string $contents Data file contents.
+ * @param boolean $header True if a header row is present.
+ * @param string $delimiter Field delimiter.
+ *
+ * @return array List of data records.
+ */
+ public function importData($contents, $header = false, $delimiter = "\t")
+ {
+ if ($_SESSION['import_data']['format'] == 'pine') {
+ $contents = preg_replace('/\n +/', '', $contents);
+ }
+
+ $contents = explode("\n", $contents);
+ $data = array();
+ if ($header) {
+ $head = explode($delimiter, array_shift($contents));
+ }
+
+ foreach ($contents as $line) {
+ if (trim($line) == '') {
+ continue;
+ }
+ $line = explode($delimiter, $line);
+ if (!isset($head)) {
+ $data[] = $line;
+ } else {
+ $newline = array();
+ for ($i = 0; $i < count($head); $i++) {
+ $newline[$head[$i]] = empty($line[$i]) ? '' : $line[$i];
+ }
+ $data[] = $newline;
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Builds a TSV file from a given data structure and returns it as a
+ * string.
+ *
+ * @param array $data A two-dimensional array containing the data set.
+ * @param boolean $header If true, the rows of $data are associative
+ * arrays with field names as their keys.
+ *
+ * @return string The TSV data.
+ */
+ public function exportData($data, $header = false)
+ {
+ if (!is_array($data) || count($data) == 0) {
+ return '';
+ }
+ $export = '';
+ $head = array_keys(current($data));
+ if ($header) {
+ $export = implode("\t", $head) . "\n";
+ }
+ foreach ($data as $row) {
+ foreach ($head as $key) {
+ $cell = $row[$key];
+ if (!empty($cell) || $cell === 0) {
+ $export .= $cell;
+ }
+ $export .= "\t";
+ }
+ $export = substr($export, 0, -1) . "\n";
+ }
+
+ return $export;
+ }
+
+ /**
+ * Builds a TSV file from a given data structure and triggers its download.
+ * It DOES NOT exit the current script but only outputs the correct headers
+ * and data.
+ *
+ * @param string $filename The name of the file to be downloaded.
+ * @param array $data A two-dimensional array containing the data
+ * set.
+ * @param boolean $header If true, the rows of $data are associative
+ * arrays with field names as their keys.
+ */
+ public function exportFile($filename, $data, $header = false)
+ {
+ $export = $this->exportData($data, $header);
+ $this->_browser->downloadHeaders($filename, 'text/tab-separated-values', false, strlen($export));
+ echo $export;
+ }
+
+ /**
+ * Takes all necessary actions for the given import step, parameters and
+ * form values and returns the next necessary step.
+ *
+ * @param integer $action The current step. One of the IMPORT_* constants.
+ * @param array $param An associative array containing needed
+ * parameters for the current step.
+ *
+ * @return mixed Either the next step as an integer constant or imported
+ * data set after the final step.
+ * @throws Horde_Data_Exception
+ */
+ public function nextStep($action, $param = array())
+ {
+ switch ($action) {
+ case Horde_Data::IMPORT_FILE:
+ parent::nextStep($action, $param);
+
+ if ($_SESSION['import_data']['format'] == 'mulberry' ||
+ $_SESSION['import_data']['format'] == 'pine') {
+ $_SESSION['import_data']['data'] = $this->importFile($_FILES['import_file']['tmp_name']);
+ $format = $_SESSION['import_data']['format'];
+ if ($format == 'mulberry') {
+ $appKeys = array('alias', 'name', 'email', 'company', 'workAddress', 'workPhone', 'homePhone', 'fax', 'notes');
+ $dataKeys = array(0, 1, 2, 3, 4, 5, 6, 7, 9);
+ } elseif ($format == 'pine') {
+ $appKeys = array('alias', 'name', 'email', 'notes');
+ $dataKeys = array(0, 1, 2, 4);
+ }
+ foreach ($appKeys as $key => $app) {
+ $map[$dataKeys[$key]] = $app;
+ }
+ $data = array();
+ foreach ($_SESSION['import_data']['data'] as $row) {
+ $hash = array();
+ if ($format == 'mulberry') {
+ if (preg_match("/^Grp:/", $row[0]) || empty($row[1])) {
+ continue;
+ }
+ $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
+ foreach ($dataKeys as $key) {
+ if (array_key_exists($key, $row)) {
+ $hash[$key] = stripslashes(preg_replace('/\\\\r/', "\n", $row[$key]));
+ }
+ }
+ } elseif ($format == 'pine') {
+ if (count($row) < 3 || preg_match("/^#DELETED/", $row[0]) || preg_match("/[()]/", $row[2])) {
+ continue;
+ }
+ $row[1] = preg_replace('/^([^,"]+),\s*(.*)$/', '$2 $1', $row[1]);
+ /* Address can be a full RFC822 address */
+ try {
+ $addr_arr = Horde_Mime_Address::parseAddressList($row[2]);
+ } catch (Horde_Mime_Exception $e) {
+ continue;
+ }
+ if (empty($addr_arr[0]->mailbox)) {
+ continue;
+ }
+ $row[2] = $addr_arr[0]->mailbox . '@' . $addr_arr[0]->host;
+ if (empty($row[1]) && !empty($addr_arr[0]->personal)) {
+ $row[1] = $addr_arr[0]->personal;
+ }
+ foreach ($dataKeys as $key) {
+ if (array_key_exists($key, $row)) {
+ $hash[$key] = $row[$key];
+ }
+ }
+ }
+ $data[] = $hash;
+ }
+ $_SESSION['import_data']['data'] = $data;
+ $_SESSION['import_data']['map'] = $map;
+ $ret = $this->nextStep(Horde_Data::IMPORT_DATA, $param);
+ return $ret;
+ }
+
+ /* Move uploaded file so that we can read it again in the next step
+ after the user gave some format details. */
+ try {
+ $this->_browser->wasFileUploaded('import_file', _("TSV file"));
+ } catch (Horde_Browser_Exception $e) {
+ throw new Horde_Data_Exception($e);
+ }
+ $file_name = Horde_Util::getTempFile('import', false);
+ if (!move_uploaded_file($_FILES['import_file']['tmp_name'], $file_name)) {
+ throw new Horde_Data_Exception('The uploaded file could not be saved.');
+ }
+ $_SESSION['import_data']['file_name'] = $file_name;
+
+ /* Read the file's first two lines to show them to the user. */
+ $_SESSION['import_data']['first_lines'] = '';
+ $fp = @fopen($file_name, 'r');
+ if ($fp) {
+ $line_no = 1;
+ while ($line_no < 3 && $line = fgets($fp)) {
+ $newline = Horde_String::length($line) > 100 ? "\n" : '';
+ $_SESSION['import_data']['first_lines'] .= substr($line, 0, 100) . $newline;
+ $line_no++;
+ }
+ }
+ return Horde_Data::IMPORT_TSV;
+
+ case Horde_Data::IMPORT_TSV:
+ $_SESSION['import_data']['header'] = $this->_vars->header;
+ $import_data = $this->importFile($_SESSION['import_data']['file_name'],
+ $_SESSION['import_data']['header']);
+ $_SESSION['import_data']['data'] = $import_data;
+ unset($_SESSION['import_data']['map']);
+ return Horde_Data::IMPORT_MAPPED;
+ }
+
+ return parent::nextStep($action, $param);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implement the Horde_Data:: API for vCard data.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Vcard extends Horde_Data_Imc {
+
+ /**
+ * Exports vcalendar data as a string. Unlike vEvent, vCard data
+ * is not enclosed in BEGIN|END:vCalendar.
+ *
+ * @param array $data An array containing Horde_iCalendar_Vcard
+ * objects.
+ * @param string $method The iTip method to use.
+ *
+ * @return string The iCalendar data.
+ */
+ public function exportData($data, $method = 'REQUEST')
+ {
+ $s = '';
+
+ foreach ($data as $vcard) {
+ $s.= $vcard->exportvCalendar();
+ }
+
+ return $s;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implement the Horde_Data:: API for vNote data.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Vnote extends Horde_Data_Imc
+{
+ /**
+ * Exports vcalendar data as a string. Unlike vEvent, vNote data
+ * is not enclosed in BEGIN|END:vCalendar.
+ *
+ * @param array $data An array containing Horde_iCalendar_Vnote
+ * objects.
+ * @param string $method The iTip method to use.
+ *
+ * @return string The iCalendar data.
+ */
+ public function exportData($data, $method = 'REQUEST')
+ {
+ $this->_iCal = new Horde_iCalendar();
+ $this->_iCal->setAttribute('METHOD', $method);
+
+ $s = '';
+ foreach ($data as $event) {
+ $s. = $event->exportvCalendar();
+ }
+
+ return $s;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Implement the Horde_Data:: API for vTodo data.
+ *
+ * Copyright 1999-2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @category Horde
+ * @package Data
+ */
+class Horde_Data_Vtodo extends Horde_Data_Imc {}
http://pear.php.net/dtd/tasks-1.0.xsd
http://pear.php.net/dtd/package-2.0
http://pear.php.net/dtd/package-2.0.xsd">
- <name>Horde_Data</name>
+ <name>Data</name>
<channel>pear.horde.org</channel>
<summary>Horde Data API</summary>
<description>This package provides a data import and export API, with backends for:
<email>chuck@horde.org</email>
<active>yes</active>
</developer>
- <date>2006-05-08</date>
- <time>21:12:22</time>
+ <date>2010-05-12</date>
<version>
- <release>0.0.3</release>
- <api>0.0.3</api>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>Converted to package.xml 2.0 for pear.horde.org
+ <notes>* Initial Horde 4 package.
</notes>
<contents>
<dir name="/">
- <dir name="Data">
- <file baseinstalldir="/Horde" name="csv.php" role="php" />
- <file baseinstalldir="/Horde" name="icalendar.php" role="php" />
- <file baseinstalldir="/Horde" name="imc.php" role="php" />
- <file baseinstalldir="/Horde" name="outlookcsv.php" role="php" />
- <file baseinstalldir="/Horde" name="tsv.php" role="php" />
- <file baseinstalldir="/Horde" name="vcard.php" role="php" />
- <file baseinstalldir="/Horde" name="vnote.php" role="php" />
- <file baseinstalldir="/Horde" name="vtodo.php" role="php" />
- </dir> <!-- /Data -->
- <dir name="tests">
- <file baseinstalldir="/Horde" name="csv_importFile_01.phpt" role="test" />
- <file baseinstalldir="/Horde" name="simple_dos.csv" role="test" />
- <file baseinstalldir="/Horde" name="simple_unix.csv" role="test" />
- </dir> <!-- /tests -->
- <file baseinstalldir="/Horde" name="Data.php" role="php" />
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Data">
+ <file name="Csv.php" role="php" />
+ <file name="Driver.php" role="php" />
+ <file name="Exception.php" role="php" />
+ <file name="Icalendar.php" role="php" />
+ <file name="Imc.php" role="php" />
+ <file name="Outlookcsv.php" role="php" />
+ <file name="Tsv.php" role="php" />
+ <file name="Vcard.php" role="php" />
+ <file name="Vnote.php" role="php" />
+ <file name="Vtodo.php" role="php" />
+ </dir> <!-- /lib/Horde/Data -->
+ <file name="Data.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ <dir name="test">
+ <dir name="Horde">
+ <dir name="Data">
+ <file name="csv_importFile_01.phpt" role="test" />
+ <file name="simple_dos.csv" role="test" />
+ <file name="simple_unix.csv" role="test" />
+ </dir> <!-- /test/Horde/Data -->
+ </dir> <!-- /test/Horde -->
+ </dir> <!-- /test -->
</dir> <!-- / -->
</contents>
<dependencies>
<min>1.7.0</min>
</pearinstaller>
<package>
- <name>iCalendar</name>
+ <name>Browser</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>Exception</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>File_Csv</name>
<channel>pear.horde.org</channel>
</package>
<package>
<name>Util</name>
<channel>pear.horde.org</channel>
</package>
+ <package>
+ <name>iCalendar</name>
+ <channel>pear.horde.org</channel>
+ </package>
</required>
- <optional>
- <extension>
- <name>gettext</name>
- </extension>
- </optional>
</dependencies>
- <phprelease />
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Data/Csv.php" as="Horde/Data/Csv.php" />
+ <install name="lib/Horde/Data/Driver.php" as="Horde/Data/Driver.php" />
+ <install name="lib/Horde/Data/Exception.php" as="Horde/Data/Exception.php" />
+ <install name="lib/Horde/Data/Icalendar.php" as="Horde/Data/Icalendar.php" />
+ <install name="lib/Horde/Data/Imc.php" as="Horde/Data/Imc.php" />
+ <install name="lib/Horde/Data/Outlookcsv.php" as="Horde/Data/Outlookcsv.php" />
+ <install name="lib/Horde/Data/Tsv.php" as="Horde/Data/Tsv.php" />
+ <install name="lib/Horde/Data/Vcard.php" as="Horde/Data/Vcard.php" />
+ <install name="lib/Horde/Data/Vnote.php" as="Horde/Data/Vnote.php" />
+ <install name="lib/Horde/Data/Vtodo.php" as="Horde/Data/Vtodo.php" />
+ <install name="lib/Horde/Data.php" as="Horde/Data.php" />
+ </filelist>
+ </phprelease>
<changelog>
<release>
+ <date>2006-05-08</date>
+ <time>21:12:22</time>
+ <version>
+ <release>0.0.3</release>
+ <api>0.0.3</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Converted to package.xml 2.0 for pear.horde.org
+ </notes>
+ </release>
+ <release>
<version>
<release>0.0.2</release>
<api>0.0.2</api>
--- /dev/null
+--TEST--
+Simple CSV files
+--FILE--
+<?php
+
+require 'Horde.php';
+require 'Horde/Data.php';
+
+$data = Horde_Data::factory('csv');
+var_dump($data->importFile(dirname(__FILE__) . '/simple_dos.csv', false, '', '', 4));
+var_dump($data->importFile(dirname(__FILE__) . '/simple_unix.csv', false, '', '', 4));
+var_dump($data->importFile(dirname(__FILE__) . '/simple_dos.csv', true, '', '', 4));
+var_dump($data->importFile(dirname(__FILE__) . '/simple_unix.csv', true, '', '', 4));
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ array(4) {
+ [0]=>
+ string(3) "one"
+ [1]=>
+ string(3) "two"
+ [2]=>
+ string(10) "three four"
+ [3]=>
+ string(4) "five"
+ }
+ [1]=>
+ array(4) {
+ [0]=>
+ string(3) "six"
+ [1]=>
+ string(5) "seven"
+ [2]=>
+ string(10) "eight nine"
+ [3]=>
+ string(4) " ten"
+ }
+}
+array(2) {
+ [0]=>
+ array(4) {
+ [0]=>
+ string(3) "one"
+ [1]=>
+ string(3) "two"
+ [2]=>
+ string(10) "three four"
+ [3]=>
+ string(4) "five"
+ }
+ [1]=>
+ array(4) {
+ [0]=>
+ string(3) "six"
+ [1]=>
+ string(5) "seven"
+ [2]=>
+ string(10) "eight nine"
+ [3]=>
+ string(4) " ten"
+ }
+}
+array(1) {
+ [0]=>
+ array(4) {
+ ["one"]=>
+ string(3) "six"
+ ["two"]=>
+ string(5) "seven"
+ ["three four"]=>
+ string(10) "eight nine"
+ ["five"]=>
+ string(4) " ten"
+ }
+}
+array(1) {
+ [0]=>
+ array(4) {
+ ["one"]=>
+ string(3) "six"
+ ["two"]=>
+ string(5) "seven"
+ ["three four"]=>
+ string(10) "eight nine"
+ ["five"]=>
+ string(4) " ten"
+ }
+}
\ No newline at end of file
--- /dev/null
+one,two,three four,five
+six,seven,eight nine, ten
--- /dev/null
+one,two,three four,five
+six,seven,eight nine, ten
+++ /dev/null
---TEST--
-Simple CSV files
---FILE--
-<?php
-
-require 'Horde.php';
-require 'Horde/Data.php';
-
-$data = Horde_Data::factory('csv');
-var_dump($data->importFile(dirname(__FILE__) . '/simple_dos.csv', false, '', '', 4));
-var_dump($data->importFile(dirname(__FILE__) . '/simple_unix.csv', false, '', '', 4));
-var_dump($data->importFile(dirname(__FILE__) . '/simple_dos.csv', true, '', '', 4));
-var_dump($data->importFile(dirname(__FILE__) . '/simple_unix.csv', true, '', '', 4));
-
-?>
---EXPECT--
-array(2) {
- [0]=>
- array(4) {
- [0]=>
- string(3) "one"
- [1]=>
- string(3) "two"
- [2]=>
- string(10) "three four"
- [3]=>
- string(4) "five"
- }
- [1]=>
- array(4) {
- [0]=>
- string(3) "six"
- [1]=>
- string(5) "seven"
- [2]=>
- string(10) "eight nine"
- [3]=>
- string(4) " ten"
- }
-}
-array(2) {
- [0]=>
- array(4) {
- [0]=>
- string(3) "one"
- [1]=>
- string(3) "two"
- [2]=>
- string(10) "three four"
- [3]=>
- string(4) "five"
- }
- [1]=>
- array(4) {
- [0]=>
- string(3) "six"
- [1]=>
- string(5) "seven"
- [2]=>
- string(10) "eight nine"
- [3]=>
- string(4) " ten"
- }
-}
-array(1) {
- [0]=>
- array(4) {
- ["one"]=>
- string(3) "six"
- ["two"]=>
- string(5) "seven"
- ["three four"]=>
- string(10) "eight nine"
- ["five"]=>
- string(4) " ten"
- }
-}
-array(1) {
- [0]=>
- array(4) {
- ["one"]=>
- string(3) "six"
- ["two"]=>
- string(5) "seven"
- ["three four"]=>
- string(10) "eight nine"
- ["five"]=>
- string(4) " ten"
- }
-}
\ No newline at end of file
+++ /dev/null
-one,two,three four,five
-six,seven,eight nine, ten
+++ /dev/null
-one,two,three four,five
-six,seven,eight nine, ten
* @package Kronolith
*/
-function _cleanup()
+function _cleanupData()
{
- global $import_step;
- $import_step = 1;
+ $GLOBALS['import_step'] = 1;
return Horde_Data::IMPORT_FILE;
}
}
}
- $csv = &Horde_Data::singleton('csv');
- $csv->exportFile(_("events.csv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Csv', array('cleanup' => '_cleanupData'))->exportFile(_("events.csv"), $data, true);
exit;
case Horde_Data::EXPORT_ICALENDAR:
}
if (!$error) {
- $data = &Horde_Data::singleton($import_format);
- if ($data instanceof PEAR_Error) {
- $notification->push(_("This file format is not supported."), 'horde.error');
- $next_step = Horde_Data::IMPORT_FILE;
- } else {
+ try {
+ $data = $injector->getInstance('Horde_Data')->getOb($import_format, array('cleanup' => '_cleanupData'));
+
if ($actionID == Horde_Data::IMPORT_FILE) {
+ $cleanup = true;
try {
$share = $kronolith_shares->getShare($_SESSION['import_data']['import_cal']);
if (!$share->hasPermission(Horde_Auth::getAuth(), Horde_Perms::EDIT)) {
$notification->push(_("You do not have permission to add events to the selected calendar."), 'horde.error');
- $next_step = $data->cleanup();
} else {
$next_step = $data->nextStep($actionID, $param);
- if ($next_step instanceof PEAR_Error) {
- $notification->push($next_step->getMessage(), 'horde.error');
- $next_step = $data->cleanup();
- }
+ $cleanup = false;
}
} catch (Exception $e) {
$notification->push(_("You have specified an invalid calendar."), 'horde.error');
+ }
+
+ if ($cleanup) {
$next_step = $data->cleanup();
}
} else {
$next_step = $data->nextStep($actionID, $param);
- if ($next_step instanceof PEAR_Error) {
- $notification->push($next_step->getMessage(), 'horde.error');
- $next_step = $data->cleanup();
- }
+ }
+ } catch (Horde_Data_Exception $e) {
+ if ($data) {
+ $notification->push($e, 'horde.error');
+ $next_step = $data->cleanup();
+ } else {
+ $notification->push(_("This file format is not supported."), 'horde.error');
+ $next_step = Horde_Data::IMPORT_FILE;
}
}
}
<?php
/**
- * $Horde: mnemo/data.php,v 1.55 2009/12/04 17:42:24 jan Exp $
- *
* Copyright 2001-2009 The Horde Project (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (ASL). If you
* did not receive this file, see http://www.horde.org/licenses/asl.php.
*
* @author Jan Schneider <jan@horde.org>
- * @since Mnemo 1.0
* @package Mnemo
*/
-function _cleanup()
+function _cleanupData()
{
- global $import_step;
- $import_step = 1;
+ $GLOBALS['import_step'] = 1;
return Horde_Data::IMPORT_FILE;
}
-@define('MNEMO_BASE', dirname(__FILE__));
-require_once MNEMO_BASE . '/lib/Application.php';
+require_once dirname(__FILE__) . '/lib/Application.php';
Horde_Registry::appInit('mnemo');
if (!$conf['menu']['import_export']) {
unset($note['uid']);
$data[] = $note;
}
- $csv = &Horde_Data::singleton('csv');
- $csv->exportFile(_("notes.csv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Csv', array('cleanup' => '_cleanupData'))->exportFile(_("notes.csv"), $data, true);
exit;
}
}
$next_step = null;
if (!$error) {
- $data = &Horde_Data::singleton($import_format);
- if (is_a($data, 'PEAR_Error')) {
- $notification->push(_("This file format is not supported."), 'horde.error');
- $next_step = Horde_Data::IMPORT_FILE;
- } else {
+ try {
+ $data = $injector->getInstance('Horde_Data')->getOb($import_format, array('cleanup' => '_cleanupData'));
$next_step = $data->nextStep($actionID, $param);
- if (is_a($next_step, 'PEAR_Error')) {
- $notification->push($next_step->getMessage(), 'horde.error');
+ } catch (Horde_Data_Exception $e) {
+ if ($data) {
+ $notification->push($e, 'horde.error');
$next_step = $data->cleanup();
+ } else {
+ $notification->push(_("This file format is not supported."), 'horde.error');
+ $next_step = Horde_Data::IMPORT_FILE;
}
}
}
* @author Jan Schneider <jan@horde.org>
*/
-function _cleanup()
+function _cleanupData()
{
- global $import_step;
- $import_step = 1;
+ $GLOBALS['import_step'] = 1;
return Horde_Data::IMPORT_FILE;
}
unset($task['delete_link']);
$data[] = $task;
}
- $csv = Horde_Data::singleton('csv');
- $csv->exportFile(_("tasks.csv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Csv', array('cleanup' => '_cleanupData'))->exportFile(_("tasks.csv"), $data, true);
exit;
case Horde_Data::EXPORT_ICALENDAR:
}
if (!$error) {
- $data = Horde_Data::singleton($import_format);
- if (is_a($data, 'PEAR_Error')) {
- $notification->push(_("This file format is not supported."), 'horde.error');
- $next_step = Horde_Data::IMPORT_FILE;
- } else {
+ try {
+ $data = $injector->getInstance('Horde_Data')->getOb($import_format, array('cleanup' => '_cleanupData'));
$next_step = $data->nextStep($actionID, $param);
- if (is_a($next_step, 'PEAR_Error')) {
- $notification->push($next_step->getMessage(), 'horde.error');
+ } catch (Horde_Data_Exception $e) {
+ if ($data) {
+ $notification->push($e, 'horde.error');
$next_step = $data->cleanup();
+ } else {
+ $notification->push(_("This file format is not supported."), 'horde.error');
+ $next_step = Horde_Data::IMPORT_FILE;
}
}
}
switch($this->_vars->get('format')) {
case Horde_Data::EXPORT_CSV:
$ext = 'csv';
- $fmt = Horde_Data::singleton('csv');
+ $fmt = $GLOBALS['injector']->getInstance('Horde_Data')->getOb('Csv');
break;
case Horde_Data::EXPORT_TSV:
$ext = 'tsv';
- $fmt = Horde_Data::singleton('tsv');
+ $fmt = $GLOBALS['injector']->getInstance('Horde_Data')->getOb('Tsv');
break;
default:
*/
require_once dirname(__FILE__) . '/lib/base.php';
-require_once 'Horde/Data.php';
if (!$conf['menu']['export']) {
header('Location: ' . Horde::applicationUrl('list.php', true));
switch (Horde_Util::getFormData('exportID')) {
case EXPORT_CSV:
- $csv = &Horde_Data::singleton('csv');
- $csv->exportFile(_("class.csv"), $data, (Horde_Util::getFormData('student') == 'all'));
+ $injector->getInstance('Horde_Data')->getOb('Csv')->exportFile(_("class.csv"), $data, (Horde_Util::getFormData('student') == 'all'));
exit;
case EXPORT_TSV:
- $tsv = &Horde_Data::singleton('tsv');
- $tsv->exportFile(_("class.tsv"), $data, (Horde_Util::getFormData('student') == 'all'));
+ $injector->getInstance('Horde_Data')->getOb('Tsv')->exportFile(_("class.tsv"), $data, (Horde_Util::getFormData('student') == 'all'));
exit;
}
* @author Jan Schneider <jan@horde.org>
*/
-function _cleanup()
+function _cleanupData()
{
- global $import_step;
- $import_step = 1;
+ $GLOBALS['import_step'] = 1;
return Horde_Data::IMPORT_FILE;
}
switch ($exportType) {
case Horde_Data::EXPORT_CSV:
- $csv = Horde_Data::singleton('csv');
- $csv->exportFile(_("contacts.csv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Csv', array('cleanup' => '_cleanupData'))->exportFile(_("contacts.csv"), $data, true);
exit;
case Horde_Data::EXPORT_OUTLOOKCSV:
- $csv = Horde_Data::singleton('outlookcsv');
- $csv->exportFile(_("contacts.csv"), $data, true, array_flip($outlook_mapping));
+ $injector->getInstance('Horde_Data')->getOb('Outlookcsv', array('cleanup' => '_cleanupData'))->exportFile(_("contacts.csv"), $data, true, array_flip($outlook_mapping));
exit;
case Horde_Data::EXPORT_TSV:
- $tsv = Horde_Data::singleton('tsv');
- $tsv->exportFile(_("contacts.tsv"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Tsv', array('cleanup' => '_cleanupData'))->exportFile(_("contacts.tsv"), $data, true);
exit;
case Horde_Data::EXPORT_VCARD:
case 'vcard30':
- $vcard = Horde_Data::singleton('vcard');
- $vcard->exportFile(_("contacts.vcf"), $data, true);
+ $injector->getInstance('Horde_Data')->getOb('Vcard', array('cleanup' => '_cleanupData'))->exportFile(_("contacts.vcf"), $data, true);
exit;
case 'ldif':
+ // TODO
+ //$injector->getInstance('Horde_Data')->getOb('Csv', array('cleanup' => '_cleanupData'))
$ldif = Horde_Data::singleton(array('turba', 'ldif'));
$ldif->exportFile(_("contacts.ldif"), $data, true);
exit;
}
if (!$error && !empty($import_format)) {
+ // TODO
if ($import_format == 'ldif') {
$data = Horde_Data::singleton(array('turba', $import_format));
} else {
exit;
}
-$vcard = Horde_Data::singleton('vcard');
$filename = str_replace(' ', '_', $object->getValue('name'));
if (!$filename) {
$filename = _("contact");
}
-$vcard->exportFile($filename . '.vcf', array($driver->tovCard($object, '2.1', null, true)), Horde_Nls::getCharset());
+
+$injector->getInstance('Horde_Data')->getOb('Vcard')->exportFile($filename . '.vcf', array($driver->tovCard($object, '2.1', null, true)), Horde_Nls::getCharset());