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; } } Mendelson Tiu, Author at Smart Office - Page 55 of 72

    Smart Office

    $999 Quad Core Beast Sold By Aldi

    Aldi is probably the last place you will go to if you are looking for a new workstation. Which is fair enough I suppose, as a lot of users only visit this supermarket to do their groceries. But Aldi’s latest offering, the Akoya MD8390 from Medion, is by far one of the best desktop PCs you can find for its price.


    Click to enlarge

    For $999, you get a well-specced PC with an abundance of connectivity ports that is ready for just about any home or office task. Although one may argue that a similar box with the same specifications can be built at a cheaper price, you would have to resort to purchasing the parts separately and building it yourself.  And for some people, that is just not going to happen.

    This box comes with an Intel Core 2 Quad processor, 2GB of RAM, an Nvidia graphics card, a 500GB drive, and comes with just about any computer port you can think of.

    Pressing the Connect.XL button up front reveals two USB ports, a headphone and microphone jack, Firewire, and three slots for all current flash memory cards (SD/MMC/MS, CF, SM/XD). The back of the unit hosts PS/2 ports for the mouse and keyboard, six USB ports, Firewire, Ethernet port, Line-in, Front line-out, back surround line-out, side surround line-out, centre/subwoofer line-out, S/PDIF out COAX and Optical, as well as an HDMI, DVI-I, and S-Video out. Medion has even included a wireless mouse and keyboard to the mix, allowing users to type freely.

     


    Click to enlarge

    Located on top of the case is an HDD bay designed for Medion’s HDDrive 2 Go Ultraspeed hard drive, which, as we said in one of our reviews before, could have been better if they just switched it with a generic port to use with other ‘portable’ hard drives.

    The MD8390 is powered by an Intel Core 2 Quad Q6600 processor running at 2.4Ghz, has 2GB of RAM, and uses Nvidia’s Geforce 8600 GS graphics card (256MB). It runs on Windows Vista Home Premium with Service Pack 1 pre-installed, saving users hundreds of megabytes on Vista downloads and updates.

    Medion has also pre-installed a Bullguard Internet Security Package (with 90-day update), Google desktop, Microsoft Office 2007 (60-day trial), Microsoft Works, Nero 8 Essentials (BackItUp 3, Burning ROM, ControlCenter, CoverDesigner, Express, MediaHome, Recode, ShowTime, StartSmart, Vision, and WaveEditor), and Ulead PhotoImpact12 on the MD8390.

     

    The MD8390 comes with an HDMI-out port that allows a user to connect the PC to any HD LCD or plasma screen and can display images to a resolution of up to 1920 x 1080. A DVI-I port is also available, should the monitor does not have any available HDMI port.

    A multi-format DVD/CD burner is also included, just in case users would want to burn files or backup data.

    The Intel Core 2 Quad processor found in the new Medion MD8390 workstation deliver a lot of processing grunt and use a lot less power. And with an RRP of $999, this is an unbelievable value for money. The MD8390 will hit Aldi stores on the 14th of August and comes with a two year warranty and a 60-day money back guarantee.

    See page over for full product specifications and final rating.

     

    Medion Akoya MD8390 Product Specifications:

    – Intel Core 2 Quad processor Q6600: 2.40 GHz, 8 MB L2 CACHE, 1066 MHz FSB
    – NVIDIA Geforce 8600 GS: 256 MB DDR2 SDRAM, DirectX 10 and HDCP support
    – 500GB hard drive
    – 2048 MB DDR2 SDRAM with 667 MHz at 64 Bit, Dual Channel Memory
    – Multiformat DVD/CD burner
    – Integrated Wireless LAN IEEE 802.11n draft
    – Network controller Ethernet LAN 10/100 Mbit/s on board
    – 8 Channel High Definition Audio

    Front connections:
    – 2 x USB 2.0
    – 1 x Firewire
    – 1 x Microphone
    – 1 x Headphone
    – Integrated USB 2.0 Flash memory card reader, reads and writes most flash memory cards

    Rear connections:
    – 2 x PS/2
    – 6 x USB 2.0
    – 1 x COM port
    – 1 x Firewire
    – 1 x LAN (RJ45)
    – 1 x Line-in
    – 1 x Front line-out
    – 1 x Back surround line-out
    – 1 x Side surround line-out
    – 1 x Centre/subwoofer line-out
    – 1 x S/PDIF out COAX
    – 1 x S/PDIF out Optical

    Video / TV connections:
    – 1 x DVI-I (incl. adaptor for D-Sub)
    – 1 x HDMI
    – 1 x TV out

    Software package include:
    – Windows Vista Home Premium with SP1
    – Nero 8
    – Microsoft Works 9
    – Microsoft Office Home and Student Edition Trial (60 day test version)
    – BullGuard Internet Security Package

    Accessories Included:
    – Wireless keyboard
    – Wireless Mouse

    ————————————
    Medion Akoya MD8390 | $999 |  | www.aldi.com.au

    For: Quad core processor; Noteworthy specs; Abundance of ports; HDMI out; Value for money
    Against: Better if Medion added more RAM to make the unit run faster
    Conclusion: A workstation well-worth your money

    New D-Link Surveillance Camera With 10x Optical Zoom

    D-Link has announced a new Wireless N Pan/Tilt/Zoom Network Surveillance Camera with 10x optical zoom which can be accessed from any mobile phone or computer.


    Click to enlarge

    The DCS-5635 comes with a high-speed motorised pan, tilt and optical/digital zoom for extensive monitoring and object tracking. Its 10x optical zoom lens claims to deliver the level of detail necessary to identify faces, license plate numbers and other important details.

    The DCS-5635 also provides support for 3GPP Mobile Surveillance — allowing the user to view a live video feed from a compatible Internet-ready mobile phone or PDA with a 3GPP player installed — for on-the-go monitoring. To maximise bandwidth efficiency and improve image quality, it supports real-time video compression in MJPEG, MPEG-4, and H.264 formats. 
    “Users can sign up to a free Dynamic DNS service on the web to assign a name and domain to the camera to remotely access it without its IP address. 2-way audio with a built-in microphone and audio-out port is also included to communicate with anyone in close proximity,” said the company. 
    Offering both Ethernet and 802.11n wireless interfaces the DCS-5635 supports WEP and WPA-PSK/TKIP for establishing secure connections to a wireless network. 
    This new network camera also offers an auto-start motion detector that can be configured, for example, to start recording and send an email alert when triggered. It can be configured to record video to a connected PC or network attached storage device when motion is detected or it can be scheduled to record at certain times throughout the day. 
    The DCS-5635 Wireless N Pan/Tilt/Zoom Network Surveillance Camera is available now for $1398.

    Samsung Launches Tough Phone

    Samsung has just released a tough mobile phone for users who want a phone that is resistant to water, dust, and shock.

    The M110 deatures a ruggedized shell and is guaranteed to survive harsh conditions like ‘coal mines and extreme sporting environments’ with its IP54 international certification. Its rubber shell ensures acts as a buffer to absorb shock, while its LCD cover can withstand scratches and scrapes.

    It also features big elevated buttons, a flashlight, and a hiking style clip which allows for the handset to be attached to a belt or bag.

    Samsung M110 Product Specifications:

    Network: Dual-Band (900/1800 MHz)
    Operating Details: Native Operating System
    Form: Rubberised bar phone
    Resistance to Water and Dust: IP45 Rating
    Features: Inbuilt flashlight, FM Radio, VGA Camera with flash and night mode
    Display: 128 x 128 pixel resolution
    Dimensions: 109 x 48 x 17.9mm
    Weight: 95g
    Talk Time: Up to 8 hours
    Standby Time: Up to 400 hours

    The Samsung M110 is available now for $199 (Pre-paid).

    See: www.samsung.com/au

    Shape Up or Else: ACCC Warns Telcos

    ACCC has issued a warning to the telecommunications industry, saying that it must raise its standards in its treatment of consumers or risk increased scrutiny and action.

    ACCC Chairman, Mr. Graeme Samuel said the ACCC expects carriers to close off access to their mobile networks for rogue operators.

    “Problems such as misleading advertising, unfair contracts and deceptive mobile phone competitions have been allowed to proliferate by service providers, publishers and carriers, who have turned a blind eye while taking a slice of the profits. It is no longer acceptable for carriers to wash their hands of responsibility as operators use their networks to entrap phone company customers with unwanted, expensive and difficult to unwind subscription services,” says Samuel.

    “If all carriers do not exhibit a responsible attitude to closing down rogue operators, they must expect the ACCC to pursue remedies available to it under the Trade Practices Act. Consumer protection issues in telecommunications consistently ranked number one as the sectors most complained about to the ACCC Infocentre, with more than 4,000 complaints a year.”

    The ACCC consistently received complaints about mobile premium services, primarily related to unsolicited services and billing, with about half alleging consumers had received premium services without agreement.

     

    Other concerns included advertising practices; consumers not understanding contracts, including inadvertently signing up to a subscription service; and difficulties with unsubscribing and the complaints handling process.

    “The ACCC is drawing a line in the sand – we’re saying to the poor performers, and there are many of them, mend your ways.”

    A particular concern was the targeting of readers of youth magazines by mobile premium service providers.  He warned the ACCC was prepared to take on publishers for running advertisements which they knew to be misleading or deceptive.

    “Similarly, the ACCC is firmly of the view, that companies which advertising plans as ‘unlimited’ should be very cautious when using such terms. To avoid misleading consumers, any qualifications to ‘unlimited’ calls or SMS messages must be clearly stated and not so significant that they negate the overall impression of the ad,” says Samuel.

    The ACCC also encouraged consumers to make sure they fully understood the terms and conditions of their contracts.

    HTC Desire Available Today

    Telstra announced that the HTC Desire is now available to its customers. According to the company, it is released a week ahead of schedule due to strong consumer interest.

    The Desire runs on Google’s latest Android operating system and will utilise Telstra’s Next G network. Read our full review of the Desire here.

    Telstra’s Executive Director of Mobility Products, Ross Fielding said, “In response to massive interest from Australian consumers, Telstra has moved the launch of HTC Desire forward by almost a week to today. The accelerated launch means Australians will be the first in Asia-Pacific to experience this breakthrough smartphone.”

    “Telstra’s flagship [T]life stores in Sydney, Melbourne and Perth will be the first to stock the new smartphone with Telstra stores across Australia receiving deliveries by the end of the week,” added Fielding.

    Customers can also purchase the smartphone immediately online at Telstra.com.au, while those who pre-registered their interest in HTC Desire were contacted to ensure that they are amongst the first to be offered the smartphone.

    “We are also pleased to announce that HTC Desire will now be exclusive to Telstra for six months – a three month extension on our previous arrangement,”  continued Fielding.

    HTC Desire will be available to purchase online from today or initially from three [T]Life stores:
    ·    [T]Life Sydney – 400 George Street Sydney, NSW, 2000.
    ·    [T]Life Melbourne – 246 Bourke Street (Cnr Swanston & Bourke) Melbourne, VIC, 3000.
    ·    [T]Life Perth – 667-669 Hay Street Mall, Perth, WA, 6000.

    Telstra stores and dealers across Australia will receive deliveries of the HTC Desire progressively through the week with most stores expected to have stock by Friday ahead of the long weekend.

    HTC Desire will be available on a range of plans including for $0 on Telstra’s $60 consumer Phone Plan for 24 months (minimum total price $1440) or $0 upfront on a $85 Ultimate plan for 24 months including 150 MB data (minimum cost $2040), or can be purchased outright with a RRP of $779. 

    Acer Unveils One Ultraportable Netbook

    Acer has just joined the ultraportable notebook bandwagon as it launches its Aspire One. This 8.9-inch netbook is powered by an Intel Atom processor, weighs less than a kilogram, and claims to have a battery life of seven hours.


    Click to enlarge
    Acer’s Aspire One: Sapphire Blue
    According to Acer, the One will be smaller than an average office diary (24 x 17 cm), has a full and easy to use software application suite, and will be available with Linpus Linux Line or Windows XP Home OS.

    Acer’s Senior Product Manager for the Oceanic Region, Henry Lee said, “Being productive while on the move, staying entertained and being able to connect and communicate with others is of great importance to our youth market. What Acer has designed is a Netbook that can be used as a mobile device where being small, fashionable, lightweight and having instant online access is paramount.”

    The Aspire One features an 8.9-inch CrystalBrite LED backlit display (resolution of 1024×600 pixels), CrystalEye webcam, and 802.11b/g WiFi built-in as standard for easy access to available wireless networks. Users can also choose to have 512MB or 1.5GB of memory, and even have two alternatives for data storage: a NAND flash module of 8GB or an 80GB internal HDD. The unit also comes with a 5-in-one memory card reader for easy file transfer between a memory card to the notebook.

    Available in four fashionable colours to suit the individual, Sapphire Blue, Seashell White, Coral Pink and Golden Brown, the Aspire One launches today with the first model netbook pre-installed with Linux at $599.00.

    See: www.acer.com.au

    Skype Now On Your HDTV

    Skype has partnered with LG and Panasonic and will offer Skype-enabled HDTVs in the coming months. According to the company, LG and Panasonic will offer specially-designed HD webcams that are optimized for Skype video calls as well as separate accessories that can be plugged into the televisions.

    The new HDTVs claims to deliver Skype features such as free Skype-to-Skype voice and video calls, calls to landline or mobile phones, the option to receive inbound calls via a user’s online Skype number, Skype voicemail, voice conference calls with up to 24 other parties, and even 720p HD video calls.

    Skype CEO, Josh Silverman said, “The popularity of Skype video calling has increased substantially in recent years with an average of 34 per cent of Skype-to-Skype calls now including video. For many people who are video calling on Skype, they have expressed a desire to communicate with their friends and family from somewhere comfortable, and preferably on a big screen. Logically, this led to the development of Skype embedded on HDTVs.”

    The Skype software will be embedded into Panasonic’s line of 2010 VIERA CAST-enabled HDTVs and LG’s 26 new LCD and plasma HDTVs with NetCast Entertainment Access. Both lines are expected to be available in mid-2010.

     

    In addition to this, Skype has announced that it will now have support for video calls on PCs in 720p high definition (HD). The latest version of Skype for Windows can deliver up to 720p HD-quality video calling at 1280 x 720 resolution, at up to 30 frames per second, giving individuals an even smoother and richer video calling experience.

    To make an HD video call, users will need a high-speed broadband connection, a new HD webcam, a PC with a 1.8 GHz processor and Skype 4.2 Beta for Windows.

    “With HD-quality Skype video calls, we can bring our users even closer to the ones they love through an even richer, more meaningful video calling experience. Imagine being able to see the sparkle of your grandchild’s eyes or the setting of your best friend’s engagement ring. Through the innovation of Skype’s engineers and our hardware partners, these scenarios are now possible without having to buy expensive equipment or software,” added Silverman.

    New HD webcams are due to arrive in early 2010.

    Efficient HP SMB Printers Launched

    Hewlett-Packard unveiled a new line of SMB printers and solutions that aim to drive productivity and increase efficiency.

    HP has revealed Smart Install, a quick and easy way for users to begin printing in as little as two minutes by simply connecting a netbook, notebook or desktop PC to the printer with a USB cable.

    New monochrome printers featuring HP Smart Install include the HP LaserJet Pro P1100 Printer series -the HP LaserJet Pro M1130/M1210 Multifunction Printer (MFP) series and the HP LaserJet Pro P1566/P1606dn Printer series.

    In addition, the company has also announced an Auto-On/Auto-Off technology that uses up to three times less energy than a device’s normal sleep mode. The company has also showed a new patented Optical Watermark technology called EzStampGuard that creates an authentication watermark stamp that can only be viewed with unique film keys.

    Finally, the company also said that SMBs can enjoy improved cost control, greater energy savings and reduced waste with EzPrintSaver, a cost management solution based on printer and user-based rules such as forced duplex printing.

     

    HP South Pacific’s Vice President Imaging and Printing, Richard Bailey said, “Today’s SMBs need to use their resources wisely, working smarter and faster to maintain their competitive edge as the economy recovers. HP, the long-time leader in LaserJet technology, offers SMBs an unrivaled opportunity to accelerate their growth through industry-first printing technologies and products that actually pay you back.”

    HP IPG’s new printer line-up include:

    • HP Color LaserJet Pro CP5225dn Printer – HP’s affordable A3 colour printer. (Starting from $2,899)
    • HP Scanjet Professional 1000 Mobile Scanner – HP’s portable scanner. (Starting from $295)
    • HP LaserJet Pro P1566 Printer – Fast mono printing that uses less energy with Instant-on and HP Auto-On/Auto-Off Technology. (Starting from $329)
    • HP LaserJet Pro P1102 Printer (Starting from $149)
    • HP LaserJet Pro P1102w Printer (Starting from $189)
    • HP LaserJet M1132 MFP – HP’s affordable 3-in-1laser multifunction printer (MFP) – smart, multifunctional, compact and easy to install. (Starting from $249)
    • HP LaserJet M1212nf MFP (Starting from $399)
    • HP Officejet 4500 All-in-One Series – HP’s most affordable flatbed inkjet all-in-one series for your business or home office needs. (Starting from $129)

    New Apple Mac Mini Revealed

    Apple has unveiled a new Mac mini that features up to twice the graphics performance, has a new HDMI port and SD card slot, in a compact aluminium enclosure.


    Click to enlarge

    The new Mac mini features a compact aluminium enclosure just 19.7 cm square and 3.6 cm thin. A new integrated power supply eliminates the need for an external power adapter, while a removable panel underneath provides quick access for memory expansion.

    It includes an NVIDIA GeForce 320M graphics processor that claims to deliver up to twice the graphics performance of its predecessor. This means that the Mac mini is ideal for graphics intensive applications or visually rich games. Mac mini comes with Mac OS X Snow Leopard, iLife, and comes standard with a 2.4 GHz Intel Core 2 Duo processor, 320GB hard and 2GB of RAM for $999.

    Apple’s Senior Vice President of Worldwide Product Marketing, Philip Schiller said, “The sleek, aluminium Mac mini packs great features, versatility and value into an elegant, amazingly compact design. With twice the graphics performance, HDMI support and industry-leading energy efficiency, customers are going to love the new Mac mini.”

    Apple is also offering a Mac mini with Mac OS X Snow Leopard Server that fulfils all the server needs of a workgroup or small business including email, calendar, file serving, Time Machine backup, Wiki Server, Podcast Producer and more.

    Mac mini with Mac OS X Snow Leopard Server uses less than 11W of power at idle, a fraction of the power consumed in comparison to typical entry-level tower servers. Mac mini with Mac OS X Snow Leopard Server is faster than before with a 2.66 GHz Intel Core 2 Duo processor, two 500GB hard drives now running at 7200 rpm, 4GB of RAM and supports unlimited clients for $1399.

    The new Mac mini is available today through the Apple Store, Apple’s retail stores and Apple Authorised Resellers.