/** * Find file meta information for adding to a zip file * * @param PATH The full path to the folder to add * @param PATH The subpath relative to the path (should be left as the default '', as this is used for the recursion to distinguish the adding base path from where it's currently looking) * @return array A list of maps that stores time,full_path,name, for each file */ function zip_scan_folder($path, $subpath = '') { $_full = $path == '' ? $subpath : $path . '/' . $subpath; if ($_full == '') { $_full = '.'; } $info = array(); $dh = @opendir($_full); if ($dh !== false) { while (($entry = readdir($dh)) !== false) { $_subpath = $subpath == '' ? $entry : $subpath . '/' . $entry; if (!should_ignore_file($_subpath) && $entry != 'backups') { $full = $path == '' ? $_subpath : $path . '/' . $_subpath; if (!is_readable($full)) { continue; } if (is_dir($full)) { $info2 = zip_scan_folder($path, $_subpath); $info = array_merge($info, $info2); } else { $mtime = filemtime($full); $info[] = array('full_path' => $full, 'name' => $_subpath, 'time' => $mtime); } } } closedir($dh); } return $info; }
/** * Get an array of all the installed languages that can be found in root/lang/ and root/lang_custom/ * * @param boolean Whether to even find empty languages * @return array The installed languages (map, lang=>type) */ function _find_all_langs($even_empty_langs = false) { $_dir = opendir(get_file_base() . '/lang/'); $_langs = array(); while (false !== ($file = readdir($_dir))) { if (!should_ignore_file('lang/' . $file, IGNORE_ACCESS_CONTROLLERS) && strlen($file) <= 5) { if (is_dir(get_file_base() . '/lang/' . $file)) { $_langs[$file] = 'lang'; } } } closedir($_dir); if (!in_safe_mode()) { $_dir = @opendir(get_custom_file_base() . '/lang_custom/'); if ($_dir !== false) { while (false !== ($file = readdir($_dir))) { if (!should_ignore_file('lang_custom/' . $file, IGNORE_ACCESS_CONTROLLERS) && strlen($file) <= 5) { if (is_dir(get_custom_file_base() . '/lang_custom/' . $file)) { if ($even_empty_langs || is_file(get_custom_file_base() . '/lang_custom/' . $file . '/global.ini')) { $_langs[$file] = 'lang_custom'; } else { $_dir2 = opendir(get_custom_file_base() . '/lang_custom/' . $file); while (false !== ($file2 = readdir($_dir2))) { if (substr($file2, -4) == '.ini' || substr($file2, -3) == '.po') { $_langs[$file] = 'lang_custom'; break; } } } } } } closedir($_dir); } if (get_custom_file_base() != get_file_base()) { $_dir = opendir(get_file_base() . '/lang_custom/'); while (false !== ($file = readdir($_dir))) { if (!should_ignore_file('lang_custom/' . $file, IGNORE_ACCESS_CONTROLLERS) && strlen($file) <= 5) { if ($even_empty_langs) { $_langs[$file] = 'lang_custom'; } else { $_dir2 = opendir(get_file_base() . '/lang_custom/' . $file); while (false !== ($file2 = readdir($_dir2))) { if (substr($file2, -4) == '.ini' || substr($file2, -3) == '.po') { $_langs[$file] = 'lang_custom'; break; } } } } } closedir($_dir); } } return $_langs; }
/** * Standard modular run function for do_next_menu hooks. They find links to put on standard navigation menus of the system. * * @return array Array of links and where to show */ function run() { $has_langs = false; $_dir = opendir(get_file_base() . '/lang/'); $_langs = array(); while (false !== ($file = readdir($_dir))) { if ($file == fallback_lang()) { continue; } if (!should_ignore_file('lang/' . $file, IGNORE_ACCESS_CONTROLLERS) && strlen($file) <= 5) { if (is_dir(get_file_base() . '/lang/' . $file)) { $has_langs = true; } } } closedir($_dir); if (!in_safe_mode()) { $_dir = @opendir(get_custom_file_base() . '/lang_custom/'); if ($_dir !== false) { while (false !== ($file = readdir($_dir))) { if ($file == fallback_lang()) { continue; } if (!should_ignore_file('lang_custom/' . $file, IGNORE_ACCESS_CONTROLLERS) && strlen($file) <= 5) { if (is_dir(get_custom_file_base() . '/lang_custom/' . $file)) { $has_langs = true; } } } closedir($_dir); } if (get_custom_file_base() != get_file_base()) { $_dir = opendir(get_file_base() . '/lang_custom/'); while (false !== ($file = readdir($_dir))) { if ($file == fallback_lang()) { continue; } if (!should_ignore_file('lang_custom/' . $file, IGNORE_ACCESS_CONTROLLERS) && strlen($file) <= 5) { $has_langs = true; } } closedir($_dir); } } return array(array('style', 'language', array('admin_lang', array('type' => 'misc'), get_module_zone('admin_lang')), do_lang_tempcode('TRANSLATE_CODE'), 'DOC_TRANSLATE'), multi_lang() ? array('style', 'language', array('admin_lang', array('type' => 'content'), get_module_zone('admin_lang')), do_lang_tempcode('TRANSLATE_CONTENT'), 'DOC_TRANSLATE_CONTENT') : NULL, !$has_langs ? NULL : array('style', 'criticise_language', array('admin_lang', array('type' => 'criticise'), get_module_zone('admin_lang')), do_lang_tempcode('CRITICISE_LANGUAGE_PACK'), 'DOC_CRITICISE_LANGUAGE_PACK')); }
/** * Standard modular listing function for OcCLE FS hooks. * * @param array The current meta-directory path * @param string The root node of the current meta-directory * @param array The current directory listing * @param array A reference to the OcCLE filesystem object * @return ~array The final directory listing (false: failure) */ function listing($meta_dir, $meta_root_node, $current_dir, &$occle_fs) { $path = get_custom_file_base() . '/uploads/filedump'; foreach ($meta_dir as $meta_dir_section) { $path .= '/' . filter_naughty($meta_dir_section); } $listing = array(); if (is_dir($path)) { $dh = opendir($path); while (($file = readdir($dh)) !== false) { if (!should_ignore_file($file, IGNORE_ACCESS_CONTROLLERS)) { if (is_dir($path . '/' . $file)) { $listing[$file] = array(); } else { $listing[] = $file; } } } return $listing; } return false; //Directory doesn't exist }
/** * Scan a directory for files, and put them into the tempcode as an entry in the visual list. * * @param PATH The directory path * @return tempcode The visual list of files */ function do_dir($path) { $out = new ocp_tempcode(); $files_here = array(); $dirs_here = array(); $handle = @opendir($path); if ($handle !== false) { while (false !== ($file = readdir($handle))) { if (!should_ignore_file($file, IGNORE_ACCESS_CONTROLLERS | IGNORE_HIDDEN_FILES)) { if (is_file($path . '/' . $file)) { $filefull = substr($path, strlen(get_file_base() . '/')) . '/' . $file; $files_here[] = $filefull; } else { $dirs_here[] = $path . '/' . $file; } } } closedir($handle); } else { warn_exit(do_lang_tempcode('DIRECTORY_NOT_FOUND', escape_html($path))); } sort($files_here); foreach ($files_here as $filefull) { $out->attach(do_template('BULK_HELPER_ENTRY', array('_GUID' => 'f57ec94c57b0ef0096c80a6c463f31d3', 'FILEFULL' => $filefull))); } sort($dirs_here); foreach ($dirs_here as $dir) { $out->attach($this->do_dir($dir)); } return $out; }
/** * The main user interface for the file dump. * * @return tempcode The UI. */ function module_do_gui() { $title = get_page_title('FILE_DUMP'); $place = filter_naughty(get_param('place', '/')); if (substr($place, -1, 1) != '/') { $place .= '/'; } $GLOBALS['FEED_URL'] = find_script('backend') . '?mode=filedump&filter=' . $place; // Show tree $dirs = explode('/', substr($place, 0, strlen($place) - 1)); $i = 0; $pre = ''; $file_tree = new ocp_tempcode(); while (array_key_exists($i, $dirs)) { if ($i > 0) { $d = $dirs[$i]; } else { $d = do_lang('FILE_DUMP'); } if (array_key_exists($i + 1, $dirs)) { $tree_url = build_url(array('page' => '_SELF', 'place' => $pre . $dirs[$i] . '/'), '_SELF'); if (!$file_tree->is_empty()) { $file_tree->attach(do_template('BREADCRUMB', array('_GUID' => '7ee62e230d53344a7d9667dc59be21c6'))); } $file_tree->attach(hyperlink($tree_url, $d)); } $pre .= $dirs[$i] . '/'; $i++; } if (!$file_tree->is_empty()) { breadcrumb_add_segment($file_tree, $d); } else { breadcrumb_set_self($i == 1 ? do_lang_tempcode('FILE_DUMP') : make_string_tempcode(escape_html($d))); } // Check directory exists $fullpath = get_custom_file_base() . '/uploads/filedump' . $place; if (!file_exists(get_custom_file_base() . '/uploads/filedump' . $place)) { if (has_specific_permission(get_member(), 'upload_filedump')) { @mkdir($fullpath, 0777) or warn_exit(do_lang_tempcode('WRITE_ERROR_DIRECTORY', escape_html($fullpath), escape_html(dirname($fullpath)))); fix_permissions($fullpath, 0777); sync_file($fullpath); } } // Find all files in the incoming directory $handle = opendir(get_custom_file_base() . '/uploads/filedump' . $place); $i = 0; $filename = array(); $description = array(); $filesize = array(); $filetime = array(); $directory = array(); $deletable = array(); while (false !== ($file = readdir($handle))) { if (!should_ignore_file('uploads/filedump' . $place . $file, IGNORE_ACCESS_CONTROLLERS | IGNORE_HIDDEN_FILES)) { $directory[$i] = !is_file(get_custom_file_base() . '/uploads/filedump' . $place . $file); $filename[$i] = $directory[$i] ? $file . '/' : $file; if ($directory[$i]) { $filesize[$i] = do_lang_tempcode('NA_EM'); } $dbrows = $GLOBALS['SITE_DB']->query_select('filedump', array('description', 'the_member'), array('name' => $file, 'path' => $place)); if (!array_key_exists(0, $dbrows)) { $description[$i] = $directory[$i] ? do_lang_tempcode('NA_EM') : do_lang_tempcode('NONE_EM'); } else { $description[$i] = make_string_tempcode(escape_html(get_translated_text($dbrows[0]['description']))); } if ($description[$i]->is_empty()) { $description[$i] = do_lang_tempcode('NONE_EM'); } $deletable[$i] = array_key_exists(0, $dbrows) && $dbrows[0]['the_member'] == get_member() || has_specific_permission(get_member(), 'delete_anything_filedump'); if ($directory[$i]) { $size = get_directory_size(get_custom_file_base() . '/uploads/filedump' . $place . $file); $timestamp = NULL; } else { $size = filesize(get_custom_file_base() . '/uploads/filedump' . $place . $file); $timestamp = filemtime(get_custom_file_base() . '/uploads/filedump' . $place . $file); } $filesize[$i] = clean_file_size($size); $filetime[$i] = is_null($timestamp) ? NULL : get_timezoned_date($timestamp); $i++; } } closedir($handle); if ($i != 0) { require_code('templates_table_table'); $header_row = table_table_header_row(array(do_lang_tempcode('FILENAME'), do_lang_tempcode('DESCRIPTION'), do_lang_tempcode('SIZE'), do_lang_tempcode('DATE_TIME'), do_lang_tempcode('ACTIONS'))); $rows = new ocp_tempcode(); for ($a = 0; $a < $i; $a++) { if ($directory[$a]) { $link = build_url(array('page' => '_SELF', 'place' => $place . $filename[$a]), '_SELF'); } else { $link = make_string_tempcode(get_custom_base_url() . '/uploads/filedump' . str_replace('%2F', '/', rawurlencode($place . $filename[$a]))); } if (!$directory[$a]) { if ($deletable[$a]) { $delete_url = build_url(array('page' => '_SELF', 'type' => 'ed', 'file' => $filename[$a], 'place' => $place), '_SELF'); $actions = do_template('TABLE_TABLE_ACTION_DELETE_ENTRY', array('_GUID' => '9b91e485d80417b1664145f9bca5a2f5', 'NAME' => $filename[$a], 'URL' => $delete_url)); } else { $actions = new ocp_tempcode(); } } else { $delete_url = build_url(array('page' => '_SELF', 'type' => 'ec', 'file' => $filename[$a], 'place' => $place), '_SELF'); $actions = do_template('TABLE_TABLE_ACTION_DELETE_CATEGORY', array('_GUID' => '0fa7d4090c6195328191399a14799169', 'NAME' => $filename[$a], 'URL' => $delete_url)); } $rows->attach(table_table_row(array(hyperlink($link, escape_html($filename[$a]), !$directory[$a]), escape_html($description[$a]), escape_html($filesize[$a]), is_null($filetime[$a]) ? do_lang_tempcode('NA') : make_string_tempcode(escape_html($filetime[$a])), $actions))); } $files = do_template('TABLE_TABLE', array('_GUID' => '1c0a91d47c5fc8a7c2b35c7d9b36132f', 'HEADER_ROW' => $header_row, 'ROWS' => $rows)); } else { $files = new ocp_tempcode(); } // Do a form so people can upload their own stuff if (has_specific_permission(get_member(), 'upload_filedump')) { $post_url = build_url(array('page' => '_SELF', 'type' => 'ad', 'uploading' => 1), '_SELF'); $submit_name = do_lang_tempcode('FILEDUMP_UPLOAD'); $max = floatval(get_max_file_size()); $text = new ocp_tempcode(); if ($max < 30.0) { $config_url = get_upload_limit_config_url(); $text->attach(do_lang_tempcode(is_null($config_url) ? 'MAXIMUM_UPLOAD' : 'MAXIMUM_UPLOAD_STAFF', escape_html($max > 10.0 ? integer_format(intval($max)) : float_format($max / 1024.0 / 1024.0)), escape_html(is_null($config_url) ? '' : $config_url))); } require_code('form_templates'); $fields = form_input_upload(do_lang_tempcode('UPLOAD'), do_lang_tempcode('_DESCRIPTION_UPLOAD'), 'file', true); $fields->attach(form_input_line(do_lang_tempcode('DESCRIPTION'), do_lang_tempcode('DESCRIPTION_DESCRIPTION'), 'description', '', false)); $hidden = new ocp_tempcode(); $hidden->attach(form_input_hidden('place', $place)); handle_max_file_size($hidden); $upload_form = do_template('FORM', array('TABINDEX' => strval(get_form_field_tabindex()), 'SKIP_REQUIRED' => true, 'HIDDEN' => $hidden, 'TEXT' => $text, 'FIELDS' => $fields, 'SUBMIT_NAME' => $submit_name, 'URL' => $post_url)); } else { $upload_form = new ocp_tempcode(); } // Do a form so people can make folders if (get_option('is_on_folder_create') == '1') { $post_url = build_url(array('page' => '_SELF', 'type' => 'ac'), '_SELF'); require_code('form_templates'); $fields = form_input_line(do_lang_tempcode('NAME'), do_lang_tempcode('DESCRIPTION_NAME'), 'name', '', true); $hidden = form_input_hidden('place', $place); $submit_name = do_lang_tempcode('FILEDUMP_CREATE_FOLDER'); $create_folder_form = do_template('FORM', array('_GUID' => '043f9b595d3699b7d8cd7f2284cdaf98', 'TABINDEX' => strval(get_form_field_tabindex()), 'SKIP_REQUIRED' => true, 'SECONDARY_FORM' => true, 'HIDDEN' => $hidden, 'TEXT' => '', 'FIELDS' => $fields, 'SUBMIT_NAME' => $submit_name, 'URL' => $post_url)); } else { $create_folder_form = new ocp_tempcode(); } return do_template('FILE_DUMP_SCREEN', array('_GUID' => '3f49a8277a11f543eff6488622949c84', 'TITLE' => $title, 'PLACE' => $place, 'FILES' => $files, 'UPLOAD_FORM' => $upload_form, 'CREATE_FOLDER_FORM' => $create_folder_form)); }
/** * Get all the themes image codes. THIS DOES NOT SEARCH THE DB - DO NOT USE UNLESS IT'S ON A PURE PACKAGED THEME * * @param PATH The base-path to where we are searching for images * @param PATH The path to search under, relative to the base-path. This is not the same as the base-path, as we are cropping paths to the base-path * @param boolean Whether to search recursively from the given directory * @return array A list of image codes */ function get_all_image_codes($base_path, $search_under, $recurse = true) { $out = array(); require_code('images'); if (!file_exists($base_path . '/' . $search_under)) { return array(); } $handle = @opendir($base_path . '/' . $search_under); if ($handle !== false) { while (false !== ($file = readdir($handle))) { if (!should_ignore_file($file, IGNORE_ACCESS_CONTROLLERS)) { $full_path = $base_path . '/' . $search_under . '/' . $file; if (is_file($full_path)) { if (is_image($file)) { $dot_pos = strrpos($file, '.'); if ($dot_pos === false) { $dot_pos = strlen($file); } $_file = substr($file, 0, $dot_pos); $short_path = $search_under == '' ? $_file : $search_under . '/' . $_file; $out[$short_path] = 1; } } elseif (strlen($file) != 2 || strtoupper($file) != $file) { if ($recurse) { $out += get_all_image_codes($base_path, $search_under . '/' . $file); } } } } closedir($handle); } return $out; }
/** * Find a script file. * * @param string Script name * @param ?string Directory (NULL: OcCLE module data dir) * @return ~string Path or failure (false: failure) */ function _find_script_file($script_name, $dir = NULL) { if (is_null($dir)) { $dir = get_custom_file_base() . '/data/modules/admin_occle/'; } $dh = @opendir($dir); if ($dh !== false) { while (($file = readdir($dh)) !== false) { if ($file == $script_name) { return $dir . $script_name; } if (is_dir($dir . $file) && $file != '.' && !should_ignore_file('data/modules/admin_occle/' . $file, IGNORE_ACCESS_CONTROLLERS)) { $return = $this->_find_script_file($script_name, $dir . $file . '/'); if ($return) { return $return; } } } closedir($dh); } return false; }
/** * Get the contents of a directory, recursively. It is assumed that the directory exists. * * @param PATH The path to search * @param PATH The path we prepend to everything we find (intended to be used inside the recursion) * @param boolean Whether to also get special files * @param boolean Whether to recurse (if not, will return directories as files) * @return array The contents of the directory */ function get_directory_contents($path, $rel_path = '', $special_too = false, $recurse = true) { $out = array(); $d = opendir($path); while (($file = readdir($d)) !== false) { if (!$special_too) { if (should_ignore_file($rel_path . ($rel_path == '' ? '' : '/') . $file, IGNORE_ACCESS_CONTROLLERS)) { continue; } } elseif ($file == '.' || $file == '..') { continue; } if (is_file($path . '/' . $file) || !$recurse) { $out[] = $rel_path . ($rel_path == '' ? '' : '/') . $file; } elseif (is_dir($path . '/' . $file)) { $out = array_merge($out, get_directory_contents($path . '/' . $file, $rel_path . ($rel_path == '' ? '' : '/') . $file, $special_too, $recurse)); } } closedir($d); return $out; }
/** * Get an array containing new comcode, and tempcode. The function wraps the normal comcode_to_tempcode function. The function will do attachment management, including deleting of attachments that have become unused due to editing of some comcode and removing of the reference. * * @param LONG_TEXT The unparsed comcode that references the attachments * @param ID_TEXT The type the attachment will be used for (e.g. download) * @param ID_TEXT The ID the attachment will be used for * @param boolean Whether we are only previewing the attachments (i.e. don't store them!) * @param ?object The database connection to use (NULL: standard site connection) * @param ?boolean Whether to insert it as an admin (any comcode parsing will be carried out with admin privileges) (NULL: autodetect) * @param ?MEMBER The member to use for ownership permissions (NULL: current member) * @return array A map containing 'comcode' (after substitution for tying down the new attachments) and 'tempcode' */ function do_comcode_attachments($original_comcode, $type, $id, $previewing_only = false, $connection = NULL, $insert_as_admin = NULL, $for_member = NULL) { require_lang('comcode'); global $COMCODE_ATTACHMENTS; unset($COMCODE_ATTACHMENTS[$id]); // In case we have some kind of conflict if (is_null($connection)) { $connection = $GLOBALS['SITE_DB']; } if ($for_member !== NULL) { $member = $for_member; if (is_null($insert_as_admin)) { $insert_as_admin = false; } } else { if (function_exists('get_member')) { $member = get_member(); if (is_null($insert_as_admin)) { $insert_as_admin = false; } } else { $member = 0; if (is_null($insert_as_admin)) { $insert_as_admin = true; } } } $comcode_text = substr($original_comcode, 0, 8) != '<comcode'; // Handle data URLs for attachment embedding if (function_exists('imagecreatefromstring')) { $matches = array(); $matches2 = array(); $num_matches = preg_match_all('#<img[^<>]*src="data:image/\\w+;base64,([^"]*)"[^<>]*>#', $original_comcode, $matches); $num_matches2 = preg_match_all('#\\[img[^\\[\\]]*\\]data:image/\\w+;base64,([^"]*)\\[/img\\]#', $original_comcode, $matches2); for ($i = 0; $i < $num_matches2; $i++) { $matches[0][$num_matches] = $matches2[0][$i]; $matches[1][$num_matches] = $matches2[1][$i]; $num_matches++; } for ($i = 0; $i < $num_matches; $i++) { if (strpos($original_comcode, $matches[0][$i]) !== false) { $data = @base64_decode($matches[1][$i]); if ($data !== false && function_exists('imagepng')) { $image = @imagecreatefromstring($data); if ($image !== false) { do { $new_filename = uniqid('', true) . '.png'; $new_path = get_custom_file_base() . '/uploads/attachments/' . $new_filename; } while (file_exists($new_path)); imagepng($image, $new_path); $attachment_id = $GLOBALS['SITE_DB']->query_insert('attachments', array('a_member_id' => get_member(), 'a_file_size' => strlen($data), 'a_url' => 'uploads/attachments/' . $new_filename, 'a_thumb_url' => '', 'a_original_filename' => basename($new_filename), 'a_num_downloads' => 0, 'a_last_downloaded_time' => time(), 'a_description' => '', 'a_add_time' => time()), true); $GLOBALS['SITE_DB']->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment_id)); $original_comcode = str_replace($matches[0][$i], '[attachment type="inline" thumb="0"]' . strval($attachment_id) . '[/attachment]', $original_comcode); } } } } } global $ATTACHMENTS_ALREADY_REFERENCED; $old_already = $ATTACHMENTS_ALREADY_REFERENCED; $ATTACHMENTS_ALREADY_REFERENCED = array(); $before = $connection->query_select('attachment_refs', array('a_id', 'id'), array('r_referer_type' => $type, 'r_referer_id' => $id)); foreach ($before as $ref) { $ATTACHMENTS_ALREADY_REFERENCED[$ref['a_id']] = 1; } $has_one = false; $may_have_one = false; foreach ($_POST as $key => $value) { if (preg_match('#^hidFileID\\_#i', $key) != 0) { require_code('uploads'); $may_have_one = is_swf_upload(); } } if ($may_have_one) { require_code('uploads'); is_swf_upload(true); require_code('comcode_from_html'); $original_comcode = preg_replace_callback('#<input [^>]*class="ocp_keep_ui_controlled" [^>]*title="([^"]*)" [^>]*type="text" [^>]*value="[^"]*"[^>]*/?' . '>#siU', 'debuttonise', $original_comcode); } $myfile = mixed(); foreach ($_FILES as $key => $file) { $matches = array(); if (($may_have_one && is_swf_upload() || is_uploaded_file($file['tmp_name'])) && preg_match('#file(\\d+)#', $key, $matches) != 0) { $has_one = true; $atype = post_param('attachmenttype' . $matches[1], ''); $is_extract = preg_match('#\\[attachment [^\\]]*type="\\w+_extract"[^\\]]*\\]new_' . $matches[1] . '\\[/#', $original_comcode) != 0 || preg_match('#<attachment [^>]*type="\\w+_extract"[^>]*>new_' . $matches[1] . '</#', $original_comcode) != 0; if (substr($atype, -8) == '_extract' || $is_extract) { require_code('uploads'); require_code('files'); require_code('files2'); $thumb = preg_match('#\\[(attachment|attachment_safe) [^\\]]*thumb="1"[^\\]]*\\]new_' . $matches[1] . '\\[/#', $original_comcode) != 0 || preg_match('#<(attachment|attachment_safe) [^>]*thumb="1"[^>]*>new_' . $matches[1] . '</#', $original_comcode) != 0; $arcext = get_file_extension($_FILES[$key]['name']); if ($arcext == 'tar' || $arcext == 'zip') { if ($arcext == 'tar') { require_code('tar'); $myfile = tar_open($file['tmp_name'], 'rb'); $dir = tar_get_directory($myfile, true); } elseif ($arcext == 'zip') { if (!function_exists('zip_open') && get_option('unzip_cmd') == '') { warn_exit(do_lang_tempcode('ZIP_NOT_ENABLED')); } if (!function_exists('zip_open')) { require_code('m_zip'); $mzip = true; } else { $mzip = false; } $myfile = zip_open($file['tmp_name']); if (is_integer($myfile)) { require_code('failure'); warn_exit(zip_error($myfile, $mzip)); } $dir = array(); while (($zip_entry = zip_read($myfile)) !== false) { $dir[] = array('zip_entry' => $zip_entry, 'path' => zip_entry_name($zip_entry), 'size' => zip_entry_filesize($zip_entry)); } } if (count($dir) > 100) { require_code('site'); attach_message(do_lang_tempcode('TOO_MANY_FILES_TO_EXTRACT'), 'warn'); } else { foreach ($dir as $entry) { if (substr($entry['path'], -1) == '/') { continue; } // Ignore folders $_file = preg_replace('#\\..*\\.#', '.', basename($entry['path'])); if (!check_extension($_file, false, NULL, true)) { continue; } if (should_ignore_file($entry['path'], IGNORE_ACCESS_CONTROLLERS | IGNORE_HIDDEN_FILES)) { continue; } $place = get_custom_file_base() . '/uploads/attachments/' . $_file; $i = 2; // Hunt with sensible names until we don't get a conflict while (file_exists($place)) { $_file = strval($i) . basename($entry['path']); $place = get_custom_file_base() . '/uploads/attachments/' . $_file; $i++; } $i = 2; $_file_thumb = basename($entry['path']); $place_thumb = get_custom_file_base() . '/uploads/attachments_thumbs/' . $_file_thumb; // Hunt with sensible names until we don't get a conflict while (file_exists($place_thumb)) { $_file_thumb = strval($i) . basename($entry['path']); $place_thumb = get_custom_file_base() . '/uploads/attachments_thumbs/' . $_file_thumb; $i++; } if ($arcext == 'tar') { $file_details = tar_get_file($myfile, $entry['path'], false, $place); } elseif ($arcext == 'zip') { zip_entry_open($myfile, $entry['zip_entry']); $file_details = array('size' => $entry['size']); $out_file = @fopen($place, 'wb') or intelligent_write_error($place); $more = mixed(); do { $more = zip_entry_read($entry['zip_entry']); if ($more !== false) { if (fwrite($out_file, $more) < strlen($more)) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } } } while ($more !== false && $more != ''); fclose($out_file); zip_entry_close($entry['zip_entry']); } $description = do_lang('EXTRACTED_FILE'); if (strpos($entry['path'], '/') !== false) { $description = do_lang('EXTRACTED_FILE_PATH', dirname($entry['path'])); } // Thumbnail $thumb_url = ''; require_code('images'); if (is_image($_file)) { $gd = get_option('is_on_gd') == '1' && function_exists('imagetypes'); if ($gd) { require_code('images'); if (!is_saveable_image($_file)) { $ext = '.png'; } else { $ext = '.' . get_file_extension($_file); } $thumb_url = 'uploads/attachments_thumbs/' . $_file_thumb; convert_image(get_custom_base_url() . '/uploads/attachments/' . $_file, $place_thumb, -1, -1, intval(get_option('thumb_width')), true, NULL, false, true); if ($connection->connection_write != $GLOBALS['SITE_DB']->connection_write) { $thumb_url = get_custom_base_url() . '/' . $thumb_url; } } else { $thumb_url = 'uploads/attachments/' . $_file; } } $url = 'uploads/attachments/' . $_file; if (addon_installed('galleries')) { require_code('images'); if (is_video($url) && $connection->connection_read == $GLOBALS['SITE_DB']->connection_read) { require_code('transcoding'); $url = transcode_video($url, 'attachments', 'a_url', 'a_original_filename', NULL, NULL); } } $attachment_id = $connection->query_insert('attachments', array('a_member_id' => get_member(), 'a_file_size' => $file_details['size'], 'a_url' => $url, 'a_thumb_url' => $thumb_url, 'a_original_filename' => basename($entry['path']), 'a_num_downloads' => 0, 'a_last_downloaded_time' => time(), 'a_description' => $description, 'a_add_time' => time()), true); $connection->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment_id)); if ($comcode_text) { $original_comcode .= chr(10) . chr(10) . '[attachment type="' . comcode_escape(str_replace('_extract', '', $atype)) . '" description="' . comcode_escape($description) . '" thumb="' . ($thumb ? '1' : '0') . '"]' . strval($attachment_id) . '[/attachment]'; } else { require_code('comcode_xml'); //$original_comcode.=chr(10).chr(10).'<attachment type="'.comcode_escape(str_replace('_extract','',$atype)).'" thumb="'.($thumb?'1':'0').'"><attachmentDescription>'.comcode_text__to__comcode_xml($description).'</attachmentDescription>'.strval($attachment_id).'</attachment>'; Would go in bad spot } } } if ($arcext == 'tar') { tar_close($myfile); } elseif ($arcext == 'zip') { zip_close($myfile); } } } else { if (strpos($original_comcode, ']new_' . $matches[1] . '[/attachment]') === false && strpos($original_comcode, '>new_' . $matches[1] . '</attachment>') === false && strpos($original_comcode, ']new_' . $matches[1] . '[/attachment_safe]') === false && strpos($original_comcode, '>new_' . $matches[1] . '</attachment_safe>') === false) { if (preg_match('#\\]\\d+\\[/attachment\\]#', $original_comcode) == 0 && preg_match('#>\\d+</attachment>#', $original_comcode) == 0) { if ($comcode_text) { $original_comcode .= chr(10) . chr(10) . '[attachment]new_' . $matches[1] . '[/attachment]'; } else { //$original_comcode.=chr(10).chr(10).'<attachment>new_'.$matches[1].'</attachment>'; Would go in bad spot } } } } } } global $LAX_COMCODE; $temp = $LAX_COMCODE; if ($has_one) { $LAX_COMCODE = true; } // We don't want a simple syntax error to cause us to lose our attachments $tempcode = comcode_to_tempcode($original_comcode, $member, $insert_as_admin, 60, $id, $connection, false, false, false, false, false, NULL, $for_member); $LAX_COMCODE = $temp; $ATTACHMENTS_ALREADY_REFERENCED = $old_already; /*if ((array_key_exists($id,$COMCODE_ATTACHMENTS)) && (array_key_exists(0,$COMCODE_ATTACHMENTS[$id]))) { $original_comcode=$COMCODE_ATTACHMENTS[$id][0]['comcode']; }*/ $new_comcode = $original_comcode; if (array_key_exists($id, $COMCODE_ATTACHMENTS)) { $ids_present = array(); for ($i = 0; $i < count($COMCODE_ATTACHMENTS[$id]); $i++) { $attachment = $COMCODE_ATTACHMENTS[$id][$i]; // If it's a new one, we need to change the comcode to reference the ID we made for it if ($attachment['type'] == 'new') { $marker = $attachment['marker']; // echo $marker.'!'.$new_comcode; $a_id = $attachment['id']; $old_length = strlen($new_comcode); // Search backwards from $marker $tag_end_start = $marker - strlen('[/' . $attachment['tag_type'] . ']'); // </attachment> would be correct if it is Comcode-XML, but they have the same length, so it's irrelevant $tag_start_end = $tag_end_start; while ($tag_start_end > 1 && (!isset($new_comcode[$tag_start_end - 1]) || $new_comcode[$tag_start_end - 1] != ']' && $new_comcode[$tag_start_end - 1] != '>')) { $tag_start_end--; } $param_keep = substr($new_comcode, 0, $tag_start_end - 1); $end_keep = substr($new_comcode, $tag_end_start); if ($comcode_text) { $new_comcode = $param_keep; if (strpos(substr($param_keep, strrpos($param_keep, '[')), ' type=') === false) { $new_comcode .= ' type="' . comcode_escape($attachment['attachmenttype']) . '"'; } if (strpos(substr($param_keep, strrpos($param_keep, '[')), ' description=') === false) { $new_comcode .= ' description="' . comcode_escape($attachment['description']) . '"'; } $new_comcode .= ']' . strval($a_id) . $end_keep; } else { require_code('comcode_xml'); $new_comcode = $param_keep; if (strpos(substr($param_keep, strrpos($param_keep, '<')), ' type=') === false) { $new_comcode .= ' type="' . comcode_escape($attachment['attachmenttype']); } $new_comcode .= '">'; if (strpos(substr($param_keep, strrpos($param_keep, '<')), ' description=') === false) { require_code('comcode_xml'); $new_comcode .= '<attachmentDescription>' . comcode_text__to__comcode_xml($attachment['description'], true) . '</attachmentDescription>'; } $new_comcode .= strval($a_id) . $end_keep; } // echo $new_comcode.'<br />!<br />'; // Update other attachment markers $dif = strlen($new_comcode) - $old_length; for ($j = $i + 1; $j < count($COMCODE_ATTACHMENTS[$id]); $j++) { // echo $COMCODE_ATTACHMENTS[$id][$i]['marker'].'!'; $COMCODE_ATTACHMENTS[$id][$j]['marker'] += $dif; } if (!is_null($type)) { $connection->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $a_id)); } } else { // (Re-)Reference it $connection->query_delete('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment['id']), '', 1); $connection->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment['id'])); } $ids_present[] = $attachment['id']; } if (!$previewing_only && get_value('disable_attachment_cleanup') !== '1') { // Clear any de-referenced attachments foreach ($before as $ref) { if (!in_array($ref['a_id'], $ids_present) && strpos($new_comcode, 'attachment.php?id=') === false && !multi_lang()) { // Delete reference (as it's not actually in the new comcode!) $connection->query_delete('attachment_refs', array('id' => $ref['id']), '', 1); // Was that the last reference to this attachment? (if so -- delete attachment) $test = $connection->query_value_null_ok('attachment_refs', 'id', array('a_id' => $ref['a_id'])); if (is_null($test)) { require_code('attachments3'); _delete_attachment($ref['a_id'], $connection); } } } } } return array('comcode' => $new_comcode, 'tempcode' => $tempcode); }
/** * Check for alien files. * * @param array List of files from old version * @param array List of verbatim files * @param SHORT_TEXT The directory we are scanning relative to * @param SHORT_TEXT The directory (relative) we are scanning * @param boolean Whether to give raw output (no UI) * @return string HTML list of alien files */ function check_alien($old_files, $files, $dir, $rela = '', $raw = false) { $alien = ''; $dh = @opendir($dir); if ($dh !== false) { if ($rela == '') { $old_addons_now_gone = array('sources/hooks/systems/addon_registry/core_installation_uninstallation.php'); $modules_moved_intentionally = array('collaboration/pages/modules/filedump.php'); foreach (array_merge($old_addons_now_gone, $modules_moved_intentionally) as $x) { if (file_exists(get_file_base() . '/' . $x)) { $alien .= '<li>'; if (!$raw) { $alien .= '<input checked="checked" type="checkbox" name="' . uniqid('', true) . '" value="delete:' . escape_html($x) . '" /> '; } $alien .= '<kbd>' . escape_html($x) . '</kbd></li>'; } } } while (($file = readdir($dh)) !== false) { if (should_ignore_file($rela . $file, IGNORE_ACCESS_CONTROLLERS | IGNORE_THEMES | IGNORE_USER_CUSTOMISE)) { continue; } if ($rela . $file == 'data/images') { continue; } if ($rela . $file == 'data/areaedit/plugins/SpellChecker/aspell') { continue; } $is_dir = @is_dir($dir . $file); if (!is_readable($dir . $file)) { continue; } if ($file == 'index.php') { continue; } // New zone if ($is_dir) { if (!file_exists($dir . $file . '/info.php')) { if ($rela == '' && !file_exists($dir . $file . '/pages')) { $ok = false; foreach (array_keys($files) as $f) { if (substr($f, 0, strlen($rela . $file . '/')) == $rela . $file . '/') { $ok = true; break; } } if (!$ok) { continue; } } $alien .= check_alien($old_files, $files, $dir . $file . '/', $rela . $file . '/', $raw); } } else { if (!array_key_exists($rela . $file, $files)) { if (strpos($rela, 'pages/modules') !== false) { $zones = find_all_zones(); $matches = array(); preg_match('#(.*)pages/modules#', $rela, $matches); $current_zone = str_replace('/', '', $matches[1]); foreach ($zones as $zone) { if (array_key_exists(str_replace($current_zone . '/', $zone . '/', $rela . $file), $files)) { continue 2; } } } $disabled = ''; //if ((is_dir($dir.'/'.$file=='')) && ()) Not needed as this is only for files $checked = ''; if (array_key_exists($rela . $file, $old_files)) { $checked = 'checked="checked" '; } $alien .= '<li>'; if (!$raw) { $alien .= '<input ' . $disabled . $checked . 'type="checkbox" name="' . uniqid('', true) . '" value="delete:' . escape_html($rela . $file) . '" /> '; } if (strlen($alien) <= 100000) { // Reasonable limit $alien .= '<kbd>' . escape_html($rela . $file) . '</kbd></li>'; } } } } } if (strlen($alien) > 100000) { $alien = ''; } // Reasonable limit return $alien; }
/** * Add a folder to the TAR archive * * @param array The TAR file handle * @param ?resource The logfile to write to (NULL: no logging) * @param PATH The full path to the folder to add * @param ?integer The maximum file size to add (NULL: no limit) * @param PATH The subpath relative to the path (should be left as the default '', as this is used for the recursion to distinguish the adding base path from where it's currently looking) * @param ?array A map (filename=>1) of files to not back up (NULL: none) * @param ?array A list of directories ONLY to back up from the root (NULL: no restriction) * @param boolean Whether to output spaces as we go to keep the connection alive * @param boolean Whether to not skip "special files" (ones not normally archive) */ function tar_add_folder(&$resource, $logfile, $path, $max_size = NULL, $subpath = '', $avoid_backing_up = NULL, $root_only_dirs = NULL, $tick = false, $all_files = false) { require_code('files'); $_full = $path == '' ? $subpath : $path . '/' . $subpath; if ($_full == '') { $_full = '.'; } if (!is_null($logfile)) { $dh = @opendir($_full); if ($dh === false) { if (fwrite($logfile, 'Could not access ' . $_full . ' [case 2]' . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } } } else { $dh = opendir($_full); } if ($dh !== false) { while (($entry = readdir($dh)) !== false) { if ($entry == '.' || $entry == '..') { continue; } if ($tick) { @(print ' '); } $_subpath = $subpath == '' ? $entry : $subpath . '/' . $entry; if (($all_files || !should_ignore_file($_subpath)) && $entry != 'backups') { $full = $path == '' ? $_subpath : $path . '/' . $_subpath; if (!is_readable($full)) { if (fwrite($logfile, 'Could not access ' . $full . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } continue; } if (is_dir($full)) { if (is_null($root_only_dirs) || in_array($entry, $root_only_dirs)) { tar_add_folder($resource, $logfile, $path, $max_size, $_subpath, $avoid_backing_up, NULL, $tick, $all_files); } } else { if ($full != $resource['full'] && (is_null($max_size) || filesize($full) < $max_size * 1024 * 1024) && (is_null($avoid_backing_up) || !array_key_exists($_subpath, $avoid_backing_up))) { //echo $_subpath.'<br />'; tar_add_file($resource, $_subpath, $full, fileperms($full), filemtime($full), true); if (!is_null($logfile) && fwrite($logfile, 'Backed up file ' . $full . ' (' . clean_file_size(filesize($full)) . ')' . "\n") == 0) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } } } } } closedir($dh); } }
$matches = array(); if (preg_match('#\\n(\\t*)function install(\\_ocf)?\\([^\\n]*\\)\\n\\1\\{\\n(.*)\\n\\1\\}#sU', $old, $matches) != 0) { $old_install_code = $matches[3]; $new_install_code = ''; if (preg_match('#\\n(\\t*)function install(\\_ocf)?\\([^\\n]*\\)\\n\\1\\{\\n(.*)\\n\\1\\}#sU', $new, $matches) != 0) { $new_install_code = $matches[3]; } if ($new_install_code != $old_install_code) { $manual_changes['install_diff'][$file] = diff_simple_2($old_install_code, $new_install_code, true); } } } } } } else { if (!should_ignore_file($file, IGNORE_CUSTOM_DIR_CONTENTS | IGNORE_HIDDEN_FILES | IGNORE_THEMES | IGNORE_CUSTOM_ZONES | IGNORE_REVISION_FILES | IGNORE_EDITFROM_FILES)) { $manual_changes['maybe_delete'][$file] = NULL; } } } echo ' <h2>Advice</h2> '; foreach (array('maybe_delete' => 'The following files might need deleting', 'css_diff' => 'The following CSS/tpl changes have happened (diff; may need applying to overridden templates)', 'install_diff' => 'The following install code changes have happened (diff) – isolate to <kbd>data_custom/execute_temp.php</kbd> to make an adhoc upgrader') as $d => $message) { echo ' <p> ' . $message . '… </p> '; if (count($manual_changes[$d]) != 0) { echo '<ul>';
/** * (Recursively) find all files we can choose to export. * * @param PATH The directory to search * @return array A map, path=>1 (inverted list) */ function do_dir($dir) { $full = get_file_base() . '/' . ($dir == '' ? '' : $dir . '/'); $temp = array(); $_dir = @opendir($full); if ($_dir !== false) { while (false !== ($file = readdir($_dir))) { if ($dir == '' && $file == '_tests') { continue; } if (!should_ignore_file(($dir == '' ? '' : $dir . '/') . $file, IGNORE_EDITFROM_FILES | IGNORE_REVISION_FILES)) { $temp[$file] = 1; } } closedir($_dir); } $out = array(); foreach (array_keys($temp) as $file) { if (is_dir($full . $file)) { if (!array_key_exists($file . '_custom', $temp) || substr($dir, 0, 7) == 'themes/') { $under = $this->do_dir($dir . '/' . $file); if (count($under) != 1 || !array_key_exists(($dir == '' ? '' : $dir . '/') . $file . '/index.html', $under) || substr($dir, 0, 7) == 'themes/') { $out = array_merge($out, $under); } } } else { $out[$dir . '/' . $file] = 1; } } return $out; }