<?php
/**
* $Horde: trean/data.php,v 1.57 2008-01-02 11:14:01 jan Exp $
*
* Copyright 2002-2008 The Horde Project (http://www.horde.org/)
*
* See the enclosed file LICENSE for license information (BSD). If you did not
* did not receive this file, see http://www.horde.org/licenses/bsdl.php.
*
* @author Mike Cochrane <mike@graftonhall.co.nz>
* @package Trean
*/
function export($folder, $depth, $recursive = true)
{
$name = $folder->get('name');
if (empty($name)) {
$name = _("Bookmarks");
}
$output = '';
if ($folder->getId() != $GLOBALS['trean_shares']->getId(Auth::getAuth())) {
$output .= sprintf('%1$s<DT><H3 FOLDED ADD_DATE="%2$s">%3$s</H3>' . "\n" . '%1$s<DL><p>' . "\n",
str_repeat(' ', $depth * 4), time(), $name);
}
$bookmarks = $folder->listBookmarks();
foreach ($bookmarks as $bookmark) {
$output .= sprintf('%s<DT><A HREF="%s" ADD_DATE="%s" LAST_VISIT="0" LAST_MODIFIED="0">%s</A>' . "\n",
str_repeat(' ', ($depth + 1) * 4),
$bookmark->url,
time(),
$bookmark->title);
}
if ($recursive) {
$folders = Trean::listFolders(PERMS_SHOW, $folder->getName(), false);
if (is_a($folders, 'PEAR_Error')) {
$notification->push(sprintf(_("An error occured listing folders: %s"), $folders->getMessage()), 'horde.error');
} else {
foreach ($folders as $subfolder) {
$output .= export($subfolder, $depth + 1);
}
}
}
return $output . str_repeat(' ', $depth * 4) . '</DL><p>' . "\n";
}
$tags = null;
$curtag_id = -1;
function startElement($parser, $name, $attrs)
{
global $tags;
global $curtag_id;
$tag = array (
"name" => trim(strip_tags($name)),
"attrs" => $attrs,
"parent_id" => $curtag_id
);
if (!isset($tags)) {
$tags = array(0 => $tag);
$curtag_id = 0;
} else {
$tags[] = $tag;
$curtag_id = count($tags) - 1;
}
}
function endElement($parser, $name)
{
global $tags;
global $curtag_id;
$curtag_id = $tags[$curtag_id]['parent_id'];
}
function characterDataElement($parser, $data)
{
global $tags;
global $curtag_id;
$tags[$curtag_id]["cdata"] .= trim(strip_tags($data));
}
@define('TREAN_BASE', dirname(__FILE__));
require_once TREAN_BASE . '/lib/base.php';
$folders_exceeded = Trean::hasPermission('max_folders') !== true &&
Trean::hasPermission('max_folders') <= Trean::countFolders();
if ($folders_exceeded) {
$message = @htmlspecialchars(sprintf(_("You are not allowed to create more than %d folders."), Trean::hasPermission('max_folders')), ENT_COMPAT, NLS::getCharset());
if (!empty($conf['hooks']['permsdenied'])) {
$message = Horde::callHook('_perms_hook_denied', array('trean:max_folders'), 'horde', $message);
}
$notification->push($message, 'horde.warning', array('content.raw'));
}
$bookmarks_exceeded = Trean::hasPermission('max_bookmarks') !== true &&
Trean::hasPermission('max_bookmarks') <= $trean_shares->countBookmarks();
if ($bookmarks_exceeded) {
$message = @htmlspecialchars(sprintf(_("You are not allowed to create more than %d bookmarks."), Trean::hasPermission('max_bookmarks')), ENT_COMPAT, NLS::getCharset());
if (!empty($conf['hooks']['permsdenied'])) {
$message = Horde::callHook('_perms_hook_denied', array('trean:max_bookmarks'), 'horde', $message);
}
$notification->push($message, 'horde.warning', array('content.raw'));
}
switch (Util::getFormData('actionID')) {
case 'import':
$result = Browser::wasFileUploaded('import_file');
if (is_a($result, 'PEAR_Error')) {
$notification->push($result->getMessage(), 'horde.error');
break;
}
$target = Util::getFormData('target', $trean_shares->getId(Auth::getAuth()));
$root = &$trean_shares->getFolder($target);
if (is_a($root, 'PEAR_Error')) {
$notification->push($root, 'horde.error');
break;
}
$contents = implode ("", file($_FILES['import_file']['tmp_name']));
// start from the "root folder"
$bookmark_data = stristr($contents, "<dl>");
// remove non significant tags
$bookmark_data = eregi_replace("(<p>|<hr>)", "", $bookmark_data);
$bookmark_data = ereg_replace("&", "&", $bookmark_data);
// close opened tags
$bookmark_data = ereg_replace("(<DT>[^\n]*</H3>)\n", "\\1</DT>\n", $bookmark_data);
$bookmark_data = ereg_replace("(<DT>[^\n]*</A>)\n", "\\1</DT>\n", $bookmark_data);
$bookmark_data = ereg_replace("(<DD>[^\n]*)(\n[ \t\n]*(<D[TL]>|</DL>))", "\\1</DD>\\2", $bookmark_data);
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterDataElement");
if (!xml_parse($xml_parser, $bookmark_data, TRUE)) {
$message = @htmlspecialchars(sprintf(_("XML error: %s at line %d"), xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser)));
if (!empty($conf['hooks']['permsdenied'])) {
$message = Horde::callHook('_perms_hook_denied', array('trean:max_folders'), 'horde', $message);
}
$notification->push($message, 'horde.error', array('content.raw'));
xml_parser_free($xml_parser);
exit;
}
xml_parser_free($xml_parser);
$folders = 0;
$bookmarks = 0;
$folder = &$root;
$bookmark = null;
$stack = array();
$stack_dl_id = array();
$max_folders = Trean::hasPermission('max_folders');
$num_folders = Trean::countFolders();
$stop_folders = false;
$max_bookmarks = Trean::hasPermission('max_bookmarks');
$num_bookmarks = $trean_shares->countBookmarks();
foreach ($tags as $key => $tag) {
if ($tag['name'] == "H3" && $tags[$tag['parent_id']]['name'] == "DT") {
/* Start of a folder. */
if ($stop_folders) {
continue;
}
if ($max_folders !== true && $num_folders >= $max_folders) {
$message = @htmlspecialchars(sprintf(_("You are not allowed to create more than %d folders."), Trean::hasPermission('max_folders')), ENT_COMPAT, NLS::getCharset());
if (!empty($conf['hooks']['permsdenied'])) {
$message = Horde::callHook('_perms_hook_denied', array('trean:max_folders'), 'horde', $message);
}
$notification->push($message, 'horde.error', array('content.raw'));
$stop_folders = true;
continue;
}
$stack[] = $folder->getId();
$folderId = $folder->addFolder(array('name' => $tag['cdata']));
$folder = &$trean_shares->getFolder($folderId);
$bookmark = null;
$folders++;
$num_folders++;
} elseif (count($stack) > 0 && $tag['name'] == "DL") {
$stack_dl_id[] = $key;
} elseif (count($stack) > 0 && $tag['name'] == "DT" && $tag['parent_id'] != end($stack_dl_id)) {
if (count($stack) > 0) {
$folder = &$trean_shares->getFolder(array_pop($stack));
$bookmark = null;
array_pop($stack_dl_id);
}
} elseif ($tag['name'] == "A" && $tags[$tag['parent_id']]['name'] == "DT") {
/* A bookmark. */
if ($max_bookmarks !== true && $num_bookmarks >= $max_bookmarks) {
$message = @htmlspecialchars(sprintf(_("You are not allowed to create more than %d bookmarks."), Trean::hasPermission('max_bookmarks')), ENT_COMPAT, NLS::getCharset());
if (!empty($conf['hooks']['permsdenied'])) {
$message = Horde::callHook('_perms_hook_denied', array('trean:max_bookmarks'), 'horde', $message);
}
$notification->push($message, 'horde.error', array('content.raw'));
$stop_bookmarks = true;
break;
}
$bookmark_id = $folder->addBookmark(array(
'bookmark_url' => trim($tag['attrs']['HREF']),
'bookmark_title' => $tag['cdata'],
'bookmark_description' => ''));
$bookmark = $trean_shares->getBookmark($bookmark_id);
$bookmarks++;
$num_bookmarks++;
} elseif ($tag['name'] == "DD" && $tags[$tag['parent_id']]['name'] == "DL") {
if (!is_null($bookmark)) {
$bookmark->description = $tag['cdata'];
$bookmark->save();
$bookmark = null;
}
}
}
$notification->push(sprintf(_("%d Folders and %d Bookmarks imported."), $folders, $bookmarks), 'horde.success');
$url = Util::addParameter('browse.php', 'f', $root->getId());
header('Location: ' . Horde::applicationUrl($url, true));
exit;
case 'export':
$folderId = Util::getFormData('export_folder');
$recursive = Util::getFormData('export_recursive');
$output = <<<EOH
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!--This is an automatically generated file.
It will be read and overwritten.
Do Not Edit! -->
<Title>Bookmarks</Title>
<H1>Bookmarks</H1>
<DL><p>
EOH;
$folder = $trean_shares->getFolder($folderId);
$output .= export($folder, 1, $recursive) . '</DL><p>' . "\n";
$browser->downloadHeaders('bookmarks.html', 'text/html', false,
strlen($output));
echo $output;
exit;
}
$title = _("Import Bookmarks");
require TREAN_TEMPLATES . '/common-header.inc';
require TREAN_TEMPLATES . '/menu.inc';
if (!$folders_exceeded || !$bookmarks_exceeded) {
require TREAN_TEMPLATES . '/data/import.inc';
}
require TREAN_TEMPLATES . '/data/export.inc';
require $registry->get('templates', 'horde') . '/common-footer.inc';