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 42 of 116

    Smart Office

    Panasonic MD Talks Appliances, TVs & The BIG Issue

    As Panasonic invades the white goods market, Channel News caught up with MD Steve Rust to see how its going.


    Click to enlarge

    Panasonic is now a fully fledged white goods brand in OZ, flogging everything from bread makers, irons and rice cookers, to washing machines and 8 smart fridges.

    “Demand has been great to date” says Steve Rust, Managing Director, Panasonic Australia, but “it’s early days.”

    “We’ve sold out of inventory and there’s been good feedback from market” citing retailer Harvey Norman, whom Rust says is “selling well” on Pana’s new gear.

    Panasonic now has over 50 white goods models on the Aussie market. One out of every two Pana products sold worldwide is now white goods and outsells its Audio Visual category .

    And  the giant hopes to repeat the trend locally.

    So, what prompted the big change to irons and washing machines for a company best known for TVs and Blu-ray?

    “We had an imbalance in the business… there was too much reliance on AV and CE business and as we know its a tough business to be in…with very rapid price erosion and no growth in the past 2 to 3 years,” says Rust.

    This ‘imbalance’ forced Panasonic’s management team to take a “prudent” approach to the market at hand.

    It now has three key pillars to its business in OZ – AV, Appliances and Communication solutions for business, which is also doing nicely.

    Speaking of TVs, how’s that side of Pana’s business going?

    “Demand hasn’t grown as such but its greater than expected, however, we can’t get enough TVs to sell,” Rust says, citing issues on the supply-side from Japan.

     

    “We have to order three months in advance..but have more coming,” he adds.  This supply issue was one AV specialist Len Wallis cited last week in an interview with CN, saying he was unable to meet the huge demand for Pana large screens.

    “The market has settled this year and, its not as furious in terms of price erosion and demand for TV’s is sitting at around 3 million units per year,” says Rust.

    Despite the entry into appliances, Panasonic is still “very strong” in AV, and the DVD recorder market is “good for us”, which may have been fuelled by the Olympics. Pana’s home theatre market is also “chugging along quite well.”

    “The biggest issue in the AV market right now is the expanding amount of IP content and the seamless integration between IT and consumer electronics,” says Rust.

    “The amount of IP content is expanding rapidly and is now provided in a way that is highly accessible to consumers.”

    Streaming services such as Spotify, JB HiFi Now, QuickFlix and others means the days of downloading content from a PC or using just iTunes are well over.

    On the appliance side, power consumtion is also becoming more and more important as electricity prices go up, but adds Pansonic’s Econavi power saving technology inbuilt into its appliances including washing machines deals with this issue very well.

    Panasonic Australia also launched a slew of cameras last week – everything from a basic compact LX7 through to high end mirrorless cameras and Rust was “very pleased with the launch” and the response so far. 

    However, “there has been a general drop in demand for cameras due to the invasion of smartphones like iPhones, especially at the entry level.”

    In addition, there is now more and more competition from online operators overseas as well as competition from the high end.

    Online channels are “growing rapidly,” says Rust, adding its not just foreign e-tailers in play – there’s is a lot of competition locally between the likes of Appliances Online and JB Hi-Fi.

    But it doesn’t mean the end of bricks and mortar just yet, and Rust says he is “confident they’ll always be room for the instore experience.”

    “Some consumers love the convenience of online but there will always be plenty who want to go instore for the product experience – to get the look and feel, talk to the storeperson and so on.”

    However, Panasonic’s MD questions the future success of international e-tailers, as issues like after-sales services issues come to the fore.

     

    “There are some questions about service in Australia for a camera that bought, say, in the US,” and adds “consumers may not be comfortable buying international e-tailers in the future.”

    “We are working with online partners including Appliances Online and are keeping an eye on other pure online retailers,” says Rust, adding Pana is being selective on choosing retail partners.

    Afer sales service is an issue the brand is particularly concerned with and “we want consumers to have a good experience when they buy a product and ensure retailers have good return capabilities.”

    However, he admits bricks and mortar retail in the future may be a bit different from today, and predicts there definitely more changes to come.

    Business Confidence Rises Sharply: NAB

    Business confidence sharp jump in December, but retail confidence still “poor”
    Australian business confidence improved considerably in December, from -9 in November to 3 last month, after deteriorating to its weakest level since 2009 in November, Nab’s Monthly Business Survey – December confirmed yesterday.

    Labour costs rose last month but remained contained, while product price inflation moderated slightly and retail price growth remained soft, up from -0.2 to 0.4, according to the survey.

    Confidence improved across all states in December, the Nab survey also found. 

    Better external sentiment (temporary avoidance of the US ‘fiscal cliff’), strengthening in Chinese data and lower rates have all helped boost business confidence locally, as well as RBA rate cut in December, NAB said yesterday.

    However, it may be a reflection of hopes of a better Christmas trading period and further upturn in 2013, as voiced by many retailers that have spoken to Channel News. 

    The most notable turnaround was in WA and Queensland where unsurprisingly, confidence was strongest and NSW, which may reflect better data out of China pointing to continued commodities demand over the year ahead

    However, it most subdued in Victoria and confidence improved solidly in Tasmania.

    But despite confidence surge, forward indicators in retail, as well as wholesale and manufacturing remain poor – with poor forward orders; credit demand at record low levels; and capital expenditure at depressed levels, says Nab.

     

    This point to a further slowing in Q1 and Nab are predicting growth of only 2% this year, bad news for retailers hoping 2013 would be see a resurgence after a flat 2012.

    Overall, the Nab survey implies underlying demand and GDP growth in the March quarter of around 2.25% and 2.75% respectively – a further slowing in growth from already below trend rates.

    However, its not all bad news. Nab also says it expect three rate cuts starting in February.

    Coming Soon…Quickflix To Hit Xbox

    First Panasonic, now Xbox is to be Quickflix-ed.


    Click to enlarge

    However, although Pana Blu-rays are in the bag, Quickflix streaming to Xbox service is not a done deal just yet, a Quickflix spokesperson told SmartHouse.

    Although the deal with Xbox is still not finalised, the Aussie-owned company is hopeful the service will go live sometime “in the next quarter,” so could be here by September/ October time.

    Final negotiations with Microsoft are still underway, the spokesperson confirmed.

    This is despite the service first flagged by Quickflix in April last.

    The Quickflix “unlimited” movie service  would stream TV and move content exclusive to Australia and New Zealand XBox Gold members for a “low fee.”

    Gamers will soon be able to watch Quickflix movies on their Xbox console and will include titles from Warner Bros, Sony, NBC Universal, MGM, Lakeshore and Pinnacle Films, meaning anything from ‘A Streetcar Named Desire’ to Johnny Depp’s new flick ‘Dark Shadows’ straight on your Xbox.

    And TV series from the BBC, ITV and HBO, maker of hits like The Sopranos, Boardwalk Empire, Game of Thrones, can also be streamed to the Microsoft console.

    Quickflix already streams to Xbox-rival Sony PlayStyation, tablets, Apple Macs, smartphones and smart TVs including Samsung, as recently announced.

    There is also set to be an official launch of Quickflix on Xbox, but we’ll let you know more as soon as we get word.

    Ex-Apple Designer: ‘I Can’t Tell Difference Between iPhone & Samsung Galaxy’

    Day 4: Samsung V Apple: What’s the difference between an iPhone and Samsung Galaxy?


    Click to enlarge
    What’s the difference between these two phones?

    Graphics guru Susan Kare can barely tell.

     In fact, they’re “confusingly similar,” she told a US court yesterday.

     Kare made the admission as the massive Apple V Samsung trial continues in California’s District court, where Apple is accusing Samsung of stealing its unique design technology and claiming $2.5 billion in damages.

    Apple called in graphics guru Susan Kare, who worked on Apple’s original graphics for the Mac in the eighties, as an expert witness to prove its argument that its rival indeed did copy Apple unique design technology, reports WSJ who were present at the trial.

    “I think of myself as someone who’s pretty granular about looking at graphics, and mistook one for the other,” Kare told the court, admitting mistaking Samsung’s Galaxy smartphone for an iPhone when she picked it up off a table.

    “In addition to the analysis, I personally had the experience of being confused.”

    The former Apple designer examined 11 Samsung smartphones in all to compare possible similarities to an Apple device and found:

    “the overall visual impression on all of these screens — compared each one by one — compared to the screenshot from the iPhone 3G, were confusingly similar.”

    Kare reckons Samsung home icons on the user interface screen of Captivate, Epic 4G and Galaxy S 4G screens all infringe Apple patents and the look and feel of its app icon design used on iPhone.

    Samsung attorney Charles Verhoeven wasn’t taking the witness claims lying down, however, and presented the two competing devices side by side before the court, claiming there was two extra steps a consumer would have to go through to hit the UI and icons Kare claims are “confusingly similar” to the iPhone.

    Verhoeven booted up the Galaxy and up appeared the Samsung logo, followed by an Android ad and Google’s search bar.

    Only after these steps could a consumer go the UI apparently similar to iPhone, thus he argued consumers would find it hard to confuse the two devices.

    Samsung attorney also pointed to Samsung “Fascinate” smartphone, doesn’t use the familiar rounded-square images as per iPhone.

     

    “It’s not 100% different,” Kare said when quizzed about the similarities between the two devices.

    She also admitted she had not examined the functionality of the competing devices but rather the look and feel.

    Apple also called in another witness, Peter Bressler, yesterday who told the court he had examined iPhone design patent and found that Samsung’s products most defintely infringed Apple’s unique technology.

    It also looks like Judge Lucy Koh is getting increasingly frustrated with both sides in the case first filed by Apple in 2010 as their respective lawyers argued over which version of their branded smartphones would be used in evidence.

    “How many versions and revisions of these phones are produced?” she said. “Give me a break!”

    NBN To Hit Cairns

    First Tas, NSW, now QLD is to get the NBN treatment.


    Click to enlarge

    Several northern Qld areas near Cairns will be among the first areas to get the National Broadband Network’s  fixed wireless service, which gives speeds of “up to” 100Mbps (eight times faster than ADSL).

    The fibre rollout in Cairns’ metro area is scheduled to start shortly and up to 5,000 homes and businesses will be switched on to NBN in stages starting mid 2013, Minister for Broadband, confirmed.

    These areas include Aurukun Shire Council, Cairns Regional Council, Cook Shire Council, Tablelands Regional Council and Yarrabah Aboriginal Shire Council.

    However, high speed broadband is not a done deal just yet , it seems, with all the NBN Co yet to lodge planning applications for towers in all five of the aforementioned local councils.

    Last week, it emerged a numbner of councils in Victoria rejected NBN Co tower applications due to visibility impact  issues.

    Read: NBN Red-Faced After Vic Rejection

    For those living outside the fibre and fixed wireless footprints, fast broadband will be available via satellite.

    “For too long, people living in regional and rural Australia have had to put up with slow, unreliable internet connections – if they could get a connection at all, Minister Conroy said.

    “Through the NBN, the government is also delivering uniform national wholesale pricing. This means people living in and around Cairns will pay the same prices for NBN services as people in Brisbane, Sydney and Melbourne.”

    Queensland Senator Jan McLucas said it was “fantastic” that a number of Far North communities, including some on Cape York, will soon have access to fast broadband service.

     

    “This is fantastic news for the Far North.The NBN will change the way we live and work here in Far North Queensland and I am very excited by the progress we’ll see on the ground in the next 12 months.”

    The Gillard Government say it is prioritising regional and rural Australia for the rollout of the NBN.

    What IS Apple Ginormous $97BN Plan?

    Apple are set to announce a grand plan for its ginormous $97bn cash kitty today.
    “Tim Cook, Apple’s CEO, and Peter Oppenheimer, Apple’s CFO, will host a conference call to announce the outcome of the Company’s discussions concerning its cash balance,” Cupertino said yesterday.

    The surprise cash plan-of-action announcement will take place Monday, March 19 at 9 a.m. Pacific Daylight Time in the US.

    The billion dollar question on everybody’s lips was what Cupertino planned to do with a cash pile of close to $100bn ($97.6bn to be precise), announced in late January made up of cash reserves, investments and other interests.

    Apple also recently announced first fiscal quarter 2012 net profit of a whopping $13.1bn. The cash reserves are believed to make Apple richer than the US government and certainly one of the most valuable companies in the world. 

    “We continue to be very disciplined with the cash and are not letting it burn a hole in our pocket,” Apple’s top money man, Peter Oppenheimer said, following January’s revelation.

    Analysts expect the tech darling to consider a dividend or share buyback meaning Apple shareholders could be in for a nice surprise with the company not having paid a dividend since 2002 (thanks to Steve Jobs).

    Issuing a dividend could lure even more investors into its den, although it appears there’s no shortage of Apple shareholder wanabees with share price topping the $600 mark for the first time in history late last week after launch of new iPad.

    On the subject of dividends, Cook has said: “I have said since becoming CEO that I am not religious about this.”

    “We’re in very active discussions at the board level about what we’re going to do with our money.”

    Read: Hey Apple, How WILL You Spend $100Bn?

    And this record $600.01 share price comes less than 5 weeks after Cupertino’s shares hit the $500 milestone.

    Whatever the plan is, Apple won’t be losing the plot and going on a mad spending spree, Chief Cook also previously warned:

    “We spend our money like it’s our last penny. I think that shareholders want that. We’re not going to have a toga party or do something outlandish.”

     

    But with profits like this the skies the limit.

    The only purchase it has made of late was an Israeli flash memory company, which Cupertino is believed to have paid between $400 million and $500m for.

    “Apple will not be providing an update on the current quarter nor will any topics be discussed other than cash,” yesterday’s announcement also stated.

    @facebook Backlash On e-Mail Invasion

    Anger after millions are given a public @facebook e-mail address – without being told.


    Click to enlarge

    There is a distinct Facebook backlash in the air after the network forced e-mail address on all 901 million plus users – whether they like it or not.

    The change occurred over the weekend as Facebook community took to rival Twitter to vent their anger and its clear they’re not happy campers :

    “FACEBOOK USERS! FB took the liberty to change our default emails this morning for ones that they have created for each user! RT and CHANGE!” one incensed Facebook user wrote.

    “@Facebook stop trying to make ‘@facebook.com’ emails happen, it is NOT going to happen!” another angry Facebooker tweeted.

    Read: Look Out Gmail: @facebook.com Hits 900M Inboxes

    The change means you can’t delete your @facebook address from your acount but you can still keep your other Gmail or Hotmail addresses.

    However, you can hide you Facebook address from public view if you dont want FB e-mails (but its pretty obvious..your user name followed by @facebook.com).

    “We basically defaulted to show your Facebook address as we rolled this out, just to keep it consistent for everyone,”Meredith Chin, Facebook’s manager of product communications, told CNN.

     

    But it appears to be a clever way of Facebook trying to increase the amount of time users spend on the social network site, which has slowed in user growth, according to comScore (although lets face it, 901 million users is no mean feat).

    Facebook first launched emails in 2010, but it was optional whether users signed up for yet another email address or not.

    Now its just been forced upon the community, without even informing users. The address have not been rolled out to all 901 million Facebookers but will be in the coming weeks.

    Is Apple Killing Retail?

    As the iPhone 5 is launched, is the expanding Apple Store empire killing retailers?


    Click to enlarge

    As retailers globally built up the Apple brand to the most valuable and loved tech company it is today, is Cupertino now taking over the show?

    Ahead of the iPhone 5 launch last week, Apple has a total of 17 stores in Australia (249 in the US) opening up new locations in Canberra’s CBD and its first in Perth, and is said to be opening another in Melbourne soon.

    Now it has emerged Apple gave retailers limited stock of the iPhone 5, with the largest retailer in the US, Best Buy, just getting 10 devices at some stores, and thus dehabilitated in its bid to meet consumer demand, reports the Wall Street Journal.

    “While Apple’s own stores appeared to be selling the new device in large numbers, other retail chains that offered the device had limited quantities from the outset,” sources told the Journal.

    “Shortages have hit Apple partners in the past, but the disparity seemed more pronounced this time.”

    Apple confirmed it has sold out completely of the iPhone 5 with Tim Cook insisting “stores continue to receive iPhone 5 shipments regularly and customers can continue to order online and receive an estimated delivery date.”

    A Vodafone spokesperson told SmartHouse last week it would work with Apple to get new stock if it did sell out of initial iPhone stock.

    Telstra did sell out of pre-sale stock but declined to say how much stock it was given by Cuperinto in the first place, saying it was “working on getting more in.” 

    Telcos were given a certain amount of pre-sale and retail stock, although the quantities Apple gave retail partners are unknown with the secretive company demanding such information be kept confidential and Apple refusing to give away such figures.

    A Citi report recently noted Apple Stores in Australia generate “sales of more than $35 million per store,” which “is in stark contrast to Dick Smith, which has sales per store of $3-$5 million.”

    Citi analyst Craig Woolford also noted JB Hi-Fi in particular was at risk from Apple’s Store empire since 20% of its sales are iOS devices and is becoming ever more reliant on Computers and TVs, rather than software and movie titles.

    However, this is a load of nonsense, says JB Hi-Fi Marketing Manager, Scott Browning, who rejects the notion that the Apple Store poses any kind of threat to his company, and reckons the analysts view is a “little strange,” he told Channel News.

    “Our growth is in line with Apple Stores” Browning insists, adding its 20% figure is “relatively sensible”, given Apple’s domination of consumer electronics with iPhones, iPads and Macs.

    It also shows “we are universal resellers and successfully sell a lot of other brands including Samsung, Microsoft based PCs and others. The fact is, Apple remains a successful business and its a transparent company, so no-one has a market advantage.”

    So is JB Hi-Fi worried about Apple expanding retail empire?

    Apple Stores located nearby actually helps JB stores sell more iOS gear, says Browning, and “our view is they actually help our stores. A lot of people are still working out what they want to buy and the Apple central stores facilitates this.”

    Cupertino’s model is to assist resellers and provide a lot of support, but is very dependent on its satellite sellers,  says Browning.

    In fact, Apple “satellite resellers,” including the likes of JB, Big W and Harvey Norman, outsell Apple’s own stores sales by a mile. Apple has less than 20 retail stores, which pales in comparison with the 155 JB Hi-fi’s and 177 Harvey Norman outlets in major towns and cities throughout Oz.

    The Apple model is about high volume, high rent locations and not spending a lot of money on advertising. The Cupertino giant  uses its stores as a testing ground for selling and merchandising techniques, which it then passes on to resellers, says Browning.

     

    Apple’s flagship stores are centralised, confined to CBDs and are a showcase for iOS products, curating the brand and its products.

    The Apple price model is also transparent, says JB Hi-Fi’s head of marketing, meaning prices are consistent throughout Apple Stores and resellers, so there’s no major gain for a consumer to buy from an Apple Store as opposed to a reseller.

    Browning also says Apple does not inform the Melbourne based company, which has 155 stores scattered in Australia, about its retail plans.

    There are now 17 Apple Stores in Oz, with another believed to be opening in Melbourne’s North West soon.

    Judge: Is Apple “Smoking Crack”?

    Crack smoking, secret emails. Firm denials.
    Welcome to Apple V Samsung.

    Judge Lucy Koh is not happy. The US Judge presiding in the battle of the patents between Apple and Samsung is so infuriated she accused Apple’s lawyer of “smoking crack” as he called more witnesses – possibly as many as 29 in all –  to the stand.

    Judge Koh accused Apple’s lawyer of “smoking crack” in the US court yesterday as the long running trial gets heated.

    “You’re Honor, I’m not smoking crack,” Apple counsel replied as court attendee Nick Wingfield reported on Twitter.

    The case comes as Apple accuse Samsung of violating several patents, including its design, icons, pinch gestures and scroll features. They’re claiming $2.5bn in damages and a ban on the sale of all devices that allegedly violate its patents, including the Nexus, Samsung S II and Galaxy Tab.

    Samsung, in turn, accuse Apple of using several of its wireless patents and technology.

    Samsung too called several witnesses to take the stand, and although not as many as its Cupertino based foe, it has used up much of its allowed time to put its case before the Californian court. Both parties were alloted around 25 hours.

    On Wednesday, Samsung called one of its industrial designers as a witness, who firmly denied the company sought to copy the iPad when it was creating the Galaxy Tab 10.1, and insisted the Korean giant was creating a tablet device long before the iPad was first released in 2010, reports Guardian.

    “I really enjoy what I do as a designer,” the Samsung designer told the US court. “I am proud of what I do.”

    However, the court also heard how Google warned Samsung that its first Tab 10.1 device was too similar to Apple’s iPad.

    Apple lawyer presented emails before the court, which claims to show even Google – makers of the Android OS- believed the Tab 10.1 was too similar to Apple’s design.

    “Since it is too similar to Apple, make it noticeably different starting with the front side,” the Android creator told Samsung designers in 2010, it is alleged.

     

    However, Samsung designer Kim Jin Soo denied any knowledge of the emails in court.

    As the case reaches its conclusion, Judge Koh has called on the tech giants to make peace, saying “it’s time for peace” but noted the “risks here for both sides.”

    The jury is currently hearing rebuttal witness evidence and Judge Koh wants deliberations to kick off August 21.

    Apple Nab Samsung In US As Lawyer Fails To ‘Spot The Difference’

    Able to tell the difference between an iPad and Samsung Galaxy Tab? Samsung lawyers couldn’t. A US Judge has ruled Samsung Tabs 10.1 have infringed on Apple owned patents, although warned Apple still need to prove their case.
    This latest blow for Samsung Galaxy Tab maker comes as an Australian court upheld an interim ban on its Tab 10.1, meaning the android Honeycomb tab is highly unlikely to be sold this side of Christmas.

    Apple are looking to ban not only the Tab 10.1 in the US but also its Galaxy S II smartphone which is pending release there.

    One of the critical deciders which appeared to favour Apple was when U.S. District Judge Lucy Koh held up both Apple’s iPad and Samsung Galaxy Tab, and asked Samsung legal counsel Kathleen Sullivan, a lawyer representing Samsung, to spot the difference and identify the iPad from the Galaxy at San Jose, California federal court, Thursday.


    Click to enlarge

    According to Reuters, she could not do it from a distance of about 10 feet away. “Not at this distance, your honor,” Sullivan replied.

    “Can any of Samsung’s lawyers tell me which one is Samsung and which one is Apple?” Judge Koh asked.

    A Samsung lawyer then did identify which was an iPad and a Galaxy, moments later.

    “It took a long time to make that distinction,” Judge Koh noted.

    Apple are claiming Samsung infringe at least three design patents, similar to the case made before an Australian court last week.

    However, its not looking good for Samsung –  the Judge ‘frequently’ remarked on the similarity between the rival tabs.

    And she did agree Samsung has infringed design patents, although appear to reject Apple claim on one of its other ‘ulility’ patents.

     

    However, the onus now is on Apple to prove the patents are valid under law.

    Samsung counsel are arguing it has raised enough “substantial questions” about the validity of patents in question to prove Apple has no case.

    However, a final decision on three other Apple design patents will be arrived at “fairly promptly” as US carriers including T Mobile and Verizon are siding with Samsung, arguing a ban on Galaxy S II will hit Christmas sales hard.

    After the hearing, Samsung spokesman Kim Titus rejected Apple’s case for a ban as “groundless.”

    However, Apple spokeswoman, Kristen Huguet, maintains Samsung are copy cats: “It’s no coincidence that Samsung’s latest products look a lot like the iPhone and iPad … This kind of blatant copying is wrong, and we need to protect Apple’s intellectual property when companies steal our ideas.”

    And it looks like other Android devices in Australia could also be in danger of being banned, following last weeks ruling by Judge Bennett,  where the ban on Galaxy Tab 10.1 was upheld until a full hearing on November 1.

    According to Foss Patents expert, Florian Mueller, after Justice Bennett’s decision it is possible “no company in the industry be able to launch any new Android-based touchscreen product in Australia anytime soon without incurring a high risk of another interim injunction

    Read Analyst Predicts Android Doom & Gloom After Apple Samsung Case

    But it wasn’t all bad news for Samsung, in Australia at least.

     

    Justice Amanda Bennett rejected Apple’s bid to vet any new Samsung tablets before they go on sale here on Friday last, meaning that although the Galaxy Tab 10.1 is banned for the interim, its 7.7 inch device could be released here instead.

    Read Sorry Apple: OZ Samsung 7.7″ Tab Likely After Ruling