This commit is contained in:
Andrew Manning 2017-02-01 17:08:46 -05:00
commit 61407ad6c8
12 changed files with 707 additions and 733 deletions

View file

@ -112,9 +112,9 @@ class Import extends \Zotlabs\Web\Controller {
// print_r($data);
if(array_key_exists('user',$data) && array_key_exists('version',$data)) {
require_once('include/Import/import_diaspora.php');
import_diaspora($data);
if(! array_key_exists('compatibility',$data)) {
call_hooks('import_foreign_channel_data',$data);
if($data['handled'])
return;
}
@ -181,6 +181,7 @@ class Import extends \Zotlabs\Web\Controller {
if($completed < 3) {
if(array_key_exists('channel',$data)) {
if($data['photo']) {
require_once('include/photo/photo_driver.php');
import_channel_photo(base64url_decode($data['photo']['data']),$data['photo']['type'],$account_id,$channel['channel_id']);
@ -188,7 +189,7 @@ class Import extends \Zotlabs\Web\Controller {
if(is_array($data['profile']))
import_profiles($channel,$data['profile']);
}
logger('import step 3');
$_SESSION['import_step'] = 3;
}
@ -207,6 +208,7 @@ class Import extends \Zotlabs\Web\Controller {
if($completed < 5) {
// create new hubloc for the new channel at this site
if(array_key_exists('channel',$data)) {
$r = hubloc_store_lowlevel(
[
'hubloc_guid' => $channel['channel_guid'],
@ -232,6 +234,8 @@ class Import extends \Zotlabs\Web\Controller {
dbesc(z_root())
);
}
}
logger('import step 5');
$_SESSION['import_step'] = 5;
}
@ -241,7 +245,7 @@ class Import extends \Zotlabs\Web\Controller {
// import xchans and contact photos
if($seize) {
if(array_key_exists('channel',$data) && $seize) {
// replace any existing xchan we may have on this site if we're seizing control
@ -328,8 +332,6 @@ class Import extends \Zotlabs\Web\Controller {
}
// FIXME - ensure we have an xchan if somebody is trying to pull a fast one
if($completed < 8) {
@ -479,6 +481,9 @@ class Import extends \Zotlabs\Web\Controller {
if(is_array($data['wiki']))
import_items($channel,$data['wiki'],false,$relocate);
if(is_array($data['webpages']))
import_items($channel,$data['webpages'],false,$relocate);
$addon = array('channel' => $channel,'data' => $data);
call_hooks('import_channel',$addon);

View file

@ -9,9 +9,10 @@ class Uexport extends \Zotlabs\Web\Controller {
killme();
if(argc() > 1) {
$channel = \App::get_channel();
require_once('include/channel.php');
$sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : '');
$channel = \App::get_channel();
if(argc() > 1 && intval(argv(1)) > 1900) {
$year = intval(argv(1));
@ -30,15 +31,16 @@ class Uexport extends \Zotlabs\Web\Controller {
}
if(argc() > 1 && argv(1) === 'basic') {
echo json_encode(identity_basic_export(local_channel()));
echo json_encode(identity_basic_export(local_channel(),$sections));
killme();
}
// FIXME - this basically doesn't work in the wild with a channel more than a few months old due to memory and execution time limits.
// It probably needs to be built at the CLI and offered to download as a tarball. Maybe stored in the members dav.
// Warning: this option may consume a lot of memory
if(argc() > 1 && argv(1) === 'complete') {
echo json_encode(identity_basic_export(local_channel(),true));
$sections = get_default_export_sections();
$sections[] = 'items';
echo json_encode(identity_basic_export(local_channel(),$sections));
killme();
}
}
@ -57,6 +59,7 @@ class Uexport extends \Zotlabs\Web\Controller {
'$basic' => t('Export your basic channel information to a file. This acts as a backup of your connections, permissions, profile and basic data, which can be used to import your data to a new server hub, but does not contain your content.'),
'$fulltitle' => t('Export Content'),
'$full' => t('Export your channel information and recent content to a JSON backup that can be restored or imported to another server hub. This backs up all of your connections, permissions, profile data and several months of posts. This file may be VERY large. Please be patient - it may take several minutes for this download to begin.'),
'$by_year' => t('Export your posts from a given year.'),
'$extra' => t('You may also export your posts and conversations for a particular year or month. Adjust the date in your browser location bar to select other dates. If the export fails (possibly due to memory exhaustion on your server hub), please try again selecting a more limited date range.'),

View file

@ -99,6 +99,17 @@ class Comanche {
}
}
/**
* Currently supported condition variables:
*
* $config.xxx.yyy - get_config with cat = xxx and k = yyy
* $request - request uri for this page
* $observer.language - viewer's preferred language (closest match)
* $observer.address - xchan_addr or false
* $observer.name - xchan_name or false
* $observer - xchan_hash of observer or empty string
*/
function get_condition_var($v) {
if($v) {
$x = explode('.',$v);

View file

@ -0,0 +1,10 @@
[h3]get_default_export_sections[/h3]
The get_default_export_sections call returns the basic functional groups of data to export using channel_export_basic().
The hook is passed an array
[
'sections' => [ 'channel', 'connections', 'config', 'apps', 'chatrooms', 'events', 'webpages', 'mail', 'wikis' ]
]
If you desire the export to contain three months of items, add 'items' to the 'sections' array

View file

@ -1 +1,10 @@
[h2]identity_basic_export[/h2]
Called when exporting data for a channel
Passed array contains
[
'channel_id' => channel_id being exported
'sections' => array of functional export sections which are being exported
'data' => the export data array which has been generated
]

View file

@ -242,6 +242,9 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
[zrl=[baseurl]/help/hook/get_best_language]get_best_language[/zrl]
called when choosing the preferred language for the page
[zrl=[baseurl]/help/hook/get_default_export_sections]get_default_export_sections[/zrl]
Called to get the default list of functional data groups to export in identity_basic_export()
[zrl=[baseurl]/help/hook/get_features]get_features[/zrl]
Called when get_features() is called

View file

@ -49,6 +49,10 @@ Topical tags are indicated by preceding the tag name with the # character. This
Topical tags are also not linked if they are purely numeric, e.g. #1. If you wish to use a numeric hashtag, please add some descriptive text such as #[zrl=https://friendicared.net/search?tag=2012-elections]2012-elections[/zrl].
[b]Bookmarks[/b]
Bookmarks indicate a link which can be saved to your bookmark folder. They use the sequence #^ followed by the link. Often these are generatd automatically. If the 'bookmarker' addon is installed, this sequence will be converted to a bookmark icon when viewing the post or comment online and clicking the icon will save the bookmark. If the bookmarker addon is not installed, the post 'dropdown menu' contains a link for saving the bookmark or bookmarks.
[b]Spaces in Tags and Mentions[/b]

View file

@ -1,148 +0,0 @@
<?php
require_once('include/bb2diaspora.php');
require_once('include/group.php');
require_once('include/follow.php');
require_once('include/photo/photo_driver.php');
function import_diaspora($data) {
$account = App::get_account();
if(! $account)
return false;
$address = escape_tags($data['user']['username']);
if(! $address) {
notice( t('No username found in import file.') . EOL);
return false;
}
$r = q("select * from channel where channel_address = '%s' limit 1",
dbesc($address)
);
if($r) {
// try at most ten times to generate a unique address.
$x = 0;
$found_unique = false;
do {
$tmp = $address . mt_rand(1000,9999);
$r = q("select * from channel where channel_address = '%s' limit 1",
dbesc($tmp)
);
if(! $r) {
$address = $tmp;
$found_unique = true;
break;
}
$x ++;
} while ($x < 10);
if(! $found_unique) {
logger('import_diaspora: duplicate channel address. randomisation failed.');
notice( t('Unable to create a unique channel address. Import failed.') . EOL);
return;
}
}
$c = create_identity(array(
'name' => escape_tags($data['user']['name']),
'nickname' => $address,
'account_id' => $account['account_id'],
'permissions_role' => 'social'
));
if(! $c['success'])
return;
$channel_id = $c['channel']['channel_id'];
// Hubzilla only: Turn on the Diaspora protocol so that follow requests will be sent.
set_pconfig($channel_id,'system','diaspora_allowed','1');
// todo - add auto follow settings, (and strip exif in hubzilla)
$location = escape_tags($data['user']['profile']['location']);
if(! $location)
$location = '';
q("update channel set channel_location = '%s' where channel_id = %d",
dbesc($location),
intval($channel_id)
);
if($data['user']['profile']['nsfw']) {
q("update channel set channel_pageflags = (channel_pageflags | %d) where channel_id = %d",
intval(PAGE_ADULT),
intval($channel_id)
);
}
if($data['user']['profile']['image_url']) {
$p = z_fetch_url($data['user']['profile']['image_url'],true);
if($p['success']) {
$rawbytes = $p['body'];
$type = guess_image_type('dummyfile',$p['header']);
import_channel_photo($rawbytes,$type,$c['channel']['channel_account_id'],$channel_id);
}
}
$gender = escape_tags($data['user']['profile']['gender']);
$about = markdown_to_bb($data['user']['profile']['bio']);
$publish = intval($data['user']['profile']['searchable']);
if($data['user']['profile']['birthday'])
$dob = datetime_convert('UTC','UTC',$data['user']['profile']['birthday'],'Y-m-d');
else
$dob = '0000-00-00';
// we're relying on the fact that this channel was just created and will only
// have the default profile currently
$r = q("update profile set gender = '%s', about = '%s', dob = '%s', publish = %d where uid = %d",
dbesc($gender),
dbesc($about),
dbesc($dob),
dbesc($publish),
intval($channel_id)
);
if($data['user']['aspects']) {
foreach($data['user']['aspects'] as $aspect) {
group_add($channel_id,escape_tags($aspect['name']),intval($aspect['contacts_visible']));
}
}
// now add connections and send friend requests
if($data['user']['contacts']) {
foreach($data['user']['contacts'] as $contact) {
$result = new_contact($channel_id, $contact['person_diaspora_handle'], $c['channel']);
if($result['success']) {
if($contact['aspects']) {
foreach($contact['aspects'] as $aspect) {
group_add_member($channel_id,$aspect['name'],$result['abook']['xchan_hash']);
}
}
}
}
}
// Then add items - note this can't be done until Diaspora adds guids to exported
// items and comments
// This will indirectly perform a refresh_all *and* update the directory
proc_run('php', 'include/directory.php', $channel_id);
notice( t('Import completed.') . EOL);
change_channel($channel_id);
goaway(z_root() . '/network' );
}

View file

@ -69,8 +69,13 @@
logger('api_export_basic: no user');
return false;
}
$sections = (($_REQUEST['sections']) ? explode(',',$_REQUEST['sections']) : '');
if($_REQUEST['posts']) {
$sections = get_default_export_sections();
$sections[] = 'items';
}
json_return_and_die(identity_basic_export(api_user(),(($_REQUEST['posts']) ? intval($_REQUEST['posts']) : 0 )));
json_return_and_die(identity_basic_export(api_user(),$sections));
}

View file

@ -476,6 +476,16 @@ function set_default_login_identity($account_id, $channel_id, $force = true) {
}
}
function get_default_export_sections() {
$sections = [ 'channel', 'connections', 'config', 'apps', 'chatrooms', 'events', 'webpages', 'mail', 'wikis' ];
$cb = [ 'sections' => $sections ];
call_hooks('get_default_export_sections', $cb);
return $cb['sections'];
}
/**
* @brief Create an array representing the important channel information
* which would be necessary to create a nomadic identity clone. This includes
@ -489,33 +499,68 @@ function set_default_login_identity($account_id, $channel_id, $force = true) {
* @returns array
* See function for details
*/
function identity_basic_export($channel_id, $items = false) {
function identity_basic_export($channel_id, $sections = null) {
/*
* Red basic channel export
* basic channel export
*/
$ret = array();
if(! $sections) {
$sections = get_default_export_sections();
}
$ret = [];
// use constants here as otherwise we will have no idea if we can import from a site
// with a non-standard platform and version.
$ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => STD_VERSION, 'database' => DB_UPDATE_VERSION, 'server_role' => Zotlabs\Lib\System::get_server_role());
$ret['compatibility'] = [
'project' => PLATFORM_NAME,
'version' => STD_VERSION,
'database' => DB_UPDATE_VERSION,
'server_role' => Zotlabs\Lib\System::get_server_role()
];
/*
* Process channel information regardless of it is one of the sections desired
* because we need the channel relocation information in all export files/streams.
*/
$r = q("select * from channel where channel_id = %d limit 1",
intval($channel_id)
);
if($r) {
translate_channel_perms_outbound($r[0]);
$ret['channel'] = $r[0];
$ret['relocate'] = [ 'channel_address' => $r[0]['channel_address'], 'url' => z_root()];
if(in_array('channel',$sections)) {
$ret['channel'] = $r[0];
}
}
if(in_array('channel',$sections)) {
$r = q("select * from profile where uid = %d",
intval($channel_id)
);
if($r)
$ret['profile'] = $r;
$r = q("select mimetype, content, os_storage from photo
where imgscale = 4 and photo_usage = %d and uid = %d limit 1",
intval(PHOTO_PROFILE),
intval($channel_id)
);
if($r) {
$ret['photo'] = [
'type' => $r[0]['mimetype'],
'data' => (($r[0]['os_storage'])
? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content']))
];
}
}
if(in_array('connections',$sections)) {
$xchans = array();
$r = q("select * from abook where abook_channel = %d ",
intval($channel_id)
@ -556,21 +601,15 @@ function identity_basic_export($channel_id, $items = false) {
if($r)
$ret['group_member'] = $r;
}
if(in_array('config',$sections)) {
$r = q("select * from pconfig where uid = %d",
intval($channel_id)
);
if($r)
$ret['config'] = $r;
$r = q("select mimetype, content, os_storage from photo where imgscale = 4 and photo_usage = %d and uid = %d limit 1",
intval(PHOTO_PROFILE),
intval($channel_id)
);
if($r) {
$ret['photo'] = array('type' => $r[0]['mimetype'], 'data' => (($r[0]['os_storage']) ? base64url_encode(file_get_contents($r[0]['content'])) : base64url_encode($r[0]['content'])));
}
// All other term types will be included in items, if requested.
$r = q("select * from term where ttype in (%d,%d) and uid = %d",
@ -591,6 +630,16 @@ function identity_basic_export($channel_id, $items = false) {
if($r)
$ret['obj'] = $r;
$r = q("select * from likes where channel_id = %d",
intval($channel_id)
);
if($r)
$ret['likes'] = $r;
}
if(in_array('apps',$sections)) {
$r = q("select * from app where app_channel = %d and app_system = 0",
intval($channel_id)
);
@ -603,13 +652,18 @@ function identity_basic_export($channel_id, $items = false) {
}
$ret['app'] = $r;
}
}
if(in_array('chatrooms',$sections)) {
$r = q("select * from chatroom where cr_uid = %d",
intval($channel_id)
);
if($r)
$ret['chatroom'] = $r;
}
if(in_array('events',$sections)) {
$r = q("select * from event where uid = %d",
intval($channel_id)
);
@ -626,7 +680,9 @@ function identity_basic_export($channel_id, $items = false) {
foreach($r as $rr)
$ret['event_item'][] = encode_item($rr,true);
}
}
if(in_array('webpages',$sections)) {
$x = menu_list($channel_id);
if($x) {
$ret['menu'] = array();
@ -636,22 +692,21 @@ function identity_basic_export($channel_id, $items = false) {
$ret['menu'][] = menu_element($ret['channel'],$m);
}
}
$addon = array('channel_id' => $channel_id,'data' => $ret);
call_hooks('identity_basic_export',$addon);
$ret = $addon['data'];
if(! $items)
return $ret;
$r = q("select * from likes where channel_id = %d",
$r = q("select * from item where item_type in ( "
. ITEM_TYPE_BLOCK . "," . ITEM_TYPE_PDL . "," . ITEM_TYPE_WEBPAGE . " ) and uid = %d",
intval($channel_id)
);
if($r) {
$ret['webpages'] = array();
xchan_query($r);
$r = fetch_post_tags($r,true);
foreach($r as $rr)
$ret['webpages'][] = encode_item($rr,true);
if($r)
$ret['likes'] = $r;
}
}
if(in_array('mail',$sections)) {
$r = q("select * from conv where uid = %d",
intval($channel_id)
);
@ -673,7 +728,9 @@ function identity_basic_export($channel_id, $items = false) {
}
$ret['mail'] = $m;
}
}
if(in_array('wikis',$sections)) {
$r = q("select * from item where resource_type like 'nwiki%%' and uid = %d order by created",
intval($channel_id)
);
@ -685,17 +742,19 @@ function identity_basic_export($channel_id, $items = false) {
$ret['wiki'][] = encode_item($rv,true);
}
}
}
if(in_array('items',$sections)) {
/** @warning this may run into memory limits on smaller systems */
/** export three months of posts. If you want to export and import all posts you have to start with
* the first year and export/import them in ascending order.
*
* Don't export linked resource items. we'll have to pull those out separately.
*/
$r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created",
$r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d
and created > %s - INTERVAL %s and resource_type = '' order by created",
intval($channel_id),
db_utcnow(),
db_quoteinterval('3 MONTH')
@ -707,6 +766,11 @@ function identity_basic_export($channel_id, $items = false) {
foreach($r as $rr)
$ret['item'][] = encode_item($rr,true);
}
}
$addon = [ 'channel_id' => $channel_id, 'sections' => $sections, 'data' => $ret];
call_hooks('identity_basic_export',$addon);
$ret = $addon['data'];
return $ret;
}
@ -782,7 +846,7 @@ function channel_export_items($channel_id, $start, $finish) {
$ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()];
}
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created",
$r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created <= '%s' and resource_type = '' order by created",
intval(ITEM_TYPE_POST),
intval($channel_id),
dbesc($start),

View file

@ -1209,38 +1209,41 @@ function scan_webpage_elements($path, $type, $cloud = false) {
$dirtoscan = get_dirpath_by_cloudpath($channel, $dirtoscan);
}
$elements = [];
if (is_dir($dirtoscan)) {
if(is_dir($dirtoscan)) {
$dirlist = scandir($dirtoscan);
if ($dirlist) {
foreach ($dirlist as $element) {
if ($element === '.' || $element === '..') {
if($dirlist) {
foreach($dirlist as $element) {
if($element === '.' || $element === '..') {
continue;
}
$folder = $dirtoscan . '/' . $element;
if (is_dir($folder)) {
if(is_dir($folder)) {
if($cloud) {
$jsonfilepath = $folder . '/' . get_filename_by_cloudname($json_filename, $channel, $folder);
} else {
}
else {
$jsonfilepath = $folder . '/' . $json_filename;
}
if (is_file($jsonfilepath)) {
if(is_file($jsonfilepath)) {
$metadata = json_decode(file_get_contents($jsonfilepath), true);
if($cloud) {
$contentfilename = get_filename_by_cloudname($metadata['contentfile'], $channel, $folder);
$metadata['path'] = $folder . '/' . $contentfilename;
} else {
}
else {
$contentfilename = $metadata['contentfile'];
$metadata['path'] = $folder . '/' . $contentfilename;
}
if ($metadata['contentfile'] === '') {
if($metadata['contentfile'] === '') {
logger('Invalid ' . $type . ' content file');
return false;
}
$content = file_get_contents($folder . '/' . $contentfilename);
if (!$content) {
if(!$content) {
if(is_readable($folder . '/' . $contentfilename)) {
$content = '';
} else {
}
else {
logger('Failed to get file content for ' . $metadata['contentfile']);
return false;
}
@ -1252,14 +1255,14 @@ function scan_webpage_elements($path, $type, $cloud = false) {
}
}
return $elements;
}
}
function import_webpage_element($element, $channel, $type) {
function import_webpage_element($element, $channel, $type) {
$arr = array(); // construct information for the webpage element item table record
switch ($type) {
switch($type) {
//
// PAGES
//
@ -1325,7 +1328,8 @@ function scan_webpage_elements($path, $type, $cloud = false) {
);
$arr['mid'] = $arr['parent_mid'] = $iteminfo[0]['mid'];
$arr['created'] = $iteminfo[0]['created'];
} else { // otherwise, generate the creation times and unique id
}
else { // otherwise, generate the creation times and unique id
$arr['created'] = datetime_convert('UTC', 'UTC');
$arr['mid'] = $arr['parent_mid'] = item_message_id();
}
@ -1348,21 +1352,23 @@ function scan_webpage_elements($path, $type, $cloud = false) {
// Blocks and pages can have any of the valid mimetypes, but layouts must be text/bbcode
if((in_array($element['mimetype'], $mimetypes)) && ($type === 'page' || $type === 'block') ) {
$arr['mimetype'] = $element['mimetype'];
} else {
}
else {
$arr['mimetype'] = 'text/bbcode';
}
// Verify ability to use html or php!!!
$execflag = false;
if ($arr['mimetype'] === 'application/x-php' || $arr['mimetype'] === 'text/html') {
if($arr['mimetype'] === 'application/x-php' || $arr['mimetype'] === 'text/html') {
$z = q("select account_id, account_roles, channel_pageflags from account "
. "left join channel on channel_account_id = account_id where channel_id = %d limit 1",
intval(local_channel())
);
if ($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
if($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) {
$execflag = true;
} else {
}
else {
logger('Unable to import element "' . $name .'" because AllowCode permission is denied.');
notice( t('Unable to import element "' . $name .'" because AllowCode permission is denied.') . EOL);
$element['import_success'] = 0;
@ -1380,14 +1386,15 @@ function scan_webpage_elements($path, $type, $cloud = false) {
intval(local_channel())
);
$remote_id = 0;
if ($z && $i) {
if($z && $i) {
$remote_id = $z[0]['id'];
$arr['id'] = $i[0]['id'];
// don't update if it has the same timestamp as the original
if ($arr['edited'] > $i[0]['edited'])
if($arr['edited'] > $i[0]['edited'])
$x = item_store_update($arr, $execflag);
} else {
if (($i) && (intval($i[0]['item_deleted']))) {
}
else {
if(($i) && (intval($i[0]['item_deleted']))) {
// was partially deleted already, finish it off
q("delete from item where mid = '%s' and uid = %d",
dbesc($arr['mid']),
@ -1396,16 +1403,16 @@ function scan_webpage_elements($path, $type, $cloud = false) {
}
$x = item_store($arr, $execflag);
}
if ($x['success']) {
if($x['success']) {
$item_id = $x['item_id'];
update_remote_id($channel, $item_id, $arr['item_type'], $name, $namespace, $remote_id, $arr['mid']);
$element['import_success'] = 1;
} else {
}
else {
$element['import_success'] = 0;
}
return $element;
}
function get_webpage_elements($channel, $type = 'all') {
@ -1413,7 +1420,7 @@ function get_webpage_elements($channel, $type = 'all') {
if(!$channel['channel_id']) {
return null;
}
switch ($type) {
switch($type) {
case 'all':
// If all, execute all the pages, layouts, blocks case statements
case 'pages':
@ -1501,7 +1508,6 @@ function get_webpage_elements($channel, $type = 'all') {
'mid' => $rr['mid'],
);
}
}
if($type !== 'all') {
@ -1558,32 +1564,32 @@ function get_webpage_elements($channel, $type = 'all') {
/* 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) {
// 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)) {
// 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)) {
// 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) {
if($zip->open($destination, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
return false;
}
//add the files
foreach ($valid_files as $file) {
// add the files
foreach($valid_files as $file) {
$zip->addFile($file, $file);
}
//debug
@ -1591,9 +1597,10 @@ function create_zip_file($files = array(), $destination = '', $overwrite = false
//close the zip -- done!
$zip->close();
//check to make sure the file exists
// check to make sure the file exists
return file_exists($destination);
} else {
}
else {
return false;
}
}

View file

@ -3130,6 +3130,7 @@ function gen_link_id($mid) {
return $mid;
}
// callback for array_walk
function array_trim(&$v,$k) {