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; } } Oonagh Reidy, Author at Smart Office - Page 84 of 116

    Smart Office

    Amazon Kindle II To “Light Up”?

    Amazon Kindle to strike again… this time with a front light.


    Shining light: Knidle eReader with front lamp?

    The Amazon whizzes are said to be tapping away on a new Kindle model which should be released by July, sources who bore witness to the new eReader told Reuters.

    The new ereader will have a novel front light meaning readers will no longer need a lamp light (or attempt to read in the dark).

    And as per previous Kindles it will run E Ink’s display technology and there will be 3G and WiFi models on sale.

     And Amazon are also getting set to release a new Kindle Fire tablet, according to the source – expected to be a larger 8.9 inches model  – compared to current 7″ Fire, although the tab which sold like hot cakes in the US for $199 is not yet available in Oz.

    This news comes as rumour mill is heaving with stories that Apple are planning to release a cut price 7″  iPad to compete with the low end niche carved out by Kindle Fire.

    Woolies Fly & Collect “Revolution”

    Going to the supermarket is soo old school.

    Get your shopping when you step off a plane.  

    Woolworths launched a revolutionary airport grocery collection service at Melbourne Airport this week, meaning shoppers no longer have to stop off at the supermarket on the way home after a long journey. 

    The ‘click&collect’ service allows customers to pre-order their groceries before they get on a place, and collect their groceries after they step off the plane in Melbourne. 
    Woolies customers can order their groceries up to seven days in advance online or via the Woolies mobile app. However, we can’t help but wonder whether chilled items like milk and meat will last, say, if a flight is delayed. 
    The goods are pick up groceries from staff at the Woolworths click&collect building at the Melbourne Airport terminal forecourt. Collection times between 9am – 9pm, seven days a week. 
    No word yet if the supermarket giant has plans to move beyond Victoria. 

    “[Woolies] customers are increasingly embracing online and mobile platforms as a convenient and hassle free way to shop,” said Kate Langford, Head of Online Business Development, Woolworths Supermarkets. 

    “Melbourne Airport is the second busiest airport in the country and the Sydney to Melbourne route is the fourth busiest route in the world so we were excited to work with Melbourne Airport to launch this new service.” 

    The new service will also be handy for the 14,000+ people who work at the Melbourne Airport. 

    Woolies is going gung-ho online and in-app shopping with other click&collect options including from 130 supermarkets, and click&collect drive thru.

    Forget Facebook, Microsoft Nabs Yammer $1.2Bn

    Software giant buys the ‘Enterprise Social Network’

    Microsoft announced a definitive agreement to acquire Yammer, for $1.2 billion in cash.

    The deal was flagged several weeks ago, although a far higher price tag of $12bn was reported.

    Yammer allows instant messaging between employees, is a “private” social network and would be an important weapon against the might of messaging services from Google and even Facebook.

    Microsoft says it plans to “accelerate Yammer’s adoption alongside Microsoft SharePoint, Office 365, Microsoft Dynamics and Skype.”

    Yammer will continue to develop its standalone service and its commitment to cross-platform experiences, Microsoft said in a statement.

    Yammer will be absorbed by Microsoft’s Office Division, led by division President Kurt DelBene.

    “The acquisition of Yammer underscores our commitment to deliver technology that businesses need and people love,” said Steve Ballmer, CEO, Microsoft.

    “Yammer adds a best-in-class enterprise social networking service to Microsoft’s growing portfolio of complementary cloud services.”

    Launched in 2008, It currently has five million users in over 200,000 organisations in the three years (including 85%of the Fortune 500).

    Major corporate users include Deloitte, Ford, Nationwide, 7-Eleven, Orbitz Worldwide and Telefonica O2. And Yammer has a few things in common with Facebook – both the Enterprise and Network share the same first investor, Peter Thiel.

     

    “When we started Yammer four years ago, we set out to do something big, said David Sacks Yammer CEO, who says “joining Microsoft will accelerate that vision and give us access to the technologies, expertise and resources we’ll need to scale and innovate.”

    The acquisition is still subject to regulatory approval, however.

    Yammer was named “Innovative Application Software Company Under $100 Million to Watch,” by analysts IDC last year.

    On Net: TPG Profit Soar 40% As Users Flock To Cheap Broadband

    Net profit soar 40% as customers head to TPG. The ISP on a broadband high after adding almost 100K new users to its ‘on net’ broadband service and posting a 40% jump in profit after tax to $78.2 million.
    Group financial results announced yesterday for the year ended 31 July 2011 (“FY11”), painted a bright picture for the small ISP, which offers competitively priced ADSL, ADSL2+ and SHDSL broadband and domain hosting services.

    Earnings before tax, depreciation (EBITDA) also increased 37% to $234.0m – above company guidance range of $225m-$230m.

    “Strong organic subscriber growth” in consumer broadband led to a net increase of 59,000 subscribers comprising of  77,000 ‘On-Net’ users, offset by a decline in Off-Net customers.

    The ‘On-Net’ broadband and home phone bundle which costs $29 was also singled out as a major growth driver, adding a impressive 98,000 subscribers during the year.

    And the ASX listed ISP is also looking to the cloud announcing the completed purchase of IntraPower, whose “Trusted Cloud” will allow it offer cloud services to its growing subscriber base.

    PIPE Networks, its optic fibre business has also continued to grow “strongly” and contributed $57.2m to the 2011 profit results thanks to “strong revenue growth.”

    Its network rollout for the Vodafone Hutchison Australia contract, which will increase PIPE’s domestic fibre footprint by approximately 60%, is “on schedule,” the company said.

    Other financial highlights includes:  earnings per share increase of  33% to 10.1c per share, and strong cashflow enabled  bank debt to be slashed by $100m.

     

    TPG’s Board of Directors has declared a final FY11 dividend of 2.25 cents per share (fully franked), payable on 22 November bringing total FY11 dividends to 4.5 cents per share.

    However, the directors have invited shareholders to reinvest in the company through its “dividend reinvestment plan.”  

    Sony Slips $191M Loss As LCDs, PS3 Tumble

    Sony are counting its losses after the Japan earthquake as sales slump10%. The electronics giant has announced its results for the first quarter to June 30.


    Click to enlarge

    However, there wasn’t a lot of good news for the Bravia maker, whose net profit slumped into negative territory, 15.5bn yen or $191m, compared to a profit of 25.7bn yen the same period in 2010. 

    Overall, sales for Q1 of its fiscal year, covering the period April – June, slumped to 1,494.9 billion yen (U.S$ 8,456m), a drop of 10% compared to same quarter last year, which Sony blamed partly on knock on effect of the earthquake in March leading to decrease in consumer products (CPS) business, which includes gaming, audio and TV. 
    Sales in the key sector fell 17.9% year-on-year to 732.3 billion yen (US$9,040 m), blamed on falling LCD sales, poor markets in the U.S and Europe, and price competition in PC category. 
    Sales of its PlayStation 3 also went south, recording 1.8 million units sales in the period – a fall of 0.6m compared to a year ago. 

    However, LCD sales in Japan bucked the trend, jumping due to higher demand as the country moves to full digital broadcasting this month.  

    Video camera sales were also down due to “contraction” in the sector, it said. 
    Sony’s operating income decreased for the first quarter was 27.5 billion yen  or US$340m, which marked a shocking 59% drop (local currency), due to a dip in gross profit  and deteriorating cost of sales ratio. 

    Factors cited included the negative impact of the earthquake as well as the general “deterioration of the electronics business” Sony said today. It also blamed declining income on additional expenses associated with the hacking of its PlayStation network earlier this year. 

    Sony also incurred other “incremental charges” including those associated with the earthquake clean up of 5.3 billion yen (U.S.$66 million). These included restoration repairing of factory fixed assets damaged in addition to idle manufacturing capacity costs. 
    However, 1.3 billion yen (16 million U.S. dollars) of these charges has been offset by insurance claims “deemed probable” to be granted.  
    However, there is some light at the end of the tunnel, it seems. Business operations hit by the quake are recovering “faster than anticipated” in its May forecast. 
       

     

    Sony are also predicting lower LCD sales compared to the May forecast and more unfavorable foreign exchange rates, forcing it to cut forecast earnings for the full-year by 25% to 60bn yen, down from an expected 80bn yen. 
    The sales outlook is also gloomy for the remainder of the fiscal year for the Japanese giant, citing poor business environment. 

    As in its previous quarter, Sony cited production “issues” in some categories, constraints in its supply chain and lower production capacity due to damaged manufacturing equipment.  

    On the pictures front, Sony was saved by DVD releases including The Green Hornet, Battle: Los Angeles and Just Go With It, pushing sales 9.3% year-on-year to 144.4 billion yen or $1,7bn (23% increase in U.S.currency).

    Sony Music recorded sales of 109.6 billion yen or $1.3bn “reflecting strong sales of a number of key releases” including Adele’s 21, Beyonce’s 4, Foo Fighters’ Wasting Light and music from hit TV show Glee. 


    Phone sales for its business, Sony Ericisson, slumped 32.1% to 1.1 billion euros ($1.7bn) due to constrained components supply and a decline in basic feature phones shipped as consumers focus on smartphones.  

    To this end, SE has gone on an Android binge, releasing a slew of models this year, in a bid to play catch up with smartphone rivals like Apple and Samsung. 

     

    Losses before taxes of 43 million euros ($61m) was recorded for the quarter at the European phone giant. 





    Foxtel $46K Fine Dodgy “Sale” Ads

    Beware of the fine print: Pay TV giant forced to fork out $46,200 for “misleading” Christmas Sale ads.


    Click to enlarge

    The offending ads promoted Foxtel’s “Christmas Sale” which claimed users could get a TV subscription for $55 a month on a six-month contract.

    However, the Christmas Sale ads also contained a small asterisk with fine print terms and conditions beneath, which effectively locked customers into a year contract with the cost of the “deal” increasing to $77 per month after the 6 months – a $22 hike.

    The ads which ran nationally in November to December last were believed to be “misleading” and “false” and contravened  Australian Consumer Law, according to the consumer watchdog, the ACCC.

    Foxtel’s ad campaign, which ran on television, radio, newspaper and magazine, also online and in brochures, has now cost the TV giant $46,200 in infringement notice penalties paid to the Australian Competition and Consumer Commission.

    ACCC chairman Rod Sims warned companies “the inclusion of an asterisk or a fine print disclaimer does not remove the potential for a headline to be misleading.”

    “Companies must ensure that they do not use misleading headlines about the price and other key terms and conditions of the services being offered.

     

    “It is not enough for a company to try to correct a misleading headline using fine print text,” Sims added.

    The payment of an infringement notice penalty is not an admission of a contravention of the Australian Consumer Law, according the ACCC. 

    It’s On: Google Internet Music To “Access All Areas”

    Listen Up iTunes, Spotify: Google music streaming will access all areas

    And with millions of Android users – now miles ahead of rival iPhone (runs 60% of all smartphones globally) – it could be on the right track with Internet streaming service Google Play Music All Access

    “This is radio without rules. It’s as ‘leanback’ as you want to, or as interactive as you want to,” used across any Android device, declared Chris Yerga, Google’s engineering director at Google 6th annual Google I/O developer conference kicks off in San Francisco, yesterday. 

    Over 6,000 of Google faithfuls (developers) were in attendance as the tech giant unveiled a monthly music subscription service called Google Play Music All Access, new Maps and Chrome that speak to you. 

    Internet streaming service Google Play Music All Access has millions of songs that joins its Play store and music locker, according to Google blog. 

    But its not just iTunes, Spotify (priced at $6.99/$11.99), which has a massive market here in Australia that may also feel the pinch of Google streaming service that will be likely very soon on all Android hardware, smartphones, tablets and is hitting a “special” Samsung Galaxy S4 next month, which also comes with other Google updates. 
    You can create a radio station from any song or artist, browse recommendations from Google music team or explore by genre. Google Play Music lets you combine your G Music with your own tunes in one single library. 
    It’s $9.99 a month, and Google are letting doubters try it free for the first month. You can store 20,000 songs for free in the cloud. 
    A “special” Samsung Galaxy S4″ hitting US on June 26, will have Google Play Music All Access preloaded, available with no contract for $649. 
    Maps Redrawn 
    Google has also redrawn its Maps service making it “smarter”, customising maps for every user and draws tailored maps that highlights only the road and landmarks you need. 

    Search results are labelled directly on the map with brief place descriptions and icons that highlight local amenities (recommended by your Google+ friends, if you have any). 
    “Like a friend drawing you a map to her favourite restaurant, with only the roads and landmarks you need to get there, the new Google Maps instantly changes to highlight information that matters most” writes Bernhard Seefeld, Google Maps Product Management Director & Yatin Chawathe, Google Maps Engineering Director, via blog. 

    But Google Maps wants something back – your data. 

    “The more you interact with the map, the better it gets. When you set your Home and Work locations, star favourite places, write reviews and share with friends, Google Maps will build more useful maps with recommendations for places you might enjoy” (Ooh, we scent privacy issues). 
    It also now includes local business listings like restaurants, bars, information and ratings –  with help from Google Zagat ratings service.
     

    Planking, iPhone 5, Steve Jobs: 2011 Most Googled

    Aussies are looking for love. And Amy Winehouse, Adele, planking and an (as yet) unreleased iPhone 5. The video game Minecraft, the British Royal Wedding and the Rugby World Cup were also among the hot searches on Google this year.


    Click to enlarge

    The third most popular search in Oz was, in fact, Google.

    Love topped the ‘what is?’ list, suggesting we are a bit confused by the phenomena (or possibly just amused by the answer), along with planking, energy and depression also baffling us.

    “We’re either a very romantic or a very jaded bunch,” declared Google spokesperson, Mr Johnny Luu, referring to political topics like the Arab Apring and Libyan uprisings (No .2) being surpassed by Apple’s iPhone 5 (No. 1) on the ‘most searched’ lists.

    And of course, Australian’s are still “obsessed” by social networks Facebook and Twitter, says Luu.

    “What the top overall search list shows is Australians are as obsessed with social networking as ever, with Facebook and YouTube being the top overall searches.”

    Biggest Loser trainer Michelle Bridges was the only Aussie to make the top 10 fastest rising searches on people. 

    Steve Jobs and British singer Amy Winehouse also were among the most searched for celeb deaths in the past year outdoing the demise of Osama Bin Laden by miles.

    People often run to Google to check on a rumoured celeb death, with Jackie Chan and Hugh Hefner topping the list despite being still very much in the land of the living.

    And with the soaring popularity of cooking shows like MasterChef, recipes for macaroons, red velvet cupcakes and pork belly most searched for foods of the 2011.

     

    “The year-end Zeitgeist is a cultural barometer showing us what quickened our national heartbeat and drove our curiosity,” Luu added.

    Byron Bay, Hamilton Island, Blue Mountains were among the top travel spots that Australians searched for this year.

    Sorry Apple: OZ Samsung 7.7″ Tab Likely After Ruling

    Apple have just lost the right to prevent Samsung selling new Tabs in Australia, meaning a new Galaxy could be just days away. In a Sydney court today, Apple were seeking to prevent its tablet rival from launching any new device, while it awaits the outcome of the current case involving the Galaxy Tab 10.1, which Apple argues is a clone if its flagship, iPad 2.
    The sale of the Galaxy Tab 10.1 which was banned by Justice Amanda Bennett in court yesterday, after granting an interim injunction to Apple, meaning the device won’t go on sale at lest until the full trial hearing goes ahead, which is timetabled for November 1, Melbourne Cup day.

    Apple were also dealt a second blow of being prevented from vetting any Samsung Tab 10 days before it is launched here in Australia.

    Read Victory! Apple Win OZ Tab Battle, iPad 2 Reigns (For Now)

    This ruling from Justice Amanda Bennett means Samsung Galaxy 7.7 inch Tab, announced earlier this year at IFA trade show in Berlin (although prevented from being shown due to Apple slapping a ban) could be winging its way Down Under soon.


    Click to enlarge

    Samsung are likely to be desperate to fill the void in its tab line – due to the ban of its flagship ‘thinner and faster’ Tab 10.1, which was due for release here last month, until Apple began legal proceedings claiming several patent infingements.

    Samsung have lodged a counter lawsuit against Cupertino, claiming  it has violated some of its wireless technology patents.

    Lawyers for the iPad maker claimed Galaxy rivals could release the now banned Tab 10.1, under a different name.

    “Samsung says Galaxy Tab 10.1, we say any tablet device” Apple lawyers argued.

    “We know what may well come is another version of the tablet. It’s up to our friends as to how they name it, whether they call it the Galaxy Tab 10.1 or 10.2 or 10.1s or whatever it happens to be.”

    Samsung’s counsel rejected the arguments and claim another tab launch would be separate to the current device under patent claims, arguing the granting of such an order would put it at an unfair disadvantage as a competitor of Apple.

    “Your honour’s reasons dealt only with the 10.1 device … as a matter of principle your orders should only deal with the 10.1 device,” Samsung’s counsel said.

    “Why should Samsung be put in a different position to any other trader in the marketplace, which is to give advanced warning so as to confer some process of effective pre-approval in the hands of its competitor,”

     

    So, the Apple V Samsung tablet trial kicks off again next month, however, it is highly unlikely Australian consumers will see Galaxy Tab 10.1 this side of Christmas.

    However, a replacement device now seems imminent.

    Justice Bennett also offered to schedule hearings outside the Federal Court’s normal timetable today, possibly early next year in order to hurry up proceedings.

    Read Samsung Revenues Set To Be Hit After Judge Rules

    $5000+ Bill Shocks Rise

    A $5000 bill shock-er: there was a 70% jump in the numbers complaining about roaming charges in 2011-12

    The number of mobile users slapped with international roaming bills of $5000 or more is increasing, according to Telecommunications Ombudsman TIO Talk publication.

    There were 4100 such complaints in 2011-12 – and has doubled in the last 12 months to September 2012.

    And although there has been a drop in roaming disputes in recent months, a greater proportion are disputing bills of $5,000 or more.

    Consumers and telcos disputed over $8 million worth of mobile roaming bills in the last year.

    “Some consumers who travel overseas for business or leisure are returning to telephone bills that are more expensive than the trips themselves,” Ombudsman Simon Cohen warned.

    Here are some chief horror stories:

    One consumer requested a special plan to make calls during a nine-week holiday to Europe, but instead was slapped with a whopper bill for $148,000.

    Another was sent a bill for $38K while using the Internet on his phone aboard which he thought was connected to WiFi, while another had a $18,000 bill for international roaming.

    We made 193, 702 complaints to the Ombudsman last year, in total, with poor coverage and lack of information given by telcos also top bug bears.

    Read: $59 Plan: Biggest Bill Shock-er of All

    Victoria got a right throttling with most new complaints per capita (1.83 per 1,000 people), followed by South Australia, New South Wales, ACT Queensland, Western Australia, while Tasmanians and  NT residents made the least.

    The most complaints per capita were reported in Docklands in Melbourne and Sydney’s Parramatta.

    Most complaints (57%) made to the TIO are about mobile services, although this dropped by 3% in July-September.

    Coverage continues to be the biggest concern of mobile users, rising 4.2% in recent months and comes as Telstra 3G service in Melbourne experienced major issues.

    Complaints about customer service, complaint handling and billing have reduced but the challenge will be to keep up this positive trend over the summer months, when demand is high, said TIO.

    The continuing usage of smartphones and tablets is likely to increase international roaming usage, the report warns, and being fully informed about roaming charges before you travel is vital.

     

    Here are tips for avoiding high global roaming charges (courtesty of TIO):

    Before travelling overseas, we encourage consumers to contact their telco and make sure they are fully informed about all potential costs and charges of international roaming and other international telephone services.

     · Find out the costs of global roaming for voice and data services before using either service.

    · Ask whether your telco has products designed specifically for roaming, such as data roaming packs, as these may reduce your overall costs.

    · As when buying any product, ask questions to ensure you understand what you are agreeing to and the possible costs involved.

    · Even if you have used global roaming previously, it is still important to contact your provider as the costs can vary significantly between countries.

    · You can ask your telco to restrict your access to global roaming (if this was previously set up). Also find out how you can turn off global roaming and data settings on your phone.

    · To avoid international call charges for incoming calls, you can set an unconditional call diversion to voicemail before leaving Australia. This means that all incoming calls divert directly to voicemail and will remain within the Australian network. Your provider will be able to explain the remote retrieval process and costs to you.

    · If you incur a large roaming bill, you should contact your telco to discuss it and ask for more information about how it was incurred. If you believe the debt is not correct and you cannot resolve the issue with your provider, you can contact the TIO.