From c98b91f5149d53f522a19ec0f69b4d4727d34896 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 17 Aug 2016 18:19:36 -0400 Subject: Stash changes for merge with dev --- include/text.php | 22 ++++++++++++++++++++++ include/widgets.php | 15 +++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'include') diff --git a/include/text.php b/include/text.php index a2a6d918b..c8e0b1888 100644 --- a/include/text.php +++ b/include/text.php @@ -2294,6 +2294,28 @@ function website_import_tools() { )); } +/** + * @brief Creates website export tools menu + * + * @return string + */ +function website_export_tools() { + + $channel = App::get_channel(); + $sys = false; + + if(App::$is_sys && is_site_admin()) { + require_once('include/channel.php'); + $channel = get_sys_channel(); + $sys = true; + } + + return replace_macros(get_markup_template('website_export_tools.tpl'), array( + '$title' => t('Export'), + '$export_label' => t('Export website...'), + )); +} + /* case insensitive in_array() */ function in_arrayi($needle, $haystack) { diff --git a/include/widgets.php b/include/widgets.php index 68db74703..fc2a9830b 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -794,6 +794,21 @@ function widget_website_import_tools($arr) { return website_import_tools(); } +function widget_website_export_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. + + if(App::$profile['profile_uid']) + if((App::$profile['profile_uid'] != local_channel()) && (! App::$is_sys)) + return ''; + + if(! local_channel()) + return ''; + + return website_export_tools(); +} + function widget_findpeople($arr) { return findpeople_widget(); } -- cgit v1.2.3 From f2e87a204d0a257edb501dfedaad867700c58842 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Wed, 17 Aug 2016 21:25:50 -0400 Subject: Progress implementing zip file export --- include/text.php | 32 +++++++------------------------- include/widgets.php | 19 ++----------------- 2 files changed, 9 insertions(+), 42 deletions(-) (limited to 'include') diff --git a/include/text.php b/include/text.php index c8e0b1888..1729048e9 100644 --- a/include/text.php +++ b/include/text.php @@ -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,29 +2290,11 @@ 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'), - )); -} - -/** - * @brief Creates website export tools menu - * - * @return string - */ -function website_export_tools() { - - $channel = App::get_channel(); - $sys = false; - - if(App::$is_sys && is_site_admin()) { - require_once('include/channel.php'); - $channel = get_sys_channel(); - $sys = true; - } - - return replace_macros(get_markup_template('website_export_tools.tpl'), array( - '$title' => t('Export'), + '$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.'), )); } diff --git a/include/widgets.php b/include/widgets.php index fc2a9830b..2f8416f8e 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -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,22 +791,7 @@ function widget_website_import_tools($arr) { if(! local_channel()) return ''; - return website_import_tools(); -} - -function widget_website_export_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. - - if(App::$profile['profile_uid']) - if((App::$profile['profile_uid'] != local_channel()) && (! App::$is_sys)) - return ''; - - if(! local_channel()) - return ''; - - return website_export_tools(); + return website_portation_tools(); } function widget_findpeople($arr) { -- cgit v1.2.3 From 40a7d3821098c095a01e2a30b2b49c53bb38e2cf Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Fri, 19 Aug 2016 19:32:52 -0400 Subject: Pages populate the available-to-export list. New checkbox class for smaller boxes. --- include/import.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'include') diff --git a/include/import.php b/include/import.php index 84881a420..f7df636f3 100644 --- a/include/import.php +++ b/include/import.php @@ -1472,3 +1472,65 @@ 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 '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; + } + + } + break; + + default: + return null; + } + return $elements; +} \ No newline at end of file -- cgit v1.2.3 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. --- include/import.php | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'include') 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; + } +} -- cgit v1.2.3 From 2d42d587388aeaedf8b53b2b56b3b4ccda37af03 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 20 Aug 2016 16:05:27 -0400 Subject: Layouts list and are selectable for export to the zip file --- include/import.php | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index b4d342273..a62747d9b 100644 --- a/include/import.php +++ b/include/import.php @@ -1479,6 +1479,8 @@ function get_webpage_elements($channel, $type = 'all') { 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']; @@ -1527,10 +1529,52 @@ function get_webpage_elements($channel, $type = 'all') { } } - break; + 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; + } + default: - return null; + break; } return $elements; } -- cgit v1.2.3 From 1c61e316b477460f05b263b9a01cc5d37b5e8cb6 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Sat, 20 Aug 2016 21:08:15 -0400 Subject: Block export and re-import works. Fixed bug where layout content was not being imported properly. --- include/import.php | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index a62747d9b..10664aa53 100644 --- a/include/import.php +++ b/include/import.php @@ -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 @@ -1573,6 +1583,47 @@ function get_webpage_elements($channel, $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; } -- cgit v1.2.3 From 305e0538d293ff4ad72f30b11998ae3b06efa4ea Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 23 Aug 2016 06:55:26 -0400 Subject: Website export to cloud files works. Created new recursive copy function in attach.php. --- include/attach.php | 47 +++++++++++++++++++++++++++++++++++++++++++++++ include/text.php | 4 ++++ 2 files changed, 51 insertions(+) (limited to 'include') diff --git a/include/attach.php b/include/attach.php index 172840b96..6b17cdca1 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1994,3 +1994,50 @@ 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; +} \ No newline at end of file diff --git a/include/text.php b/include/text.php index 1729048e9..99ac59ca7 100644 --- a/include/text.php +++ b/include/text.php @@ -2295,6 +2295,10 @@ function website_portation_tools() { '$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'), )); } -- cgit v1.2.3 From 85d8300421818f81788fcf082b00f14c444be567 Mon Sep 17 00:00:00 2001 From: redmatrix Date: Tue, 30 Aug 2016 17:23:14 -0700 Subject: increase timeout on oembed remote fetches. This is a balancing act. Too short and many sites won't show up. Too long and you could be watching a spinner anxiously waiting for the page to load even if your own site is blindingly fast. --- include/oembed.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/oembed.php b/include/oembed.php index fe6f10d71..085637a00 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -156,9 +156,12 @@ function oembed_fetch_url($embedurl){ if ($action !== 'block') { // try oembed autodiscovery $redirects = 0; - $result = z_fetch_url($furl, false, $redirects, array('timeout' => 15, 'accept_content' => "text/*", 'novalidate' => true )); + $result = z_fetch_url($furl, false, $redirects, array('timeout' => 30, 'accept_content' => "text/*", 'novalidate' => true )); + if($result['success']) $html_text = $result['body']; + else + logger('fetch failure: ' . $furl); if($html_text) { $dom = @DOMDocument::loadHTML($html_text); @@ -171,7 +174,10 @@ function oembed_fetch_url($embedurl){ foreach($entries as $e){ $href = $e->getAttributeNode("href")->nodeValue; $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); - $txt = $x['body']; + if($x['success']) + $txt = $x['body']; + else + logger('fetch failed: ' . $href); break; } // soundcloud is now using text/json+oembed instead of application/json+oembed, @@ -180,7 +186,10 @@ function oembed_fetch_url($embedurl){ foreach($entries as $e){ $href = $e->getAttributeNode("href")->nodeValue; $x = z_fetch_url($href . '&maxwidth=' . App::$videowidth); - $txt = $x['body']; + if($x['success']) + $txt = $x['body']; + else + logger('json fetch failed: ' . $href); break; } } -- cgit v1.2.3 From 16b7df37170483aa8d3dba9080a5f3f3940ec202 Mon Sep 17 00:00:00 2001 From: Andrew Manning Date: Tue, 30 Aug 2016 22:11:14 -0400 Subject: Imported webpage elements update existing elements properly. AllowCode permission is checked correctly and issues error on import if denied. --- include/import.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/import.php b/include/import.php index 10664aa53..ddffb2ac3 100644 --- a/include/import.php +++ b/include/import.php @@ -1311,8 +1311,6 @@ 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) { if(is_readable($folder . '/' . $contentfilename)) { $content = ''; @@ -1401,18 +1399,14 @@ function scan_webpage_elements($path, $type, $cloud = false) { ); $arr['mid'] = $arr['parent_mid'] = $iteminfo[0]['mid']; $arr['created'] = $iteminfo[0]['created']; - $arr['edited'] = (($element['edited']) ? datetime_convert('UTC', 'UTC', $element['edited']) : datetime_convert()); } else { // otherwise, generate the creation times and unique id - $arr['created'] = (($element['created']) ? datetime_convert('UTC', 'UTC', $element['created']) : datetime_convert()); - $arr['edited'] = datetime_convert('UTC', 'UTC', '0000-00-00 00:00:00'); + $arr['created'] = datetime_convert('UTC', 'UTC'); $arr['mid'] = $arr['parent_mid'] = item_message_id(); } + // Update the edited time whether or not the element already exists + $arr['edited'] = datetime_convert('UTC', 'UTC'); // 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 @@ -1425,7 +1419,7 @@ function scan_webpage_elements($path, $type, $cloud = false) { 'application/x-pdl', 'application/x-php' ]; - // Blocks and pages can have any mimetype, but layouts must be text/bbcode + // 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 { @@ -1434,7 +1428,7 @@ function scan_webpage_elements($path, $type, $cloud = false) { // Verify ability to use html or php!!! $execflag = false; - if ($arr['mimetype'] === 'application/x-php') { + 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()) @@ -1442,10 +1436,15 @@ function scan_webpage_elements($path, $type, $cloud = false) { if ($z && (($z[0]['account_roles'] & ACCOUNT_ROLE_ALLOWCODE) || ($z[0]['channel_pageflags'] & PAGE_ALLOWCODE))) { $execflag = true; + } 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; + return $element; } } - $z = q("select * from iconfig where v = '%s' and k = '%s' and cat = 'service' limit 1", + $z = q("select * from iconfig where v = '%s' and k = '%s' and cat = 'system' limit 1", dbesc($name), dbesc($namespace) ); -- cgit v1.2.3 From 2b9322fc7d879fecbe334083bbd028538c985c54 Mon Sep 17 00:00:00 2001 From: Mario Vavti Date: Wed, 31 Aug 2016 09:38:47 +0200 Subject: provide a possibility to create checklists in bbcode [x] creates a checked checkbox, [] creates an unchecked checkbox --- include/bbcode.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/bbcode.php b/include/bbcode.php index db3a1011b..2d86bd263 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -769,6 +769,8 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) } // Check for list text $Text = str_replace("[*]", "
  • ", $Text); + $Text = str_replace("[]", "
  • ", $Text); + $Text = str_replace("[x]", "
  • ", $Text); // handle nested lists $endlessloop = 0; -- cgit v1.2.3