From 80ed05d45d0e9f7f23848919a3a8af388988fdd9 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 20 Aug 2016 15:22:30 -0400 Subject: Export of pages and their layouts to a zip file works. Bug on importing the exported zip file for pages. --- Zotlabs/Lib/ExtendedZip.php | 57 ++++++++++++++ Zotlabs/Module/Webpages.php | 142 +++++++++++++++++++++++++++++++++-- include/import.php | 45 ++++++++++- view/tpl/webpage_export_list.tpl | 6 +- view/tpl/website_portation_tools.tpl | 2 +- 5 files changed, 242 insertions(+), 10 deletions(-) create mode 100644 Zotlabs/Lib/ExtendedZip.php diff --git a/Zotlabs/Lib/ExtendedZip.php b/Zotlabs/Lib/ExtendedZip.php new file mode 100644 index 000000000..a40110c55 --- /dev/null +++ b/Zotlabs/Lib/ExtendedZip.php @@ -0,0 +1,57 @@ +addEmptyDir($localname); + $this->_addTree($dirname, $localname); + } + + // Internal function, to recurse + protected function _addTree($dirname, $localname) { + $dir = opendir($dirname); + while ($filename = readdir($dir)) { + // Discard . and .. + if ($filename == '.' || $filename == '..') + continue; + + // Proceed according to type + $path = $dirname . '/' . $filename; + $localpath = $localname ? ($localname . '/' . $filename) : $filename; + if (is_dir($path)) { + // Directory: add & recurse + $this->addEmptyDir($localpath); + $this->_addTree($path, $localpath); + } + else if (is_file($path)) { + // File: just add + $this->addFile($path, $localpath); + } + } + closedir($dir); + } + + // Helper function + public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') { + $zip = new self(); + $zip->open($zipFilename, $flags); + $zip->addTree($dirname, $localname); + $zip->close(); + } + +} diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index b927f95df..daa323007 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -70,7 +70,6 @@ class Webpages extends \Zotlabs\Web\Controller { require_once('include/import.php'); $elements = get_webpage_elements($channel, 'pages'); - logger(json_encode($elements), LOGGER_DEBUG); $o .= replace_macros(get_markup_template('webpage_export_list.tpl'), array( '$title' => t('Export Webpage Elements'), '$exportbtn' => t('Export selected'), @@ -405,20 +404,151 @@ class Webpages extends \Zotlabs\Web\Controller { if(isset($_POST['w_download'])) { $_SESSION['action'] = 'export_select_list'; $_SESSION['export'] = 'zipfile'; - if(isset($_POST['filename'])) { - $filename = filter_var($_POST['filename'], FILTER_SANITIZE_ENCODED); + if(isset($_POST['zipfilename']) && $_POST['zipfilename'] !== '') { + $filename = filter_var($_POST['zipfilename'], FILTER_SANITIZE_ENCODED); } else { $filename = 'website.zip'; } + $_SESSION['zipfilename'] = $filename; + } + + break; + + case 'zipfile': + + $tmp_folder_name = random_string(10); + $zip_folder_name = random_string(10); + $zip_filename = $_SESSION['zipfilename']; + $tmp_folderpath = '/tmp/' . $tmp_folder_name; + $zip_folderpath = '/tmp/' . $zip_folder_name; + if (!mkdir($zip_folderpath, 0770, false)) { + logger('Error creating zip file export folder: ' . $zip_folderpath, LOGGER_NORMAL); + json_return_and_die(array('message' => 'Error creating zip file export folder')); + } + $zip_filepath = '/tmp/' . $zip_folder_name . '/' . $zip_filename; + + $checkedpages = $_POST['page']; + $pages = []; + if (!empty($checkedpages)) { + foreach ($checkedpages as $mid) { + + $channel = \App::get_channel(); + $p = q("select * from iconfig left join item on iconfig.iid = item.id + where item.uid = %d and item.mid = '%s' and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d", + intval($channel['channel_id']), + dbesc($mid), + intval(ITEM_TYPE_WEBPAGE) + ); + + if($p) { + foreach ($p as $pp) { + // Get the associated layout + $layoutinfo = array(); + if($pp['layout_mid']) { + // TODO: Should we check for ownership here if the layout is already associated with the page? + $l = q("select iconfig.v, iconfig.k, mimetype, title, body from iconfig + left join item on item.id = iconfig.iid + where mid = '%s' and item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' order by iconfig.v asc limit 1", + dbesc($pp['layout_mid']), + intval($channel['channel_id']) + ); + if($l) { + $l = $l[0]; + $layoutinfo = array( + 'body' => $l['body'], + 'mimetype' => $l['mimetype'], + 'description' => $l['title'], + 'name' => $l['v'], + 'json' => array( + 'description' => $l['title'], + 'name' => $l['v'], + ) + ); + switch ($layoutinfo['mimetype']) { + case 'text/bbcode': + default: + $layout_ext = 'bbcode'; + break; + } + $layout_filename = $layoutinfo['name'] . '.' . $layout_ext; + $tmp_layoutfolder = $tmp_folderpath . '/layouts/' . $layoutinfo['name']; + $layout_filepath = $tmp_layoutfolder . '/' . $layout_filename; + $layoutinfo['json']['contentfile'] = $layout_filename; + $layout_jsonpath = $tmp_layoutfolder . '/layout.json'; + if (!mkdir($tmp_layoutfolder, 0770, true)) { + logger('Error creating temp export folder: ' . $tmp_layoutfolder, LOGGER_NORMAL); + json_return_and_die(array('message' => 'Error creating temp export folder')); + } + file_put_contents($layout_filepath, $layoutinfo['body']); + file_put_contents($layout_jsonpath, json_encode($layoutinfo['json'], JSON_UNESCAPED_SLASHES)); + } + } + switch ($pp['mimetype']) { + case 'text/html': + $page_ext = 'html'; + break; + case 'text/bbcode': + $page_ext = 'bbcode'; + break; + case 'text/markdown': + $page_ext = 'md'; + break; + case 'application/x-pdl': + $page_ext = 'pdl'; + break; + case 'application/x-php': + $page_ext = 'php'; + break; + default: + break; + } + $pageinfo = array( + 'title' => $pp['title'], + 'body' => $pp['body'], + 'pagelink' => $pp['v'], + 'mimetype' => $pp['mimetype'], + 'contentfile' => $pp['v'] . '.' . $page_ext, + 'layout' => ((x($layoutinfo,'name')) ? $layoutinfo['name'] : ''), + 'json' => array( + 'title' => $pp['title'], + 'pagelink' => $pp['v'], + 'mimetype' => $pp['mimetype'], + 'layout' => ((x($layoutinfo,'name')) ? $layoutinfo['name'] : ''), + ) + ); + $page_filename = $pageinfo['pagelink'] . '.' . $page_ext; + $tmp_pagefolder = $tmp_folderpath . '/pages/' . $pageinfo['pagelink']; + $page_filepath = $tmp_pagefolder . '/' . $page_filename; + $page_jsonpath = $tmp_pagefolder . '/page.json'; + $pageinfo['json']['contentfile'] = $page_filename; + if (!mkdir($tmp_pagefolder, 0770, true)) { + logger('Error creating temp export folder: ' . $tmp_pagefolder, LOGGER_NORMAL); + json_return_and_die(array('message' => 'Error creating temp export folder')); + } + file_put_contents($page_filepath, $pageinfo['body']); + file_put_contents($page_jsonpath, json_encode($pageinfo['json'], JSON_UNESCAPED_SLASHES)); + } + } + } + } + // TODO: Generate zipped file and return for download + + //create_zip_file($tmp_folderpath, $zip_filepath, true); + + \Zotlabs\Lib\ExtendedZip::zipTree($tmp_folderpath, $zip_filepath, \ZipArchive::CREATE); + + header('Content-disposition: attachment; filename="' . $zip_filename . '"'); + header("Content-Type: application/zip"); + readfile($zip_filepath); + rrmdir($zip_folderpath); + rrmdir($tmp_folderpath); + break; default : break; } } - - - } } diff --git a/include/import.php b/include/import.php index f7df636f3..b4d342273 100644 --- a/include/import.php +++ b/include/import.php @@ -1533,4 +1533,47 @@ function get_webpage_elements($channel, $type = 'all') { return null; } return $elements; -} \ No newline at end of file +} + +/* creates a compressed zip file */ + +function create_zip_file($files = array(), $destination = '', $overwrite = false) { + //if the zip file already exists and overwrite is false, return false + if (file_exists($destination) && !$overwrite) { + return false; + } + //vars + $valid_files = array(); + //if files were passed in... + if (is_array($files)) { + //cycle through each file + foreach ($files as $file) { + //make sure the file exists + if (file_exists($file)) { + $valid_files[] = $file; + } + } + } + + //if we have good files... + if (count($valid_files)) { + //create the archive + $zip = new ZipArchive(); + if ($zip->open($destination, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) { + return false; + } + //add the files + foreach ($valid_files as $file) { + $zip->addFile($file, $file); + } + //debug + //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status; + //close the zip -- done! + $zip->close(); + + //check to make sure the file exists + return file_exists($destination); + } else { + return false; + } +} diff --git a/view/tpl/webpage_export_list.tpl b/view/tpl/webpage_export_list.tpl index 1b943ace8..d980ea981 100644 --- a/view/tpl/webpage_export_list.tpl +++ b/view/tpl/webpage_export_list.tpl @@ -17,7 +17,9 @@

Pages

- + + + {{foreach $pages as $page}} diff --git a/view/tpl/website_portation_tools.tpl b/view/tpl/website_portation_tools.tpl index d9ebed179..2f68a7393 100644 --- a/view/tpl/website_portation_tools.tpl +++ b/view/tpl/website_portation_tools.tpl @@ -46,7 +46,7 @@
- +
-- cgit v1.2.3
Export?Page TitlePage LinkType
Export?Page TitlePage LinkType
@@ -27,7 +29,7 @@ -
+
{{$page.title}}