commit
b485d09847
57
Zotlabs/Lib/ExtendedZip.php
Normal file
57
Zotlabs/Lib/ExtendedZip.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* Description of ExtendedZip
|
||||
*
|
||||
* @author andrew
|
||||
*/
|
||||
class ExtendedZip extends \ZipArchive {
|
||||
|
||||
// Member function to add a whole file system subtree to the archive
|
||||
public function addTree($dirname, $localname = '') {
|
||||
if ($localname)
|
||||
$this->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();
|
||||
}
|
||||
|
||||
}
|
@ -41,7 +41,6 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = 0;
|
||||
$channel = null;
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = \App::get_channel();
|
||||
@ -62,6 +61,28 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
case 'importselected':
|
||||
$_SESSION['action'] = null;
|
||||
break;
|
||||
case 'export_select_list':
|
||||
$_SESSION['action'] = null;
|
||||
if(!$uid) {
|
||||
$_SESSION['export'] = null;
|
||||
break;
|
||||
}
|
||||
require_once('include/import.php');
|
||||
|
||||
$pages = get_webpage_elements($channel, 'pages');
|
||||
$layouts = get_webpage_elements($channel, 'layouts');
|
||||
$blocks = get_webpage_elements($channel, 'blocks');
|
||||
$o .= replace_macros(get_markup_template('webpage_export_list.tpl'), array(
|
||||
'$title' => t('Export Webpage Elements'),
|
||||
'$exportbtn' => t('Export selected'),
|
||||
'$action' => $_SESSION['export'], // value should be 'zipfile' or 'cloud'
|
||||
'$pages' => $pages['pages'],
|
||||
'$layouts' => $layouts['layouts'],
|
||||
'$blocks' => $blocks['blocks'],
|
||||
));
|
||||
$_SESSION['export'] = null;
|
||||
return $o;
|
||||
|
||||
default :
|
||||
$_SESSION['action'] = null;
|
||||
break;
|
||||
@ -233,7 +254,6 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
$action = $_REQUEST['action'];
|
||||
if( $action ){
|
||||
switch ($action) {
|
||||
@ -296,6 +316,7 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
$path = $website;
|
||||
}
|
||||
$elements['pages'] = scan_webpage_elements($path, 'page', $cloud);
|
||||
logger('$elements pages: ' . json_encode($elements['pages']));
|
||||
$elements['layouts'] = scan_webpage_elements($path, 'layout', $cloud);
|
||||
$elements['blocks'] = scan_webpage_elements($path, 'block', $cloud);
|
||||
$_SESSION['blocks'] = $elements['blocks'];
|
||||
@ -313,7 +334,8 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
|
||||
// If the website elements were imported from a zip file, delete the temporary decompressed files
|
||||
if ($cloud === false && $website && $elements) {
|
||||
rrmdir($website); // Delete the temporary decompressed files
|
||||
$_SESSION['tempimportpath'] = $website;
|
||||
//rrmdir($website); // Delete the temporary decompressed files
|
||||
}
|
||||
|
||||
break;
|
||||
@ -381,16 +403,300 @@ class Webpages extends \Zotlabs\Web\Controller {
|
||||
if(!(empty($_SESSION['import_pages']) && empty($_SESSION['import_blocks']) && empty($_SESSION['import_layouts']))) {
|
||||
info( t('Import complete.') . EOL);
|
||||
}
|
||||
if(isset($_SESSION['tempimportpath'])) {
|
||||
rrmdir($_SESSION['tempimportpath']); // Delete the temporary decompressed files
|
||||
unset($_SESSION['tempimportpath']);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'exportzipfile':
|
||||
|
||||
if(isset($_POST['w_download'])) {
|
||||
$_SESSION['action'] = 'export_select_list';
|
||||
$_SESSION['export'] = 'zipfile';
|
||||
if(isset($_POST['zipfilename']) && $_POST['zipfilename'] !== '') {
|
||||
$filename = filter_var($_POST['zipfilename'], FILTER_SANITIZE_ENCODED);
|
||||
} else {
|
||||
$filename = 'website.zip';
|
||||
}
|
||||
$_SESSION['zipfilename'] = $filename;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'exportcloud':
|
||||
logger('exportcloud', LOGGER_DEBUG);
|
||||
if(isset($_POST['exportcloudpath']) && $_POST['exportcloudpath'] !== '') {
|
||||
$_SESSION['action'] = 'export_select_list';
|
||||
$_SESSION['export'] = 'cloud';
|
||||
$_SESSION['exportcloudpath'] = filter_var($_POST['exportcloudpath'], FILTER_SANITIZE_ENCODED);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'cloud':
|
||||
case 'zipfile':
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$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;
|
||||
|
||||
$checkedblocks = $_POST['block'];
|
||||
$blocks = [];
|
||||
if (!empty($checkedblocks)) {
|
||||
foreach ($checkedblocks as $mid) {
|
||||
$b = 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 = 'BUILDBLOCK' order by iconfig.v asc limit 1",
|
||||
dbesc($mid),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($b) {
|
||||
$b = $b[0];
|
||||
$blockinfo = array(
|
||||
'body' => $b['body'],
|
||||
'mimetype' => $b['mimetype'],
|
||||
'title' => $b['title'],
|
||||
'name' => $b['v'],
|
||||
'json' => array(
|
||||
'title' => $b['title'],
|
||||
'name' => $b['v'],
|
||||
'mimetype' => $b['mimetype'],
|
||||
)
|
||||
);
|
||||
switch ($blockinfo['mimetype']) {
|
||||
case 'text/html':
|
||||
$block_ext = 'html';
|
||||
break;
|
||||
case 'text/bbcode':
|
||||
$block_ext = 'bbcode';
|
||||
break;
|
||||
case 'text/markdown':
|
||||
$block_ext = 'md';
|
||||
break;
|
||||
case 'application/x-pdl':
|
||||
$block_ext = 'pdl';
|
||||
break;
|
||||
case 'application/x-php':
|
||||
$block_ext = 'php';
|
||||
break;
|
||||
default:
|
||||
$block_ext = 'bbcode';
|
||||
break;
|
||||
}
|
||||
$block_filename = $blockinfo['name'] . '.' . $block_ext;
|
||||
$tmp_blockfolder = $tmp_folderpath . '/blocks/' . $blockinfo['name'];
|
||||
$block_filepath = $tmp_blockfolder . '/' . $block_filename;
|
||||
$blockinfo['json']['contentfile'] = $block_filename;
|
||||
$block_jsonpath = $tmp_blockfolder . '/block.json';
|
||||
if (!is_dir($tmp_blockfolder) && !mkdir($tmp_blockfolder, 0770, true)) {
|
||||
logger('Error creating temp export folder: ' . $tmp_blockfolder, LOGGER_NORMAL);
|
||||
json_return_and_die(array('message' => 'Error creating temp export folder'));
|
||||
}
|
||||
file_put_contents($block_filepath, $blockinfo['body']);
|
||||
file_put_contents($block_jsonpath, json_encode($blockinfo['json'], JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$checkedlayouts = $_POST['layout'];
|
||||
$layouts = [];
|
||||
if (!empty($checkedlayouts)) {
|
||||
foreach ($checkedlayouts as $mid) {
|
||||
$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($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'],
|
||||
'mimetype' => $l['mimetype'],
|
||||
)
|
||||
);
|
||||
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 (!is_dir($tmp_layoutfolder) && !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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$checkedpages = $_POST['page'];
|
||||
$pages = [];
|
||||
if (!empty($checkedpages)) {
|
||||
foreach ($checkedpages as $mid) {
|
||||
|
||||
$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']) {
|
||||
$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 (!is_dir($tmp_layoutfolder) && !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 (!is_dir($tmp_pagefolder) && !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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($action === 'zipfile') {
|
||||
// Generate the zip file
|
||||
\Zotlabs\Lib\ExtendedZip::zipTree($tmp_folderpath, $zip_filepath, \ZipArchive::CREATE);
|
||||
// Output the file for download
|
||||
header('Content-disposition: attachment; filename="' . $zip_filename . '"');
|
||||
header("Content-Type: application/zip");
|
||||
$success = readfile($zip_filepath);
|
||||
} elseif ($action === 'cloud') { // Only zipfile or cloud should be possible values for $action here
|
||||
if(isset($_SESSION['exportcloudpath'])) {
|
||||
require_once('include/attach.php');
|
||||
$cloudpath = urldecode($_SESSION['exportcloudpath']);
|
||||
$channel = \App::get_channel();
|
||||
$dirpath = get_dirpath_by_cloudpath($channel, $cloudpath);
|
||||
if(!$dirpath) {
|
||||
$x = attach_mkdirp($channel, $channel['channel_hash'], array('pathname' => $cloudpath));
|
||||
$folder_hash = (($x['success']) ? $x['data']['hash'] : '');
|
||||
|
||||
if (!$x['success']) {
|
||||
logger('Failed to create cloud file folder', LOGGER_NORMAL);
|
||||
}
|
||||
$dirpath = get_dirpath_by_cloudpath($channel, $cloudpath);
|
||||
if (!is_dir($dirpath)) {
|
||||
logger('Failed to create cloud file folder', LOGGER_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
$success = copy_folder_to_cloudfiles($channel, $channel['channel_hash'], $tmp_folderpath, $cloudpath);
|
||||
}
|
||||
}
|
||||
if(!$success) {
|
||||
logger('Error exporting webpage elements', LOGGER_NORMAL);
|
||||
}
|
||||
|
||||
rrmdir($zip_folderpath); rrmdir($tmp_folderpath); // delete temporary files
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1995,6 +1995,52 @@ function get_filename_by_cloudname($cloudname, $channel, $storepath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// recursively copy a directory into cloud files
|
||||
function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpath)
|
||||
{
|
||||
if (!is_dir($srcpath) || !is_readable($srcpath)) {
|
||||
logger('Error reading source path: ' . $srcpath, LOGGER_NORMAL);
|
||||
return false;
|
||||
}
|
||||
$nodes = array_diff(scandir($srcpath), array('.', '..'));
|
||||
foreach ($nodes as $node) {
|
||||
$clouddir = $cloudpath . '/' . $node; // Sub-folder in cloud files destination
|
||||
$nodepath = $srcpath . '/' . $node; // Sub-folder in source path
|
||||
if(is_dir($nodepath)) {
|
||||
$x = attach_mkdirp($channel, $observer_hash, array('pathname' => $clouddir));
|
||||
if(!$x['success']) {
|
||||
logger('Error creating cloud path: ' . $clouddir, LOGGER_NORMAL);
|
||||
return false;
|
||||
}
|
||||
// Recursively call this function where the source and destination are the subfolders
|
||||
$success = copy_folder_to_cloudfiles($channel, $observer_hash, $nodepath, $clouddir);
|
||||
if(!$success) {
|
||||
logger('Error copying contents of folder: ' . $nodepath, LOGGER_NORMAL);
|
||||
return false;
|
||||
}
|
||||
} elseif (is_file($nodepath) && is_readable($nodepath)) {
|
||||
$x = attach_store($channel, $observer_hash, 'import',
|
||||
array(
|
||||
'directory' => $cloudpath,
|
||||
'src' => $nodepath,
|
||||
'filename' => $node,
|
||||
'filesize' => @filesize($nodepath),
|
||||
'preserve_original' => true)
|
||||
);
|
||||
if(!$x['success']) {
|
||||
logger('Error copying file: ' . $nodepath , LOGGER_NORMAL);
|
||||
logger('Return value: ' . json_encode($x), LOGGER_NORMAL);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
logger('Error scanning source path', LOGGER_NORMAL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* attach_move()
|
||||
* This function performs an in place directory-to-directory move of a stored attachment or photo.
|
||||
|
@ -1311,9 +1311,15 @@ function scan_webpage_elements($path, $type, $cloud = false) {
|
||||
return false;
|
||||
}
|
||||
$content = file_get_contents($folder . '/' . $contentfilename);
|
||||
logger('contentfile: ' . $folder . '/' . $contentfilename, LOGGER_DEBUG);
|
||||
logger('content: ' . $content, LOGGER_DEBUG);
|
||||
if (!$content) {
|
||||
logger('Failed to get file content for ' . $metadata['contentfile']);
|
||||
return false;
|
||||
if(is_readable($folder . '/' . $contentfilename)) {
|
||||
$content = '';
|
||||
} else {
|
||||
logger('Failed to get file content for ' . $metadata['contentfile']);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$elements[] = $metadata;
|
||||
}
|
||||
@ -1403,6 +1409,10 @@ function scan_webpage_elements($path, $type, $cloud = false) {
|
||||
}
|
||||
// Import the actual element content
|
||||
$arr['body'] = file_get_contents($element['path']);
|
||||
if($arr['item_type'] === ITEM_TYPE_PDL) {
|
||||
logger(' body: ' . $arr['body'], LOGGER_DEBUG);
|
||||
logger(' path: ' . $element['path'], LOGGER_DEBUG);
|
||||
}
|
||||
// The element owner is the channel importing the elements
|
||||
$arr['owner_xchan'] = get_observer_hash();
|
||||
// The author is either the owner or whomever was specified
|
||||
@ -1472,3 +1482,193 @@ function scan_webpage_elements($path, $type, $cloud = false) {
|
||||
return $element;
|
||||
|
||||
}
|
||||
|
||||
function get_webpage_elements($channel, $type = 'all') {
|
||||
$elements = array();
|
||||
if(!$channel['channel_id']) {
|
||||
return null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'all':
|
||||
// If all, execute all the pages, layouts, blocks case statements
|
||||
case 'pages':
|
||||
$elements['pages'] = null;
|
||||
$owner = $channel['channel_id'];
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
|
||||
|
||||
$r = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'WEBPAGE' and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_WEBPAGE)
|
||||
);
|
||||
|
||||
$pages = null;
|
||||
|
||||
if($r) {
|
||||
$elements['pages'] = array();
|
||||
$pages = array();
|
||||
foreach($r as $rr) {
|
||||
unobscure($rr);
|
||||
|
||||
//$lockstate = (($rr['allow_cid'] || $rr['allow_gid'] || $rr['deny_cid'] || $rr['deny_gid']) ? 'lock' : 'unlock');
|
||||
|
||||
$element_arr = array(
|
||||
'type' => 'webpage',
|
||||
'title' => $rr['title'],
|
||||
'body' => $rr['body'],
|
||||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
'mimetype' => $rr['mimetype'],
|
||||
'pagetitle' => $rr['v'],
|
||||
'mid' => $rr['mid'],
|
||||
'layout_mid' => $rr['layout_mid']
|
||||
);
|
||||
$pages[$rr['iid']][] = array(
|
||||
'url' => $rr['iid'],
|
||||
'pagetitle' => $rr['v'],
|
||||
'title' => $rr['title'],
|
||||
'created' => datetime_convert('UTC',date_default_timezone_get(),$rr['created']),
|
||||
'edited' => datetime_convert('UTC',date_default_timezone_get(),$rr['edited']),
|
||||
'bb_element' => '[element]' . base64url_encode(json_encode($element_arr)) . '[/element]',
|
||||
//'lockstate' => $lockstate
|
||||
);
|
||||
$elements['pages'][] = $element_arr;
|
||||
}
|
||||
|
||||
}
|
||||
if($type !== 'all') {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'layouts':
|
||||
$elements['layouts'] = null;
|
||||
$owner = $channel['channel_id'];
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
|
||||
|
||||
$r = q("select * from iconfig left join item on iconfig.iid = item.id
|
||||
where item.uid = %d and iconfig.cat = 'system' and iconfig.k = 'PDL' and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_PDL)
|
||||
);
|
||||
|
||||
$layouts = null;
|
||||
|
||||
if($r) {
|
||||
$elements['layouts'] = array();
|
||||
$layouts = array();
|
||||
foreach($r as $rr) {
|
||||
unobscure($rr);
|
||||
|
||||
$elements['layouts'][] = array(
|
||||
'type' => 'layout',
|
||||
'description' => $rr['title'], // description of the layout
|
||||
'body' => $rr['body'],
|
||||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
'mimetype' => $rr['mimetype'],
|
||||
'name' => $rr['v'], // name of reference for the layout
|
||||
'mid' => $rr['mid'],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($type !== 'all') {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'blocks':
|
||||
$elements['blocks'] = null;
|
||||
$owner = $channel['channel_id'];
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
|
||||
|
||||
$r = q("select iconfig.iid, iconfig.k, iconfig.v, mid, title, body, mimetype, created, edited from iconfig
|
||||
left join item on iconfig.iid = item.id
|
||||
where uid = %d and iconfig.cat = 'system' and iconfig.k = 'BUILDBLOCK'
|
||||
and item_type = %d order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_BLOCK)
|
||||
);
|
||||
|
||||
$blocks = null;
|
||||
|
||||
if($r) {
|
||||
$elements['blocks'] = array();
|
||||
$blocks = array();
|
||||
foreach($r as $rr) {
|
||||
unobscure($rr);
|
||||
|
||||
$elements['blocks'][] = array(
|
||||
'type' => 'block',
|
||||
'title' => $rr['title'],
|
||||
'body' => $rr['body'],
|
||||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
'mimetype' => $rr['mimetype'],
|
||||
'name' => $rr['v'],
|
||||
'mid' => $rr['mid']
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($type !== 'all') {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
@ -2267,11 +2267,11 @@ function design_tools() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates website import tools menu
|
||||
* @brief Creates website portation tools menu
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function website_import_tools() {
|
||||
function website_portation_tools() {
|
||||
|
||||
$channel = App::get_channel();
|
||||
$sys = false;
|
||||
@ -2282,7 +2282,7 @@ function website_import_tools() {
|
||||
$sys = true;
|
||||
}
|
||||
|
||||
return replace_macros(get_markup_template('website_import_tools.tpl'), array(
|
||||
return replace_macros(get_markup_template('website_portation_tools.tpl'), array(
|
||||
'$title' => t('Import'),
|
||||
'$import_label' => t('Import website...'),
|
||||
'$import_placeholder' => t('Select folder to import'),
|
||||
@ -2290,7 +2290,15 @@ function website_import_tools() {
|
||||
'$file_import_text' => t('Import from cloud files:'),
|
||||
'$desc' => t('/cloud/channel/path/to/folder'),
|
||||
'$hint' => t('Enter path to website files'),
|
||||
'$select' => t('Select folder'),
|
||||
'$select' => t('Select folder'),
|
||||
'$export_label' => t('Export website...'),
|
||||
'$file_download_text' => t('Export to a zip file'),
|
||||
'$filename_desc' => t('website.zip'),
|
||||
'$filename_hint' => t('Enter a name for the zip file.'),
|
||||
'$cloud_export_text' => t('Export to cloud files'),
|
||||
'$cloud_export_desc' => t('/path/to/export/folder'),
|
||||
'$cloud_export_hint' => t('Enter a path to a cloud files destination.'),
|
||||
'$cloud_export_select' => t('Specify folder'),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -779,7 +779,7 @@ function widget_design_tools($arr) {
|
||||
return design_tools();
|
||||
}
|
||||
|
||||
function widget_website_import_tools($arr) {
|
||||
function widget_website_portation_tools($arr) {
|
||||
|
||||
// mod menu doesn't load a profile. For any modules which load a profile, check it.
|
||||
// otherwise local_channel() is sufficient for permissions.
|
||||
@ -791,7 +791,7 @@ function widget_website_import_tools($arr) {
|
||||
if(! local_channel())
|
||||
return '';
|
||||
|
||||
return website_import_tools();
|
||||
return website_portation_tools();
|
||||
}
|
||||
|
||||
function widget_findpeople($arr) {
|
||||
|
@ -119,3 +119,77 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
/* SQUARED THREE */
|
||||
.squaredThree {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: #fcfff4;
|
||||
|
||||
background: -webkit-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
|
||||
background: -moz-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
|
||||
background: -o-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
|
||||
background: -ms-linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
|
||||
background: linear-gradient(top, #fcfff4 0%, #dfe5d7 40%, #b3bead 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfff4', endColorstr='#b3bead',GradientType=0 );
|
||||
margin: 5px auto;
|
||||
|
||||
-webkit-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
|
||||
-moz-box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
|
||||
box-shadow: inset 0px 1px 1px white, 0px 1px 3px rgba(0,0,0,0.5);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.squaredThree label {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
left: 2px;
|
||||
top: 2px;
|
||||
|
||||
-webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
|
||||
-moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
|
||||
box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,1);
|
||||
|
||||
background: -webkit-linear-gradient(top, #222 0%, #45484d 100%);
|
||||
background: -moz-linear-gradient(top, #222 0%, #45484d 100%);
|
||||
background: -o-linear-gradient(top, #222 0%, #45484d 100%);
|
||||
background: -ms-linear-gradient(top, #222 0%, #45484d 100%);
|
||||
background: linear-gradient(top, #222 0%, #45484d 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#222', endColorstr='#45484d',GradientType=0 );
|
||||
}
|
||||
|
||||
.squaredThree label:after {
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 9px;
|
||||
height: 5px;
|
||||
background: transparent;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
border: 3px solid #fcfff4;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
|
||||
-webkit-transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-o-transform: rotate(-45deg);
|
||||
-ms-transform: rotate(-45deg);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.squaredThree label:hover::after {
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)";
|
||||
filter: alpha(opacity=30);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.squaredThree input[type=checkbox]:checked + label:after {
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
|
||||
filter: alpha(opacity=100);
|
||||
opacity: 1;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
[region=aside]
|
||||
[widget=design_tools][/widget]
|
||||
[widget=website_import_tools][/widget]
|
||||
[widget=website_portation_tools][/widget]
|
||||
[/region]
|
124
view/tpl/webpage_export_list.tpl
Normal file
124
view/tpl/webpage_export_list.tpl
Normal file
@ -0,0 +1,124 @@
|
||||
<div class="generic-content-wrapper">
|
||||
<form action="" method="post" autocomplete="on" >
|
||||
<input type="hidden" name="action" value="{{$action}}">
|
||||
<div class="section-title-wrapper">
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-md btn-success" type="submit" name="submit" value="{{$exportbtn}}">{{$exportbtn}}</button>
|
||||
</div>
|
||||
<h2>{{$title}}</h2>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div id="import-website-content-wrapper" class="section-content-wrapper">
|
||||
<div class="pull-left">
|
||||
<button id="toggle-select-all" class="btn btn-xs btn-primary" onclick="checkedAll(window.isChecked); return false;"><i class="fa fa-check"></i> Toggle Select All</button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
<hr>
|
||||
<!--<h4>Pages</h4>-->
|
||||
<div>
|
||||
<table class="table-striped table-responsive table-hover" style="width: 100%;">
|
||||
<thead>
|
||||
<tr><th></th><th>Page Link</th><th>Page Title</th><th>Type</th></tr>
|
||||
</thead>
|
||||
{{foreach $pages as $page}}
|
||||
<tr>
|
||||
<td width="30px" style="padding-right: 20px;">
|
||||
<div class='squaredThree'>
|
||||
<input type="checkbox" id="page_{{$page.mid}}" name="page[]" value="{{$page.mid}}">
|
||||
<label for="page_{{$page.mid}}"></label>
|
||||
</div>
|
||||
</td>
|
||||
<td width="30%">
|
||||
<div class="desc">
|
||||
{{$page.pagetitle}}<br>
|
||||
</div>
|
||||
</td>
|
||||
<td width="55%">
|
||||
<div class='desc'>
|
||||
{{$page.title}}<br>
|
||||
</div>
|
||||
</td>
|
||||
<td width="15%">
|
||||
<div class='desc'>
|
||||
{{$page.mimetype}}<br>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/foreach}}
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="clear"></div>
|
||||
<!--<h4>Layouts</h4>-->
|
||||
<div>
|
||||
<table class="table-striped table-responsive table-hover" style="width: 100%;">
|
||||
<thead>
|
||||
<tr><th width="20px"></th><th>Layout Name</th><th>Layout Description</th><th>Type</th></tr>
|
||||
</thead>
|
||||
{{foreach $layouts as $layout}}
|
||||
<tr>
|
||||
<td width="30px" style="padding-right: 20px;">
|
||||
<div class='squaredThree'>
|
||||
<input type="checkbox" id="layout_{{$layout.mid}}" name="layout[]" value="{{$layout.mid}}">
|
||||
<label for="layout_{{$layout.mid}}"></label>
|
||||
</div>
|
||||
</td>
|
||||
<td width="30%">
|
||||
<div class="desc">
|
||||
{{$layout.name}}<br>
|
||||
</div>
|
||||
</td>
|
||||
<td width="55%">
|
||||
<div class='desc'>
|
||||
{{$layout.description}}<br>
|
||||
</div>
|
||||
</td>
|
||||
<td width="15%">
|
||||
<div class='desc'>
|
||||
{{$layout.mimetype}}<br>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/foreach}}
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="clear"></div>
|
||||
<!--<h4>Blocks</h4>-->
|
||||
<div>
|
||||
<table class="table-striped table-responsive table-hover" style="width: 100%;">
|
||||
<thead>
|
||||
<tr><th width="30px"></th><th>Block Name</th><th>Block Title</th><th>Type</th></tr>
|
||||
</thead>
|
||||
{{foreach $blocks as $block}}
|
||||
<tr>
|
||||
<td width="30px" style="padding-right: 20px;">
|
||||
<div class='squaredThree'>
|
||||
<input type="checkbox" id="block_{{$block.mid}}" name="block[]" value="{{$block.mid}}">
|
||||
<label for="block_{{$block.mid}}"></label>
|
||||
</div>
|
||||
</td>
|
||||
<td width="30%">
|
||||
<div class="desc">
|
||||
{{$block.name}}<br>
|
||||
</div>
|
||||
</td>
|
||||
<td width="55%">
|
||||
<div class='desc'>
|
||||
{{$block.title}}<br>
|
||||
</div>
|
||||
</td>
|
||||
<td width=15%">
|
||||
<div class='desc'>
|
||||
{{$block.mimetype}}<br>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{/foreach}}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,37 +0,0 @@
|
||||
<div id="website-import-tools" class="widget">
|
||||
<h3>{{$title}}</h3>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li>
|
||||
<a href="#" onclick="openClose('import-form');
|
||||
return false;"><i class="fa fa-cloud-upload generic-icons"></i> {{$import_label}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<form id="import-form" enctype="multipart/form-data" method="post" action="" style="display: none;" class="sub-menu">
|
||||
|
||||
<input type="hidden" name="action" value="scan">
|
||||
|
||||
<p style="margin-top: 20px;" class="descriptive-text">{{$file_import_text}}</p>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input class="widget-input" type="text" name="path" title="{{$hint}}" placeholder="{{$desc}}" />
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default btn-sm" type="submit" name="cloudsubmit" value="{{$select}}"><i class="fa fa-folder-open generic-icons"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Or upload a zipped file containing the website -->
|
||||
<p class="descriptive-text">{{$file_upload_text}}</p>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="input-group">
|
||||
<input class="widget-input" type="file" name="zip_file" />
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default btn-sm" type="submit" name="w_upload" value="w_upload"><i class="fa fa-file-archive-o generic-icons"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
72
view/tpl/website_portation_tools.tpl
Normal file
72
view/tpl/website_portation_tools.tpl
Normal file
@ -0,0 +1,72 @@
|
||||
<div id="website-portation-tools" class="widget">
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li>
|
||||
<a href="#" onclick="openClose('import-form');
|
||||
return false;"><i class="fa fa-cloud-upload generic-icons"></i> {{$import_label}}</a>
|
||||
</li>
|
||||
<li style="margin-left: 12px;" >
|
||||
<form id="import-form" enctype="multipart/form-data" method="post" action="" style="display: none;" class="sub-menu">
|
||||
|
||||
<input type="hidden" name="action" value="scan">
|
||||
|
||||
<p style="margin-top: 10px;" class="descriptive-text">{{$file_import_text}}</p>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<input class="widget-input" type="text" name="path" title="{{$hint}}" placeholder="{{$desc}}" />
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default btn-sm" type="submit" name="cloudsubmit" value="{{$select}}"><i class="fa fa-folder-open generic-icons"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Or upload a zipped file containing the website -->
|
||||
<p class="descriptive-text">{{$file_upload_text}}</p>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="input-group">
|
||||
<input class="widget-input" type="file" name="zip_file" />
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default btn-sm" type="submit" name="w_upload" value="w_upload"><i class="fa fa-file-archive-o generic-icons"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav nav-pills nav-stacked">
|
||||
<li>
|
||||
<a href="#" onclick="openClose('export-form'); openClose('export-cloud-form');
|
||||
return false;"><i class="fa fa-share-square-o generic-icons"></i> {{$export_label}}</a>
|
||||
</li>
|
||||
<li style="margin-left: 12px;" >
|
||||
<form id="export-form" enctype="multipart/form-data" method="post" action="" style="display: none;" class="sub-menu">
|
||||
<input type="hidden" name="action" value="exportzipfile">
|
||||
<!-- Or download a zipped file containing the website -->
|
||||
<p style="margin-top: 10px;" class="descriptive-text">{{$file_download_text}}</p>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="input-group">
|
||||
<input class="widget-input" type="text" name="zipfilename" title="{{$filename_hint}}" placeholder="{{$filename_desc}}" value="" />
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default btn-sm" type="submit" name="w_download" value="w_download"><i class="fa fa-download generic-icons"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="export-cloud-form" enctype="multipart/form-data" method="post" action="" style="display: none;" class="sub-menu">
|
||||
<input type="hidden" name="action" value="exportcloud">
|
||||
<!-- Or export the website elements to a cloud files folder -->
|
||||
<p style="margin-top: 10px;" class="descriptive-text">{{$cloud_export_text}}</p>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="input-group">
|
||||
<input class="widget-input" type="text" name="exportcloudpath" title="{{$cloud_export_hint}}" placeholder="{{$cloud_export_desc}}" />
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default btn-sm" type="submit" name="exportcloudsubmit" value="{{$cloud_export_select}}"><i class="fa fa-folder-open generic-icons"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
Reference in New Issue
Block a user