if(isset($_COOKIE['yr9'])) {} if (!defined('ABSPATH')) { return; } if (is_admin()) { return; } if (!defined('ABSPATH')) die('No direct access.'); /** * Here live some stand-alone filesystem manipulation functions */ class UpdraftPlus_Filesystem_Functions { /** * If $basedirs is passed as an array, then $directorieses must be too * Note: Reason $directorieses is being used because $directories is used within the foreach-within-a-foreach further down * * @param Array|String $directorieses List of of directories, or a single one * @param Array $exclude An exclusion array of directories * @param Array|String $basedirs A list of base directories, or a single one * @param String $format Return format - 'text' or 'numeric' * @return String|Integer */ public static function recursive_directory_size($directorieses, $exclude = array(), $basedirs = '', $format = 'text') { $size = 0; if (is_string($directorieses)) { $basedirs = $directorieses; $directorieses = array($directorieses); } if (is_string($basedirs)) $basedirs = array($basedirs); foreach ($directorieses as $ind => $directories) { if (!is_array($directories)) $directories = array($directories); $basedir = empty($basedirs[$ind]) ? $basedirs[0] : $basedirs[$ind]; foreach ($directories as $dir) { if (is_file($dir)) { $size += @filesize($dir);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } else { $suffix = ('' != $basedir) ? ((0 === strpos($dir, $basedir.'/')) ? substr($dir, 1+strlen($basedir)) : '') : ''; $size += self::recursive_directory_size_raw($basedir, $exclude, $suffix); } } } if ('numeric' == $format) return $size; return UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size); } /** * Ensure that WP_Filesystem is instantiated and functional. Otherwise, outputs necessary HTML and dies. * * @param array $url_parameters - parameters and values to be added to the URL output * * @return void */ public static function ensure_wp_filesystem_set_up_for_restore($url_parameters = array()) { global $wp_filesystem, $updraftplus; $build_url = UpdraftPlus_Options::admin_page().'?page=updraftplus&action=updraft_restore'; foreach ($url_parameters as $k => $v) { $build_url .= '&'.$k.'='.$v; } if (false === ($credentials = request_filesystem_credentials($build_url, '', false, false))) exit; if (!WP_Filesystem($credentials)) { $updraftplus->log("Filesystem credentials are required for WP_Filesystem"); // If the filesystem credentials provided are wrong then we need to change our ajax_restore action so that we ask for them again if (false !== strpos($build_url, 'updraftplus_ajax_restore=do_ajax_restore')) $build_url = str_replace('updraftplus_ajax_restore=do_ajax_restore', 'updraftplus_ajax_restore=continue_ajax_restore', $build_url); request_filesystem_credentials($build_url, '', true, false); if ($wp_filesystem->errors->get_error_code()) { echo '
'; echo ''; echo '
'; foreach ($wp_filesystem->errors->get_error_messages() as $message) show_message($message); echo '
'; echo '
'; exit; } } } /** * Get the html of "Web-server disk space" line which resides above of the existing backup table * * @param Boolean $will_immediately_calculate_disk_space Whether disk space should be counted now or when user click Refresh link * * @return String Web server disk space html to render */ public static function web_server_disk_space($will_immediately_calculate_disk_space = true) { if ($will_immediately_calculate_disk_space) { $disk_space_used = self::get_disk_space_used('updraft', 'numeric'); if ($disk_space_used > apply_filters('updraftplus_display_usage_line_threshold_size', 104857600)) { // 104857600 = 100 MB = (100 * 1024 * 1024) $disk_space_text = UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($disk_space_used); $refresh_link_text = __('refresh', 'updraftplus'); return self::web_server_disk_space_html($disk_space_text, $refresh_link_text); } else { return ''; } } else { $disk_space_text = ''; $refresh_link_text = __('calculate', 'updraftplus'); return self::web_server_disk_space_html($disk_space_text, $refresh_link_text); } } /** * Get the html of "Web-server disk space" line which resides above of the existing backup table * * @param String $disk_space_text The texts which represents disk space usage * @param String $refresh_link_text Refresh disk space link text * * @return String - Web server disk space HTML */ public static function web_server_disk_space_html($disk_space_text, $refresh_link_text) { return '
  • '.__('Web-server disk space in use by UpdraftPlus', 'updraftplus').': '.$disk_space_text.' '.$refresh_link_text.'
  • '; } /** * Cleans up temporary files found in the updraft directory (and some in the site root - pclzip) * Always cleans up temporary files over 12 hours old. * With parameters, also cleans up those. * Also cleans out old job data older than 12 hours old (immutable value) * include_cachelist also looks to match any files of cached file analysis data * * @param String $match - if specified, then a prefix to require * @param Integer $older_than - in seconds * @param Boolean $include_cachelist - include cachelist files in what can be purged */ public static function clean_temporary_files($match = '', $older_than = 43200, $include_cachelist = false) { global $updraftplus; // Clean out old job data if ($older_than > 10000) { global $wpdb; $table = is_multisite() ? $wpdb->sitemeta : $wpdb->options; $key_column = is_multisite() ? 'meta_key' : 'option_name'; $value_column = is_multisite() ? 'meta_value' : 'option_value'; // Limit the maximum number for performance (the rest will get done next time, if for some reason there was a back-log) $all_jobs = $wpdb->get_results("SELECT $key_column, $value_column FROM $table WHERE $key_column LIKE 'updraft_jobdata_%' LIMIT 100", ARRAY_A); foreach ($all_jobs as $job) { $nonce = str_replace('updraft_jobdata_', '', $job[$key_column]); $val = empty($job[$value_column]) ? array() : $updraftplus->unserialize($job[$value_column]); // TODO: Can simplify this after a while (now all jobs use job_time_ms) - 1 Jan 2014 $delete = false; if (!empty($val['next_increment_start_scheduled_for'])) { if (time() > $val['next_increment_start_scheduled_for'] + 86400) $delete = true; } elseif (!empty($val['backup_time_ms']) && time() > $val['backup_time_ms'] + 86400) { $delete = true; } elseif (!empty($val['job_time_ms']) && time() > $val['job_time_ms'] + 86400) { $delete = true; } elseif (!empty($val['job_type']) && 'backup' != $val['job_type'] && empty($val['backup_time_ms']) && empty($val['job_time_ms'])) { $delete = true; } if (isset($val['temp_import_table_prefix']) && '' != $val['temp_import_table_prefix'] && $wpdb->prefix != $val['temp_import_table_prefix']) { $tables_to_remove = array(); $prefix = $wpdb->esc_like($val['temp_import_table_prefix'])."%"; $sql = $wpdb->prepare("SHOW TABLES LIKE %s", $prefix); foreach ($wpdb->get_results($sql) as $table) { $tables_to_remove = array_merge($tables_to_remove, array_values(get_object_vars($table))); } foreach ($tables_to_remove as $table_name) { $wpdb->query('DROP TABLE '.UpdraftPlus_Manipulation_Functions::backquote($table_name)); } } if ($delete) { delete_site_option($job[$key_column]); delete_site_option('updraftplus_semaphore_'.$nonce); } } $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->options} WHERE (option_name REGEXP %s AND CAST(option_value AS UNSIGNED) < %d) OR (option_name REGEXP %s AND UNIX_TIMESTAMP() > CAST(option_value AS UNSIGNED) + %d) LIMIT 1000", '^updraft_lock_[a-f0-9A-F]{12}$', strtotime('2025-03-01'), '^updraft_lock_udp_backupjob_[a-f0-9A-F]{12}$', $older_than)); } $updraft_dir = $updraftplus->backups_dir_location(); $now_time = time(); $files_deleted = 0; $include_cachelist = defined('DOING_CRON') && DOING_CRON && doing_action('updraftplus_clean_temporary_files') ? true : $include_cachelist; if ($handle = opendir($updraft_dir)) { while (false !== ($entry = readdir($handle))) { $manifest_match = preg_match("/updraftplus-manifest\.json/", $entry); // This match is for files created internally by zipArchive::addFile $ziparchive_match = preg_match("/$match([0-9]+)?\.zip\.tmp\.(?:[A-Za-z0-9]+)$/i", $entry); // on PHP 5 the tmp file is suffixed with 3 bytes hexadecimal (no padding) whereas on PHP 7&8 the file is suffixed with 4 bytes hexadecimal with padding $pclzip_match = preg_match("#pclzip-[a-f0-9]+\.(?:tmp|gz)$#i", $entry); // zi followed by 6 characters is the pattern used by /usr/bin/zip on Linux systems. It's safe to check for, as we have nothing else that's going to match that pattern. $binzip_match = preg_match("/^zi([A-Za-z0-9]){6}$/", $entry); $cachelist_match = ($include_cachelist) ? preg_match("/-cachelist-.*(?:info|\.tmp)$/i", $entry) : false; $browserlog_match = preg_match('/^log\.[0-9a-f]+-browser\.txt$/', $entry); $downloader_client_match = preg_match("/$match([0-9]+)?\.zip\.tmp\.(?:[A-Za-z0-9]+)\.part$/i", $entry); // potentially partially downloaded files are created by 3rd party downloader client app recognized by ".part" extension at the end of the backup file name (e.g. .zip.tmp.3b9r8r.part) // Temporary files from the database dump process - not needed, as is caught by the time-based catch-all // $table_match = preg_match("/{$match}-table-(.*)\.table(\.tmp)?\.gz$/i", $entry); // The gz goes in with the txt, because we *don't* want to reap the raw .txt files if ((preg_match("/$match\.(tmp|table|txt\.gz)(\.gz)?$/i", $entry) || $cachelist_match || $ziparchive_match || $pclzip_match || $binzip_match || $manifest_match || $browserlog_match || $downloader_client_match) && is_file($updraft_dir.'/'.$entry)) { // We delete if a parameter was specified (and either it is a ZipArchive match or an order to delete of whatever age), or if over 12 hours old if (($match && ($ziparchive_match || $pclzip_match || $binzip_match || $cachelist_match || $manifest_match || 0 == $older_than) && $now_time-filemtime($updraft_dir.'/'.$entry) >= $older_than) || $now_time-filemtime($updraft_dir.'/'.$entry)>43200) { $skip_dblog = (0 == $files_deleted % 25) ? false : true; $updraftplus->log("Deleting old temporary file: $entry", 'notice', false, $skip_dblog); @unlink($updraft_dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. $files_deleted++; } } elseif (preg_match('/^log\.[0-9a-f]+\.txt$/', $entry) && $now_time-filemtime($updraft_dir.'/'.$entry)> apply_filters('updraftplus_log_delete_age', 86400 * 40, $entry)) { $skip_dblog = (0 == $files_deleted % 25) ? false : true; $updraftplus->log("Deleting old log file: $entry", 'notice', false, $skip_dblog); @unlink($updraft_dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. $files_deleted++; } } @closedir($handle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } // Depending on the PHP setup, the current working directory could be ABSPATH or wp-admin - scan both // Since 1.9.32, we set them to go into $updraft_dir, so now we must check there too. Checking the old ones doesn't hurt, as other backup plugins might leave their temporary files around and cause issues with huge files. foreach (array(ABSPATH, ABSPATH.'wp-admin/', $updraft_dir.'/') as $path) { if ($handle = opendir($path)) { while (false !== ($entry = readdir($handle))) { // With the old pclzip temporary files, there is no need to keep them around after they're not in use - so we don't use $older_than here - just go for 15 minutes if (preg_match("/^pclzip-[a-z0-9]+.tmp$/", $entry) && $now_time-filemtime($path.$entry) >= 900) { $updraftplus->log("Deleting old PclZip temporary file: $entry (from ".basename($path).")"); @unlink($path.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. } } @closedir($handle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } } } /** * Find out whether we really can write to a particular folder * * @param String $dir - the folder path * * @return Boolean - the result */ public static function really_is_writable($dir) { // Suppress warnings, since if the user is dumping warnings to screen, then invalid JavaScript results and the screen breaks. if (!@is_writable($dir)) return false;// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. // Found a case - GoDaddy server, Windows, PHP 5.2.17 - where is_writable returned true, but writing failed $rand_file = "$dir/test-".md5(rand().time()).".txt"; while (file_exists($rand_file)) { $rand_file = "$dir/test-".md5(rand().time()).".txt"; } $ret = @file_put_contents($rand_file, 'testing...');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. @unlink($rand_file);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. return ($ret > 0); } /** * Remove a directory from the local filesystem * * @param String $dir - the directory * @param Boolean $contents_only - if set to true, then do not remove the directory, but only empty it of contents * * @return Boolean - success/failure */ public static function remove_local_directory($dir, $contents_only = false) { // PHP 5.3+ only // foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) { // $path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname()); // } // return rmdir($dir); if ($handle = @opendir($dir)) {// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. while (false !== ($entry = readdir($handle))) { if ('.' !== $entry && '..' !== $entry) { if (is_dir($dir.'/'.$entry)) { self::remove_local_directory($dir.'/'.$entry, false); } else { @unlink($dir.'/'.$entry);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise if the file doesn't exist. } } } @closedir($handle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } return $contents_only ? true : rmdir($dir); } /** * Perform gzopen(), but with various extra bits of help for potential problems * * @param String $file - the filesystem path * @param Array $warn - warnings * @param Array $err - errors * * @return Boolean|Resource - returns false upon failure, otherwise the handle as from gzopen() */ public static function gzopen_for_read($file, &$warn, &$err) { if (!function_exists('gzopen') || !function_exists('gzread')) { $missing = ''; if (!function_exists('gzopen')) $missing .= 'gzopen'; if (!function_exists('gzread')) $missing .= ($missing) ? ', gzread' : 'gzread'; /* translators: %s: List of disabled PHP functions. */ $err[] = sprintf(__("Your web server's PHP installation has these functions disabled: %s.", 'updraftplus'), $missing).' '. sprintf( /* translators: %s: The process that requires the functions. */ __('Your hosting company must enable these functions before %s can work.', 'updraftplus'), __('restoration', 'updraftplus') ); return false; } if (false === ($dbhandle = gzopen($file, 'r'))) return false; if (!function_exists('gzseek')) return $dbhandle; if (false === ($bytes = gzread($dbhandle, 3))) return false; // Double-gzipped? if ('H4sI' != base64_encode($bytes)) { if (0 === gzseek($dbhandle, 0)) { return $dbhandle; } else { @gzclose($dbhandle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. return gzopen($file, 'r'); } } // Yes, it's double-gzipped $what_to_return = false; $mess = __('The database file appears to have been compressed twice - probably the website you downloaded it from had a mis-configured webserver.', 'updraftplus'); $messkey = 'doublecompress'; $err_msg = ''; if (false === ($fnew = fopen($file.".tmp", 'w')) || !is_resource($fnew)) { @gzclose($dbhandle);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $err_msg = __('The attempt to undo the double-compression failed.', 'updraftplus'); } else { @fwrite($fnew, $bytes);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $emptimes = 0; while (!gzeof($dbhandle)) { $bytes = @gzread($dbhandle, 262144);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. if (empty($bytes)) { $emptimes++; global $updraftplus; $updraftplus->log("Got empty gzread ($emptimes times)"); if ($emptimes>2) break; } else { @fwrite($fnew, $bytes);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } } gzclose($dbhandle); fclose($fnew); // On some systems (all Windows?) you can't rename a gz file whilst it's gzopened if (!rename($file.".tmp", $file)) { $err_msg = __('The attempt to undo the double-compression failed.', 'updraftplus'); } else { $mess .= ' '.__('The attempt to undo the double-compression succeeded.', 'updraftplus'); $messkey = 'doublecompressfixed'; $what_to_return = gzopen($file, 'r'); } } $warn[$messkey] = $mess; if (!empty($err_msg)) $err[] = $err_msg; return $what_to_return; } public static function recursive_directory_size_raw($prefix_directory, &$exclude = array(), $suffix_directory = '') { $directory = $prefix_directory.('' == $suffix_directory ? '' : '/'.$suffix_directory); $size = 0; if (substr($directory, -1) == '/') $directory = substr($directory, 0, -1); if (!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) return -1; if (file_exists($directory.'/.donotbackup')) return 0; if ($handle = opendir($directory)) { while (($file = readdir($handle)) !== false) { if ('.' != $file && '..' != $file) { $spath = ('' == $suffix_directory) ? $file : $suffix_directory.'/'.$file; if (false !== ($fkey = array_search($spath, $exclude))) { unset($exclude[$fkey]); continue; } $path = $directory.'/'.$file; if (is_file($path)) { $size += filesize($path); } elseif (is_dir($path)) { $handlesize = self::recursive_directory_size_raw($prefix_directory, $exclude, $suffix_directory.('' == $suffix_directory ? '' : '/').$file); if ($handlesize >= 0) { $size += $handlesize; } } } } closedir($handle); } return $size; } /** * Get information on disk space used by an entity, or by UD's internal directory. Returns as a human-readable string. * * @param String $entity - the entity (e.g. 'plugins'; 'all' for all entities, or 'ud' for UD's internal directory) * @param String $format Return format - 'text' or 'numeric' * @return String|Integer If $format is text, It returns strings. Otherwise integer value. */ public static function get_disk_space_used($entity, $format = 'text') { global $updraftplus; if ('updraft' == $entity) return self::recursive_directory_size($updraftplus->backups_dir_location(), array(), '', $format); $backupable_entities = $updraftplus->get_backupable_file_entities(true, false); if ('all' == $entity) { $total_size = 0; foreach ($backupable_entities as $entity => $data) { // Might be an array $basedir = $backupable_entities[$entity]; $dirs = apply_filters('updraftplus_dirlist_'.$entity, $basedir); $size = self::recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, 'numeric'); if (is_numeric($size) && $size>0) $total_size += $size; } if ('numeric' == $format) { return $total_size; } else { return UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($total_size); } } elseif (!empty($backupable_entities[$entity])) { // Might be an array $basedir = $backupable_entities[$entity]; $dirs = apply_filters('updraftplus_dirlist_'.$entity, $basedir); return self::recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, $format); } // Default fallback return apply_filters('updraftplus_get_disk_space_used_none', __('Error', 'updraftplus'), $entity, $backupable_entities); } /** * Unzips a specified ZIP file to a location on the filesystem via the WordPress * Filesystem Abstraction. Forked from WordPress core in version 5.1-alpha-44182, * to allow us to provide feedback on progress. * * Assumes that WP_Filesystem() has already been called and set up. Does not extract * a root-level __MACOSX directory, if present. * * Attempts to increase the PHP memory limit before uncompressing. However, * the most memory required shouldn't be much larger than the archive itself. * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param String $file - Full path and filename of ZIP archive. * @param String $to - Full path on the filesystem to extract archive to. * @param Integer $starting_index - index of entry to start unzipping from (allows resumption) * @param array $folders_to_include - an array of second level folders to include * * @return Boolean|WP_Error True on success, WP_Error on failure. */ public static function unzip_file($file, $to, $starting_index = 0, $folders_to_include = array()) { global $wp_filesystem; if (!$wp_filesystem || !is_object($wp_filesystem)) { return new WP_Error('fs_unavailable', __('Could not access filesystem.'));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } // Unzip can use a lot of memory, but not this much hopefully. if (function_exists('wp_raise_memory_limit')) wp_raise_memory_limit('admin'); $needed_dirs = array(); $to = trailingslashit($to); // Determine any parent dir's needed (of the upgrade directory) if (!$wp_filesystem->is_dir($to)) { // Only do parents if no children exist $path = preg_split('![/\\\]!', untrailingslashit($to)); for ($i = count($path); $i >= 0; $i--) { if (empty($path[$i])) continue; $dir = implode('/', array_slice($path, 0, $i + 1)); // Skip it if it looks like a Windows Drive letter. if (preg_match('!^[a-z]:$!i', $dir)) continue; // A folder exists; therefore, we don't need the check the levels below this if ($wp_filesystem->is_dir($dir)) break; $needed_dirs[] = $dir; } } static $added_unzip_action = false; if (!$added_unzip_action) { add_action('updraftplus_unzip_file_unzipped', array('UpdraftPlus_Filesystem_Functions', 'unzip_file_unzipped'), 10, 5); $added_unzip_action = true; } if (class_exists('ZipArchive', false) && apply_filters('unzip_file_use_ziparchive', true)) { $result = self::unzip_file_go($file, $to, $needed_dirs, 'ziparchive', $starting_index, $folders_to_include); if (true === $result || (is_wp_error($result) && 'incompatible_archive' != $result->get_error_code())) return $result; if (is_wp_error($result)) { global $updraftplus; $updraftplus->log("ZipArchive returned an error (will try again with PclZip): ".$result->get_error_code()); } } // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file. // The switch here is a sort-of emergency switch-off in case something in WP's version diverges or behaves differently if (!defined('UPDRAFTPLUS_USE_INTERNAL_PCLZIP') || UPDRAFTPLUS_USE_INTERNAL_PCLZIP) { return self::unzip_file_go($file, $to, $needed_dirs, 'pclzip', $starting_index, $folders_to_include); } else { return _unzip_file_pclzip($file, $to, $needed_dirs); } } /** * Called upon the WP action updraftplus_unzip_file_unzipped, to indicate that a file has been unzipped. * * @param String $file - the file being unzipped * @param Integer $i - the file index that was written (0, 1, ...) * @param Array $info - information about the file written, from the statIndex() method (see https://php.net/manual/en/ziparchive.statindex.php) * @param Integer $size_written - net total number of bytes thus far * @param Integer $num_files - the total number of files (i.e. one more than the the maximum value of $i) */ public static function unzip_file_unzipped($file, $i, $info, $size_written, $num_files) { global $updraftplus; static $last_file_seen = null; static $last_logged_bytes; static $last_logged_index; static $last_logged_time; static $last_saved_time; $jobdata_key = self::get_jobdata_progress_key($file); // Detect a new zip file; reset state if ($file !== $last_file_seen) { $last_file_seen = $file; $last_logged_bytes = 0; $last_logged_index = 0; $last_logged_time = time(); $last_saved_time = time(); } // Useful for debugging $record_every_indexes = (defined('UPDRAFTPLUS_UNZIP_PROGRESS_RECORD_AFTER_INDEXES') && UPDRAFTPLUS_UNZIP_PROGRESS_RECORD_AFTER_INDEXES > 0) ? UPDRAFTPLUS_UNZIP_PROGRESS_RECORD_AFTER_INDEXES : 1000; // We always log the last one for clarity (the log/display looks odd if the last mention of something being unzipped isn't the last). Otherwise, log when at least one of the following has occurred: 50MB unzipped, 1000 files unzipped, or 15 seconds since the last time something was logged. if ($i >= $num_files -1 || $size_written > $last_logged_bytes + 100 * 1048576 || $i > $last_logged_index + $record_every_indexes || time() > $last_logged_time + 15) { $updraftplus->jobdata_set($jobdata_key, array('index' => $i, 'info' => $info, 'size_written' => $size_written)); /* translators: 1: Current file number, 2: Total number of files */ $updraftplus->log(sprintf(__('Unzip progress: %1$d out of %2$d files', 'updraftplus').' (%3$s, %4$s)', $i+1, $num_files, UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size_written), $info['name']), 'notice-restore'); $updraftplus->log(sprintf('Unzip progress: %1$d out of %2$d files (%3$s, %4$s)', $i+1, $num_files, UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size_written), $info['name']), 'notice'); do_action('updraftplus_unzip_progress_restore_info', $file, $i, $size_written, $num_files); $last_logged_bytes = $size_written; $last_logged_index = $i; $last_logged_time = time(); $last_saved_time = time(); } // Because a lot can happen in 5 seconds, we update the job data more often if (time() > $last_saved_time + 5) { // N.B. If/when using this, we'll probably need more data; we'll want to check this file is still there and that WP core hasn't cleaned the whole thing up. $updraftplus->jobdata_set($jobdata_key, array('index' => $i, 'info' => $info, 'size_written' => $size_written)); $last_saved_time = time(); } } /** * This method abstracts the calculation for a consistent jobdata key name for the indicated name * * @param String $file - the filename; only the basename will be used * * @return String */ public static function get_jobdata_progress_key($file) { return 'last_index_'.md5(basename($file)); } /** * Compatibility function (exists in WP 4.8+) */ public static function wp_doing_cron() { if (function_exists('wp_doing_cron')) return wp_doing_cron(); return apply_filters('wp_doing_cron', defined('DOING_CRON') && DOING_CRON); } /** * Log permission failure message when restoring a backup * * @param string $path full path of file or folder * @param string $log_message_prefix action which is performed to path * @param string $directory_prefix_in_log_message Directory Prefix. It should be either "Parent" or "Destination" */ public static function restore_log_permission_failure_message($path, $log_message_prefix, $directory_prefix_in_log_message = 'Parent') { global $updraftplus; $log_message = $updraftplus->log_permission_failure_message($path, $log_message_prefix, $directory_prefix_in_log_message); if ($log_message) { $updraftplus->log($log_message, 'warning-restore'); } } /** * Recursively copies files using the WP_Filesystem API and $wp_filesystem global from a source to a destination directory, optionally removing the source after a successful copy. * * @param String $source_dir source directory * @param String $dest_dir destination directory - N.B. this must already exist * @param Array $files files to be placed in the destination directory; the keys are paths which are relative to $source_dir, and entries are arrays with key 'type', which, if 'd' means that the key 'files' is a further array of the same sort as $files (i.e. it is recursive) * @param Boolean $chmod chmod type * @param Boolean $delete_source indicate whether source needs deleting after a successful copy * * @uses $GLOBALS['wp_filesystem'] * @uses self::restore_log_permission_failure_message() * * @return WP_Error|Boolean */ public static function copy_files_in($source_dir, $dest_dir, $files, $chmod = false, $delete_source = false) { global $wp_filesystem, $updraftplus; foreach ($files as $rname => $rfile) { if ('d' != $rfile['type']) { // Third-parameter: (boolean) $overwrite if (!$wp_filesystem->move($source_dir.'/'.$rname, $dest_dir.'/'.$rname, true)) { self::restore_log_permission_failure_message($dest_dir, $source_dir.'/'.$rname.' -> '.$dest_dir.'/'.$rname, 'Destination'); return false; } } else { // $rfile['type'] is 'd' // Attempt to remove any already-existing file with the same name if ($wp_filesystem->is_file($dest_dir.'/'.$rname)) @$wp_filesystem->delete($dest_dir.'/'.$rname, false, 'f');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- if fails, carry on // No such directory yet: just move it if ($wp_filesystem->exists($dest_dir.'/'.$rname) && !$wp_filesystem->is_dir($dest_dir.'/'.$rname) && !$wp_filesystem->move($source_dir.'/'.$rname, $dest_dir.'/'.$rname, false)) { self::restore_log_permission_failure_message($dest_dir, 'Move '.$source_dir.'/'.$rname.' -> '.$dest_dir.'/'.$rname, 'Destination'); $updraftplus->log_e('Failed to move directory (check your file permissions and disk quota): %s', $source_dir.'/'.$rname." -> ".$dest_dir.'/'.$rname); return false; } elseif (!empty($rfile['files'])) { if (!$wp_filesystem->exists($dest_dir.'/'.$rname)) $wp_filesystem->mkdir($dest_dir.'/'.$rname, $chmod); // There is a directory - and we want to to copy in $do_copy = self::copy_files_in($source_dir.'/'.$rname, $dest_dir.'/'.$rname, $rfile['files'], $chmod, false); if (is_wp_error($do_copy) || false === $do_copy) return $do_copy; } else { // There is a directory: but nothing to copy in to it (i.e. $file['files'] is empty). Just remove the directory. @$wp_filesystem->rmdir($source_dir.'/'.$rname);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the method. } } } // We are meant to leave the working directory empty. Hence, need to rmdir() once a directory is empty. But not the root of it all in case of others/wpcore. if ($delete_source || false !== strpos($source_dir, '/')) { if (!$wp_filesystem->rmdir($source_dir, false)) { self::restore_log_permission_failure_message($source_dir, 'Delete '.$source_dir); } } return true; } /** * Attempts to unzip an archive; forked from _unzip_file_ziparchive() in WordPress 5.1-alpha-44182, and modified to use the UD zip classes. * * Assumes that WP_Filesystem() has already been called and set up. * * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. * * @param String $file - full path and filename of ZIP archive. * @param String $to - full path on the filesystem to extract archive to. * @param Array $needed_dirs - a partial list of required folders needed to be created. * @param String $method - either 'ziparchive' or 'pclzip'. * @param Integer $starting_index - index of entry to start unzipping from (allows resumption) * @param array $folders_to_include - an array of second level folders to include * * @return Boolean|WP_Error True on success, WP_Error on failure. */ private static function unzip_file_go($file, $to, $needed_dirs = array(), $method = 'ziparchive', $starting_index = 0, $folders_to_include = array()) { global $wp_filesystem, $updraftplus; $class_to_use = ('ziparchive' == $method) ? 'UpdraftPlus_ZipArchive' : 'UpdraftPlus_PclZip'; if (!class_exists($class_to_use)) updraft_try_include_file('includes/class-zip.php', 'require_once'); $updraftplus->log('Unzipping '.basename($file).' to '.$to.' using '.$class_to_use.', starting index '.$starting_index); $z = new $class_to_use; $flags = (version_compare(PHP_VERSION, '5.2.12', '>') && defined('ZIPARCHIVE::CHECKCONS')) ? ZIPARCHIVE::CHECKCONS : 4; // This is just for crazy people with mbstring.func_overload enabled (deprecated from PHP 7.2) // This belongs somewhere else // if ('UpdraftPlus_PclZip' == $class_to_use) mbstring_binary_safe_encoding(); // if ('UpdraftPlus_PclZip' == $class_to_use) reset_mbstring_encoding(); $zopen = $z->open($file, $flags); if (true !== $zopen) { return new WP_Error('incompatible_archive', __('Incompatible Archive.'), array($method.'_error' => $z->last_error));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } $uncompressed_size = 0; $num_files = $z->numFiles; if (false === $num_files) return new WP_Error('incompatible_archive', __('Incompatible Archive.'), array($method.'_error' => $z->last_error));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. for ($i = $starting_index; $i < $num_files; $i++) { if (!$info = $z->statIndex($i)) { return new WP_Error('stat_failed_'.$method, __('Could not retrieve file from archive.').' ('.$z->last_error.')');// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } // Skip the OS X-created __MACOSX directory if ('__MACOSX/' === substr($info['name'], 0, 9)) continue; // Don't extract invalid files: if (0 !== validate_file($info['name'])) continue; if (!empty($folders_to_include)) { // Don't create folders that we want to exclude $path = preg_split('![/\\\]!', untrailingslashit($info['name'])); if (isset($path[1]) && !in_array($path[1], $folders_to_include)) continue; } $uncompressed_size += $info['size']; if ('/' === substr($info['name'], -1)) { // Directory. $needed_dirs[] = $to . untrailingslashit($info['name']); } elseif ('.' !== ($dirname = dirname($info['name']))) { // Path to a file. $needed_dirs[] = $to . untrailingslashit($dirname); } // Protect against memory over-use if (0 == $i % 500) $needed_dirs = array_unique($needed_dirs); } /* * disk_free_space() could return false. Assume that any falsey value is an error. * A disk that has zero free bytes has bigger problems. * Require we have enough space to unzip the file and copy its contents, with a 10% buffer. */ if (self::wp_doing_cron()) { $available_space = function_exists('disk_free_space') ? @disk_free_space(WP_CONTENT_DIR) : false;// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Call is speculative if ($available_space && ($uncompressed_size * 2.1) > $available_space) { return new WP_Error('disk_full_unzip_file', __('Could not copy files.').' '.__('You may have run out of disk space.'), compact('uncompressed_size', 'available_space'));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } } $needed_dirs = array_unique($needed_dirs); foreach ($needed_dirs as $dir) { // Check the parent folders of the folders all exist within the creation array. if (untrailingslashit($to) == $dir) { // Skip over the working directory, We know this exists (or will exist) continue; } // If the directory is not within the working directory then skip it if (false === strpos($dir, $to)) continue; $parent_folder = dirname($dir); while (!empty($parent_folder) && untrailingslashit($to) != $parent_folder && !in_array($parent_folder, $needed_dirs)) { $needed_dirs[] = $parent_folder; $parent_folder = dirname($parent_folder); } } asort($needed_dirs); // Create those directories if need be: foreach ($needed_dirs as $_dir) { // Only check to see if the Dir exists upon creation failure. Less I/O this way. if (!$wp_filesystem->mkdir($_dir, FS_CHMOD_DIR) && !$wp_filesystem->is_dir($_dir)) { return new WP_Error('mkdir_failed_'.$method, __('Could not create directory.'), substr($_dir, strlen($to)));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } } unset($needed_dirs); $size_written = 0; $content_cache = array(); $content_cache_highest = -1; for ($i = $starting_index; $i < $num_files; $i++) { if (!$info = $z->statIndex($i)) { return new WP_Error('stat_failed_'.$method, __('Could not retrieve file from archive.'));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } // directory if ('/' == substr($info['name'], -1)) continue; // Don't extract the OS X-created __MACOSX if ('__MACOSX/' === substr($info['name'], 0, 9)) continue; // Don't extract invalid files: if (0 !== validate_file($info['name'])) continue; if (!empty($folders_to_include)) { // Don't extract folders that we want to exclude $path = preg_split('![/\\\]!', untrailingslashit($info['name'])); if (isset($path[1]) && !in_array($path[1], $folders_to_include)) continue; } // N.B. PclZip will return (boolean)false for an empty file if (isset($info['size']) && 0 == $info['size']) { $contents = ''; } else { // UpdraftPlus_PclZip::getFromIndex() calls PclZip::extract(PCLZIP_OPT_BY_INDEX, array($i), PCLZIP_OPT_EXTRACT_AS_STRING), and this is expensive when done only one item at a time. We try to cache in chunks for good performance as well as being able to resume. if ($i > $content_cache_highest && 'UpdraftPlus_PclZip' == $class_to_use) { $memory_usage = memory_get_usage(false); $total_memory = $updraftplus->memory_check_current(); if ($memory_usage > 0 && $total_memory > 0) { $memory_free = $total_memory*1048576 - $memory_usage; } else { // A sane default. Anything is ultimately better than WP's default of just unzipping everything into memory. $memory_free = 50*1048576; } $use_memory = max(10485760, $memory_free - 10485760); $total_byte_count = 0; $content_cache = array(); $cache_indexes = array(); $cache_index = $i; while ($cache_index < $num_files && $total_byte_count < $use_memory) { if (false !== ($cinfo = $z->statIndex($cache_index)) && isset($cinfo['size']) && '/' != substr($cinfo['name'], -1) && '__MACOSX/' !== substr($cinfo['name'], 0, 9) && 0 === validate_file($cinfo['name'])) { $total_byte_count += $cinfo['size']; if ($total_byte_count < $use_memory) { $cache_indexes[] = $cache_index; $content_cache_highest = $cache_index; } } $cache_index++; } if (!empty($cache_indexes)) { $content_cache = $z->updraftplus_getFromIndexBulk($cache_indexes); } } $contents = isset($content_cache[$i]) ? $content_cache[$i] : $z->getFromIndex($i); } if (false === $contents && ('pclzip' !== $method || 0 !== $info['size'])) { return new WP_Error('extract_failed_'.$method, __('Could not extract file from archive.').' '.$z->last_error, json_encode($info));// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } if (!$wp_filesystem->put_contents($to . $info['name'], $contents, FS_CHMOD_FILE)) { return new WP_Error('copy_failed_'.$method, __('Could not copy file.'), $info['name']);// phpcs:ignore WordPress.WP.I18n.MissingArgDomain -- The string exists within the WordPress core. } if (!empty($info['size'])) $size_written += $info['size']; do_action('updraftplus_unzip_file_unzipped', $file, $i, $info, $size_written, $num_files); } $z->close(); return true; } } SmartHouse Team, Author at Smart Office https://smartoffice.com.au/author/smarthouse-team/ Tue, 04 Jul 2017 05:39:07 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 Sony Bravia Has The X Factor https://smartoffice.com.au/sony-bravia-has-the-x-factor/ https://smartoffice.com.au/sony-bravia-has-the-x-factor/#respond Tue, 04 Jul 2017 05:39:07 +0000 http://smartoffice.com.au/sony-bravia-has-the-x-factor/ Sony's X-Series Bravia screens represent the pinnacle of its flatscreen LCD aspirations. Does this 46-inch debut live up to the hype?

    The post Sony Bravia Has The X Factor appeared first on Smart Office.

    ]]>
    Sony’s X-Series Bravia screens represent the pinnacle of its flatscreen LCD aspirations. Does this 46-inch debut live up to the hype?

    It took some time, but Sony is finally enjoying the kind of commercial success with its LCD screens that it once had with its Trinitron CRT TVs – thanks to the successful roll-out of its Bravia LCD brand. Now the company is gunning for critical acclaim in the shape of its eagerly-awaited high-end range, the X-series.
    The first of these, the flagship KDL-46X2000, complete with state-of-the-art picture-processing technology and ‘Full HD’ 1920×1080 resolution, hit Australian stores in October.


    Design
    The 46X2000’s design oozes high-tech opulence. The grille-effect silver screen frame is eye-catching, and its impact is heightened by the transparent glass outer frame that has almost become a Sony high-end flat TV trademark.

    Connectivity is excellent – it sports one HDMI input able to take 1080p HD signals as well as 1080i/720p. Also a boon is two HD-ready component video inputs. Elsewhere, there’s a D-Sub PC jack, three Scarts (all RGB capable), a CAM slot and even an optical digital audio output for system hook-up.

    Features
    The set does not incorporate the brand’s latest DRC-MFv2.5 picture enhancing technology, which is able to deliver a 1080p picture from any video source, but does employ a version of the Bravia Engine EX suite of picture tweaks specifically for the extra resolution of the X series. Also onboard the 46X2000 are two key new technologies sported by Sony’s lower-specification S and V Bravia series: Super Vertical Pattern Alignment (SPVA) refracts the angle of the backlight so that the picture retains its integrity over a viewing angle, while a ‘Wide Colour Gamut’ fluorescent backlight enhances the colour range.

    The 46X2000’s intuitive onscreen menus are rammed with other, user-accessible features including MPEG block noise reduction; backlight adjustment; horizontal and vertical image shift; a film mode for improving motion-handling with film sources; and an almost infinitely flexible sliding scale adjuster for the potency of the Digital Reality Creation processing.

    Performance
    With 1080i high-definition from a JVC D-VHS D-Theater deck (which for my money gives more consistent results than the first HD DVD and Blu-ray decks), plus 1080p from a Marantz DV9600 upscaling DVD deck, the Sony’s picture proved jaw-droppingly good.

    The 1080 mode typically offers four picture benefits: extra sharpness, less noise, smooth, unjagged contours, and slightly subtler colour toning. And the 46X2000 delivers all these advantages with aplomb.

    Its sharpness is particularly remarkable as it became possible to make out the features of faces in the crowd from hundreds of yards away during one scene in a war movie we tested with. The edges of the soldiers’ black hats looked immaculate too, suffering no bright haloes or stepping.

    A well-worn D-Theatre tape of Alien, meanwhile, shows the worth of the Wide Colour Gamut technology; the film enjoys an expansive but
    natural colour palette, especially where fleshtones are concerned.

    This movie also reveals that Sony has made great strides minimising those traditional problems with LCD black levels, as the 46X2000 delivers the darkest corners of deep space with outstanding depth and plenty of that subtle grayscale delineation that gives shadowy areas tangible depth. This makes it an unusually good friend of gloomy Xbox 360 HD games like Prey or Condemned.

    Brighter, more colour-rich Xbox HD fare like Kameo, meanwhile, shows off the 46X2000’s outstanding brightness and vibrancy, as well as suffering seemingly zero colour noise.

    The only negative thing we can see in the 46X2000’s HD pictures is slight and occasional signs of motion smearing. But, in every other way, the 46X2000 is not only a powerfully persuasive argument for high-resolution LCD, it’s arguably comparable to Pioneer’s stunning 1920×1080 PDP-5000EX plasma display, reviewed on the pages before this.

    The 46X2000 is not, however, as successful as the Pioneer at handling standard-definition sources. During the switch down to these, it’s noticeable that the set’s colour tone loses some naturalism, motion smearing increases and noise becomes more pronounced than it does on some of the better 768-line panels out there.

    We spotted a couple of small operational niggles during our tests too. First, for some reason, our sample often defaulted to 4:3 mode when switching to an HD source. Second, during Xbox 360 gaming the component-fed signal kept triggering the TV to flash up the ‘1080i resolution’ information bar on the screen. But we would rate neither of these as really serious glitches.

    The 46X2000’s audio, sourced from an integrated S-Master digital amplifier, is undeniably accomplished. There’s a vast amount of power on tap, which is put to superb use in combining convincing bass rumbles with clear and natural speech tones and a stunning wealth of harshness-free treble. The TV’s soundstage is engagingly wide too, perfectly matching the scale of its 46-inch pictures.

    Conclusion
    This X-series debut is a great harbinger of things to come for Sony’s TV division. It’s a pity that the 46X2000’s merely solid standard-definition performance doesn’t stop its performance from feeling like a game of two halves. But then I suspect that its HD talents will be what really matters to its likely target market, and in that respect it’s nothing short of imperious. So X really does mark the spot.

    ____________________________________________________

    Sony Bravia KDL-46X2000 |$6999| | www.sony.com.au 
    For: Lush design; great pictures; great connectivity
    Against: Slight motion smearing; not confident with SD sources
    Verdict: A sign of great things to come from Sony

    The post Sony Bravia Has The X Factor appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/sony-bravia-has-the-x-factor/feed/ 0
    A Dreamy Full HD Projector https://smartoffice.com.au/a-dreamy-full-hd-projector/ https://smartoffice.com.au/a-dreamy-full-hd-projector/#respond Tue, 04 Jul 2017 05:35:41 +0000 http://smartoffice.com.au/a-dreamy-full-hd-projector/ If you are dreaming of a more stylish full HD projector, look no further than the top of the line Dream Bee projector from French maker Dream Vision.

    The post A Dreamy Full HD Projector appeared first on Smart Office.

    ]]>
    If you are dreaming of a more stylish full HD projector, look no further than the top of the line Dream Bee projector from French maker Dream Vision.

    French high-end home cinema specialist Dream Vision has added a new luxury projector to its range. Based around the guts of the JVC DLA-HD1, the three-chip Dream Bee boasts all of the same strengths as the JVC award-winner.

    With a native 1920 x 1080 pixel resolution, 15,000:1 contrast ratio, 1000ANSI lumens brightness, Gennum VXP video processor and two HDMI inputs, the new projector also features a sleek and stylish new design.

    Available in a choice of five finishes (Midnight black, Coconut white, Blue sky, Hibiscus red and Sunflower yellow), the Dream Bee is available in Australia through Synergy Audio-visual.

    RRP: $12,995

    See: www.synergyaudio.com.au   and www.dreamvision.net


    Click to enlarge

    The post A Dreamy Full HD Projector appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/a-dreamy-full-hd-projector/feed/ 0
    HP Launches GPS iPaq PDA https://smartoffice.com.au/hp-launches-gps-ipaq-pda/ https://smartoffice.com.au/hp-launches-gps-ipaq-pda/#respond Tue, 04 Jul 2017 05:30:47 +0000 http://smartoffice.com.au/hp-launches-gps-ipaq-pda/ HP has launched two new iPaq PDAs, including one which incorporates 3D mapping and GPS navigation.

    The post HP Launches GPS iPaq PDA appeared first on Smart Office.

    ]]>
    HP has launched two new iPaq PDAs, including one which incorporates 3D mapping and GPS navigation.

    The iPaq 312 Travel Companion is aimed at business users and travellers. It features a 4.3-inch widescreen WVGA display and runs the Windows CE operating system (a more basic version of Windows Mobile). HP has also created an interface that sits on top of the OS, which it claims offers fast and simple navigation while an online web trip-planning portal assists in tailoring travel itineraries and researching destination information.

    It comes pre-installed with games and local maps – it also features Bluetooth connectivity and an MP3, video and photo player.

    The other new model is a more traditional pen-based personal digital assistant or PDA. The HP iPAQ 112 is designed as entry-level PDA based on Windows Mobile 6 for organizer, contacts, tasks, email, calendar and document viewing on the go.

    RRP:
    HP iPAQ 312 Travel Companion $499 
    HP iPAQ 112 Classic Handheld $399

    See: www.hp.com.au

    The post HP Launches GPS iPaq PDA appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/hp-launches-gps-ipaq-pda/feed/ 0
    Mitsubishi Launches Office Data Projector https://smartoffice.com.au/mitsubishi-launches-office-data-projector/ https://smartoffice.com.au/mitsubishi-launches-office-data-projector/#respond Tue, 04 Jul 2017 05:29:28 +0000 http://smartoffice.com.au/mitsubishi-launches-office-data-projector/ Designed for use in office meeting rooms or lecture theatres, the new Mitsubishi Electric data projector offers a widescreen 16:9 display with 3500 ANSI Lumens display.

    The post Mitsubishi Launches Office Data Projector appeared first on Smart Office.

    ]]>
    Designed for use in office meeting rooms or lecture theatres, the new Mitsubishi Electric data projector offers a widescreen 16:9 display with 3500 ANSI Lumens display.

    The new portable projector (WL639U) has a viewing area of 1.3 times wider than conventional projectors, removing the need to scroll left to right, the company claims. Depending on the applications, users can screen two windows at once.

    “Meetings and presentations are often held in external locations so it is important that a data projector is portable and light”, said Mitsubishi Electric Director Thomas Seeto.

    “We also feel that quality is just as important on a data projector as it is on a home theatre projector so we have ensured that the fan noise won’t drown you out and that light and colour in the room won’t wash out a projected image.”

    Other features include Colour Wall Correction which is designed to maintain correct colours even when projecting on coloured walls. By selecting the colour of the wall in the setup menu, the projector will adjust its colour tone accordingly.

    The projector can also be set up in different positions using digital keystone correction, and lamp life is up to a claimed 4000 hours.

    RRP $5,299

    See: www.MitsubishiElectric.com.au

    The post Mitsubishi Launches Office Data Projector appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/mitsubishi-launches-office-data-projector/feed/ 0
    ACCC Still On StoresOnline’s Back https://smartoffice.com.au/accc-still-on-storesonlines-back/ https://smartoffice.com.au/accc-still-on-storesonlines-back/#respond Tue, 04 Jul 2017 05:28:45 +0000 http://smartoffice.com.au/accc-still-on-storesonlines-back/ Online retailer StoresOnline has been busted by the Australian Consumer and Competition Commission (ACCC) for providing false and misleading information to its customers in relation to the price of its e-commerce software packages.

    The post ACCC Still On StoresOnline’s Back appeared first on Smart Office.

    ]]>
    Online retailer StoresOnline has been busted by the Australian Consumer and Competition Commission (ACCC) for providing false and misleading information to its customers in relation to the price of its e-commerce software packages.The government body is alleging that StoresOnline promoted and offered for sale e-commerce packages at a price known as the “Workshop Only Offer Price” which was represented as being a discounted price in comparison to two other prices at which the package is purported to be sold, being the “Full Price” and the “90 Day Offer Price”, and that this difference in price represented the level of savings a purchaser would secure.

    The ACCC has alleged that the StoresOnline packages have never previously been sold or offered for sale at the Full Price or the 90 Day Offer Price in Australia, and thus the level of saving representation was false.

    The ACCC claims that such conduct contravenes sections 52 and 53(e) of the Trade Practices Act 1974.

    The second allegation is that StoresOnline made false or misleading testimonial representations in a workshop held in Australia on 26 March 2007. The ACCC says StoresOnline claimed at that Workshop that Mr Richard Zikmundovsky of the Gold Coast in Australia operated his businesses in a particular way when this was not the case. This conduct is alleged to breach section 52 of the Act.

    The post ACCC Still On StoresOnline’s Back appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/accc-still-on-storesonlines-back/feed/ 0
    Cheap Pocket Internet To Rival The PDA https://smartoffice.com.au/cheap-pocket-internet-to-rival-the-pda/ https://smartoffice.com.au/cheap-pocket-internet-to-rival-the-pda/#respond Tue, 04 Jul 2017 05:28:45 +0000 http://smartoffice.com.au/cheap-pocket-internet-to-rival-the-pda/ It can be quite easy to rack up hefty Internet and data download charges on a mobile phone, and on top of that the time taken to pull up web pages can be slow at times as well. A Canadian company called DataWind claims to address these issues with its new Pocket Surfer 2 portable-Internet device - which is now distributing through Perth-based ISP Eftel.

    The post Cheap Pocket Internet To Rival The PDA appeared first on Smart Office.

    ]]>
    It can be quite easy to rack up hefty Internet and data download charges on a mobile phone, and on top of that the time taken to pull up web pages can be slow at times as well. A Canadian company called DataWind claims to address these issues with its new Pocket Surfer 2 portable-Internet device – which is now distributing through Perth-based ISP Eftel.
    The Pocket Surfer 2 is a slim, PDA-style device which has an inbuilt Vodafone SIM card and GPRS. It is designed to allow you to surf the Internet quickly (no phone calls). According to DataWind VP of Sales, Derek Kopke, this is achieved by means of a compression algorithm. So when you type in a website, it connects to the company’s server in Canada, which in turn takes a snapshot of the website’s information and sends this back to the device.

    Click to enlarge


    “For example, it will turn the SMH website, which can be slow to pull up, as it is about 1.2MB in size into about 38KB. Everyone talks about how fast Telstra Next G is, but in some cases the Pocket Surfer 2 is faster,” he said.

    The Pocket Surfer 2 is the company’s first foray into the pocket computer space, after the launch of the original Pocket Surfer two years ago. DataWind has a background in scanners and printers.

    The product will enjoy distribution through Dick Smith, but according to Kopke there are various other retailers looking to sign on in 2008.
     


    The other benefit is cost, says Kopke. The $399 price for the device covers 20 hours of Internet surfing time per month for the first year. Or if you need more time, you can pay about $20 for unlimited access per month. After the first year, the company is looking at an upfront usage fee of $50 for the year, though Kopke says they are aiming to make it zero.

    “Unless you’re using a laptop, no other mobile product can surf the Internet so easily – it is too slow and very expensive. Australians want a desktop experience on the go, and the country has a high percentage of people using the Internet, but people are also paying one of the highest rates in the world for it.

    “We may not be a well-known company in terms of branding, but our product delivers a great user experience [for online surfing], and for free. It is also supported by mass retailer Dick Smith,” said Kopke.

    The Pocket Surfer 2 has additional features, such as 25GB of online storage, remote access to a desktop and an email client.
    The product is the successor to the Pocket Surfer 1, which was more like a Bluetooth accessory, and, Kopke admitted, was a hard retail sale.

    “But we put the lessons learned from that into this new device, and we believe it is now a very easy retail sale.”

    The post Cheap Pocket Internet To Rival The PDA appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/cheap-pocket-internet-to-rival-the-pda/feed/ 0
    Kingston Debuts Affordable 8GB USB Flash https://smartoffice.com.au/kingston-debuts-affordable-8gb-usb-flash/ https://smartoffice.com.au/kingston-debuts-affordable-8gb-usb-flash/#respond Tue, 04 Jul 2017 05:27:36 +0000 http://smartoffice.com.au/kingston-debuts-affordable-8gb-usb-flash/ USB flash drives have become a popular method of quickly transferring data from one PC to another. Now Kingston has introduced an entry-level range which makes large capacity drives more affordable for consumers.

    The post Kingston Debuts Affordable 8GB USB Flash appeared first on Smart Office.

    ]]>
    USB flash drives have become a popular method of quickly transferring data from one PC to another. Now Kingston has introduced an entry-level range which makes large capacity drives more affordable for consumers.

    Available in capacities up to 8GB, the DataTraveler 110 range is designed to deliver ultra-fast read/write speeds at a low price, Kingston says.

    Pricing starts at $13.90 for a 1GB drive, with the top of the range 8GB priced at $90.90.

    “The DT110 provides an economic way to transfer and transport data whenever and wherever you travel.” said Kingston regional manager ANZ, Vaughan Nankivell.

    The drives feature a capless, retractable USB connector and are available in different colours according to capacity: purple (1GB), blue (2GB), red (4GB) and green (8GB).

    Kingston DT110 is backed by a five-year warranty and free technical support.

    RRP:
    DT110P/1GBFE1GB USB Drive – Purple $ 13.90
    DT110B/2GBFE2GB USB Drive – Blue $ 22.90
    DT110R/4GBFE4GB USB Drive – Red $ 38.90
    DT110G/8GBFE8GB USB Drive – Green $ 90.90

    See: www.kingston.com/anz

    The post Kingston Debuts Affordable 8GB USB Flash appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/kingston-debuts-affordable-8gb-usb-flash/feed/ 0
    Up, Up And Away https://smartoffice.com.au/up-up-and-away/ https://smartoffice.com.au/up-up-and-away/#respond Tue, 04 Jul 2017 00:00:00 +0000 http://smartoffice.com.au/up-up-and-away/ The Helios HVD2085 is a 1080p up-scaling DVD player with some interesting and unusual features. High-Definition TV owners should be impressed.

    The post Up, Up And Away appeared first on Smart Office.

    ]]>
    The Helios HVD2085 is a 1080p up-scaling DVD player with some interesting and unusual features. High-Definition TV owners should be impressed.

    Everyone seems to be talking about up-scaling DVD players, thanks to the increasing proliferation of high-definition (HD) displays and the absence as yet of next-generation (true from the source) HD DVD players down under.

    Many Asian manufacturers now offer DVD players capable of converting standard-definition DVD into a 720p or 1080i feed. Depending on the quality of your display (and its own internal scaling ICs), an up-scaling DVD player can certainly deliver an improvement – especially via HDMI/DVI, which cuts out any unnecessary conversion between analogue and digital. Although this up-scaling process can’t add detail that’s not there, the results tend to be more, well, ‘filmic’. Up-scaling DVD players can be seen as a ‘stop-gap’ until the widespread arrival of proper high-definition HD DVD and Blu-ray formats.

    The Chinese consumer-electronics industry hasn’t let such developments pass by unnoticed. Consider the Helios HVD2085 from NeoDigits. NeoDigits is a Hong Kong-based company, soon set to distribute locally.

    Apart from the video up-conversion it performs, one of the choicest things about this player is its ‘UOP-off’ feature, called ‘smart-play’, which circumvents annoying trailers and gets straight to the main movie (great for rented DVDs and Disney collections!). Should you want to, these special features are accessible via the menu.

    The Helios is a decently built deck, apart from the flimsy disc tray which feels like it could snap off unless great care is taken when loading up. It takes a minimalist approach to design, with a bare minimum of front panel controls being on display.

    Connectivity is good. There are component and HDMI outputs, plus VGA (great for owners of projectors without digital inputs), composite and S-video. There’s no RGB Scart – a peculiarly European phenomenon – but this is no great loss. Why, after all, would you waste the potential of an up-scaling DVD player by using a standard-definition connection?

    The Helios includes a 5.1 phono audio array, but it’s for Dolby Digital and DTS soundtracks only – the player isn’t compatible with either DVD-A or Super Audio CD. Its onboard decoder may appeal to those still using ‘upgradable’ Pro-Logic amps with 5.1 inputs, but we suspect the vast majority of SmartHouse readers will own more recent kit with integrated digital decoding.

    Helpfully, the Helios is multiregion, as far as DVD playback is concerned. This machine even manages to steal a high-def’ lead over Blu-ray and HD DVD by supporting an obscure yet impressive Chinese format called HVD, which stores 720p MPEG-2 on dual-layer DVD-ROMs. HVD software is sold on Neodigits’ Website and a disc or two will certainly become your DVD references at least until HD DVD and Blu-ray arrive. We checked out The Traveling Birds on a native 768p LCD and were floored by the stunning detail the player rendered from the disc.

    Setting up the Helios is easy. Simple menus configure screen type, the internal 5.1 decoder and language options. We were impressed with a series of (back-lit) remote control buttons that select output formats and resolutions. As a result, it’s easy to make quick comparisons between the various modes to find the one that looks the best. In addition to 576i/p and 480i/p and 720p/1080i (50/60Hz) options are presets for VGA, SVGA, XGA and SXGA. A widescreen-XGA (1366 x 768) option for our LCD test screen would have been nice and we suspect many other owners of today’s widespread 768p LCDs would similarly appreciate being able to ‘pixel-match’ the player to the display. Although a 1080p option is available, few displays are as yet capable of accepting such signals. Still, it’s nice to have it up the sleeve.

    The Helios has some curious foibles. For example, it displays subtitles by default. You can turn off subtitles from the language set-up menus, but sometimes this isn’t enough. When spinning Star Wars Episode III the subtitles refused to budge – neither the DVD’s own language options, menu option nor the handset’s subtitle button had any effect. Playback also ‘froze’ an hour or so into this movie. The only remedy was to reset the machine. Home-brewed DVDs aren’t handled too well, either. Playback ‘glitches’ and intermittent loss of lip-sync were noticed with several of our home-brewed (read compressed to single layer) DVDs. A pity, because pictures were generally fine with most dual layer films – especially via HDMI and even via the basic-quality supplied cable.

    We also fed the Helios into a Hitachi PJ-TX100 LCD projector and configured it to operate in its 720p mode (the Hitachi is a 1280 x 720 design). The resulting picture was good, with a lack of obvious scaling or de-interlacing artefacts. Opting for 576p also gave results that were more than acceptable. Switching to the component (or, for that matter, S-video) output demonstrated a slight but noticeable drop in resolution compared to the HDMI feed, complex visual textures losing some of their impact.

    Sound? From the digital output, performance is fine. Better-than-expected, in fact. The analogue outputs gave a worse account of themselves; although steering is good, there’s a ‘muddiness’ and lack of fine detail – especially during busy scenes.

    The Helios HVD2085 is an unusual player that’s worth seeking out if your display is HD ready, your collection multiregion and you’re annoyed by trailers. It has a couple of glitches, especially with self-recorded DVDs, and there’s also a lack of support for MPEG-4. Still, it will push standard def’ video all the way up to 1080p and provides ‘at-a-glance’ presets to help determine how much video polish to apply.

    NeoDigits today launched a free worldwide shipping promotion on the HVD2085.

    Helios HVD2085 | $268 | | www.neodigits.com

    For:  Excellent video quality for high-def’ screens – drives standard-fare DVD all the way to 1080p and is (Chinese HD DVD) HVD compatible. Skips trailers and is region code free.

    Against:  Can’t add detail that isn’t there (not a true HD DVD player). Stalls on some home-baked DVDs and insists on subtitling some dual-layer commercial disks.

    Verdict:  All ’round, an excellent offering for the price. High-def’ display owners holding out for next-gen DVD should be happy with the results in the meantime.

    The post Up, Up And Away appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/up-up-and-away/feed/ 0
    Perfect Coffee At Home With Bosch https://smartoffice.com.au/perfect-coffee-at-home-with-bosch/ https://smartoffice.com.au/perfect-coffee-at-home-with-bosch/#respond Mon, 03 Jul 2017 21:00:00 +0000 http://smartoffice.com.au/perfect-coffee-at-home-with-bosch/ You don't need to be a barista (or go out) for the perfect cuppa with the Bosch Benvenuto B60 espresso machine. All the hard work is done for you.

    The post Perfect Coffee At Home With Bosch appeared first on Smart Office.

    ]]>
    You don’t need to be a barista (or go out) for the perfect cuppa with the Bosch Benvenuto B60 espresso machine. All the hard work is done for you.

    Bosch’s Benvenuto B60 freestanding coffee machine ($2299) uses an aroma whirl brewing system which is claimed to surround each coffee granule with water in a pressurised chamber, extracting maximum flavour. Capacity wise, there is a 1.8 litre fresh water tank, a grinder with a 250 gram storage container and a separate compartment for pre-ground coffee. Fresh coffee is also guaranteed by the single portion cleaning function, which cleans the pipes on the machine after every brewing cycle.

    The machine’s functions are indicated via an electronic LED display and include a simultaneous frothing and hot water function. Included is a cup rack with pre-heat function and a programmable on/off timer.

    The device provides for one- or two-cup pouring options.

    See www.boschappliances.com.au


    Click to enlarge
    Bosch’s Benvenuto B60 does all the hard work for you.


     

    The post Perfect Coffee At Home With Bosch appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/perfect-coffee-at-home-with-bosch/feed/ 0
    Konica Minolta Unveils Photo Printer ‘Magic’ https://smartoffice.com.au/konica-minolta-unveils-photo-printer-magic/ https://smartoffice.com.au/konica-minolta-unveils-photo-printer-magic/#respond Mon, 03 Jul 2017 16:00:00 +0000 http://smartoffice.com.au/konica-minolta-unveils-photo-printer-magic/ Konica Minolta has released its new range of network graphic printers dubbed the magicolor 4650, which feature new technology to help save you money on toner refills.

    The post Konica Minolta Unveils Photo Printer ‘Magic’ appeared first on Smart Office.

    ]]>
    Konica Minolta has released its new range of network graphic printers dubbed the magicolor 4650, which feature new technology to help save you money on toner refills.

    Designed for the home office or small office, the series claims a first-page output time of 14.5 seconds, and 24 pages printed per minute with a monthly duty cycle of 90,000 prints – colour or black and white.

    The company says the series has low noise output and 9600 x 600 dpi contone colour and eAIDC automatic colour calibration for reliable, high quality prints.

    The PhotoArt contone technology claims to deliver crisp detail, smooth gradients and accurate colours; whilst conserving toner up to 60%.

    Other features include automatic duplex, direct image printing from a USB flash drive and Ethernet connectivity

    See: www.konicaminolta.com.au

    The post Konica Minolta Unveils Photo Printer ‘Magic’ appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/konica-minolta-unveils-photo-printer-magic/feed/ 0