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

    Smart Office

    PC ‘Weak’ as Microsoft Admit ‘Post-PC’ World

    Global PC demand is falling as consumer lovingly embrace iPhone and tabs.

    Can Windows 8 save PC market?

    That’s according to Gartner analysts, who predict Worldwide PC shipments are to total 368 million units in 2012, a 4.4% jump on last year.

    However, Australian PC shipments are set to decline 2% this year, with desktops expected to drop 12%, although notebooks will rise 2%.

    However, this dreary forecast is set to reverse in 2013 as shipments are predicted to hit 400m by year end, according to the PC forecast just released.

    But the PC market will have to play catch up in bringing “a new level of innovation that consumers want to see in devices,” said Ranjit Atwal, research director at Gartner.

    “The real question is whether Windows 8 and ultrabooks will create the compelling offering that gets the earlier adopter of devices excited about PCs again.”

    And speaking of good old PC lord, Microsoft, its former tech guru, Ray Ozzie, admitted the post-PC era is firmly upon us at a tech conference Wednesday. Ozzie left the company suddenly in 2010.

    “People argue about ‘are we in a post-PC world?’. Why are we arguing? Of course we are in a post-PC world,” he said at a conference in Seattle, Microsoft home turf, reports Reuters.

    “That doesn’t mean the PC dies, that just means that the scenarios that we use them in, we stop referring to them as PCs, we refer to them as other things,” he said.

    Microsoft has come a long way since his departure, he admitted.

    “I’m happy about some things and I’m impatient about other things,” he added.

     

    And while the bad world economy and supply issues with SSDs played a key part in the weaker market, changing consumer dynamics was of “far greater” to vendors, say Gartner.

    2011 redefined the landscape of the device market with the advent of mobile computing on tabs like iPad, Apple and Android smartphones, say analysts.

    The use of e-mail, social networking and Internet, traditionally the domain of the PC, are now being used across mobile devices, making them in some cases more attractive propositions, said Atwal.

    Consumers will now look at a task that they have to perform, and will determine which device will allow them to perform such a task in the convenient way, rather than the other way around. 

    Ultrabooks will garner greater attention in the latter half of 2012 as the industry looks to reinvigorate the market.

    However, PCs will face even more competition from Android and Microsoft media tablets, as well as the new iPad, unveiled yesterday, Atwal noted.

    “Moreover, we expect the shift to the personal cloud will also accelerate as consumers increasingly adopt cloud-based services as part of their digital ecosystem,” he added.

    And of the declining Aussie PC market, local Gartner analyst, Eileen said:

    “Consumer spending is getting slower in mature markets like Australia, and Gartner foresees this situation will continue in 2012. Meanwhile, the impact of the HDD shortage that occurred during Q4 2011 will be somewhat delayed, we think most serious in 1H 2012.

     

    “We also don’t foresee good performance in the desk-based PC market. The fast adoption of media tablets is having a heavy impact on traditional PC market growth.”

    Emerging markets, which currently have low PC penetration rates, are key to worldwide growth in both the short and long-term, and Gartner expects market share increases from just over 50% in 2011 to nearly 70% in 2016.

    HTC Charm Offensive For ‘Sublime’ Rhyme

    HTC are pulling out all the stops for the Oz launch of Rhyme – its new chick phone. 3.7″ WVGA super LCD HTC Rhyme runs Android 2.3.4 Gingerbread with 4 GB onboard memory, 768 MB RAM, 8 GB microSD pre-installed, 5 Mp front camera with auto focus and power LED flash, HD 720p video recording.


    Click to enlarge

    HTC’s new slimline Rhyme has serious charm, apparently.

    “Attached to your bag, the Charm alerts you of calls, missed calls, and messages. It also keeps your phone within easy reach and goes with anything,” purrs the Taiwanese creator.

    Other than that not much is known about pricing or availabilty although the device does appear on one Aussie mobile site Mobicity, on pre-order for $629 outright.

    But here’s another one for the ladies: put Rhyme into a docking station and it turns into a picture frame.

    “Rhyme is the ultimate stylish device so what better way to celebrate so what better way to celebrate, than with a sublime experience in a world class spa and salon,” HTC Australia wrote in an launch invite this week.

     And what’s more, HTC are treating attendees to “a relaxing range of 30 minute express spa treatments” at exclusive Hair & Day Spa next Thursday, offering attendees manicure & pedicure, massage, facial or scalp and even hair treatments in a bid perhaps to attract the female contingent. (I can’t see the male journlists falling over themselves for a mani/pedi).

     

    Attendees of the launch taking place next week will also be buttered up with canap_s and refreshments. (Will let you know if the charm works, next week).

    Belkin Jumps On iPhone 5 Wagon

    Belkin bright iPhone 5 cases, armbands and screen protectors, revealed.


    Click to enlarge

    As the new Apple is unleashed to the masses, Belkin is bracing itself for enormous demand for iPhone 5 cases and armbands, as the redesigned 4″ Apple goes on sale in OZ today.

    Belkin has created a truckload of colourful cases, armbands, wallet and screen protectors to fit snugly around the longer and thinner iPhone 5, some of which are on sale from today.

    The new Apple gear start at $14.95 for a screen protector to $34.95 for Grip Max iPhone case with treble protection.

    Belkin Shield Series (F8W172) iPhone 5 cases are made from ultrathin polycarbonate, with some nifty designs including Shield Dottie, Shield Blooms and Shield Pixie.

    Belkin Shields start at $29.95, while the high-gloss finish Multi and BlueMicra Shield Sheer Matte (F8W095) sell for $19.95

    Belkin has also released the Grip Series for iPhone 5 made from a flexible, easy-to-grip TPU material and provides durable protection from impacts and scratches. They come in bright colours including pink and Day Glo and Purple Lightening Grip Neon Glo (F8W097), and cost $19.95 – $34.95 model dependant.

    Belkin’s Wallet Folio for new the iPhone (F8W101) costs $29.95, has an inner pocket to carry notes and credit cards and slip over to cover the screen.

    And for sports enthusiasts, there are water-resistant sport armbands for the new iPhone which are made from lightweight, breathable Lycra and neoprene, are hand-washable and have a the clear window for full control of the iPhone.


    Click to enlarge

    Belkin’s EaseFit Armband (F8W105), priced at $24.95, comes with an adjustable strap, while the EaseFit Armband Plus (F8W106) has a longer adjustable strap for increased comfort and fit and costs $29.99.

     

    Belkin also has developed an iPhone 5 Screen Guard with Tru Clear technology, an anti-smudge protector (F8W180qe2) for $14.95 and a High Definition for Retina Display Screen Protector (F8W182qe) $17.95.

    Some of the new Belkin accessories for the iPhone 5 will be available today, with additional accessories launching throughout the summer at select retailers across Australia and New Zealand.

    “Ranging from fun and bright to sleek and sporty, our designs for the iPhone 5 offer stylish solutions for everyone,” said Patrick Sullivan, director of global product management at Belkin.

    Forget 90″ TV: Sharp Sound Bar Is Big

    Fresh after releasing a 90″ LCD TV last month, Sharp is now going big on sound in the form of a 2.1Ch sound bar.
    The new 2.1 Channel sound bar (HT-SB60) with wireless subwoofer has 3D Audio (Arnis 3D Sound Solution), which gives the illusion of surround sound with its soft dome speaker system.  

    Costing $499, which is no bar for a soundbar, a Sharp spokesperson said demand will “depend on how the [Sharp 90″] TV is recieved” in Oz, but is designed to fit under a 60-inch TV to a 90-inch set.

    But it can be a standalone soundbar however, and hooked up to any device via a HDMI cable, regardless of make, the  spokesperson also pointed out.

    Total power output power: RMS 310W Soundbar: 160 watts (80W/ch + 150W) – 10% T.H.D, subwoofer: 150 watts – 10% T.H.D.

    The HT-SB60 has 2X HDMI inputs, 1X HDMI output with Audio Return Channel (ARC), to hook up the soundbar to the TV, an audio input terminal and an optical digital input terminal.

    “The new Sharp sound bar was developed to enhance the large TV experience – it’s designed to fit perfectly under a 60-inch television and can accommodate TVs up to 90-inches,” said Mark Beard, Marketing Manager, Sharp, Australia. 

     

    The sound bar weighs 3.6 kg and the subwoofer 6.1 kg.

    The Sharp HT-SB60, RRP $499, is available from all retailers.

    For further product information and full specifications visit www.sharp.net.au

    Quickflix Streams To Panasonic Blu-rays

    Stream Quickflix movies on-demand to your Pana Blu-ray.


    Click to enlarge

    Panasonic is unleashing Quickflix streaming services to selected Blu-ray models via its VIERA Connect platform.

    Quickflix on-demand service streams movies from Hollywood studios including Warner Bros, Sony Pictures, NBCUniversal, and from HBO, BBC & iTV – meaning everything from TV series like The Wire to movies like 21 Jump Street, Coriolanus and Meeting Evil to oldies like ‘All Quiet on the Western Front’ can be streamed to your player via the web.

    And there is also children’s content from the ABC, BBC, Turner and Cookie Jar.

    Quickflix’s service starts at $14.99 for unlimited streaming and can be bundled with Quickflix DVD by post plans, with the option of premium pay per view movies.

    Panasonic’s VIERA Connect also has a slew of other apps including to YouTube, Facebook, Twitter, Skype, as well as Yahoo!7’s PLUS7 and ABC iView.

    The Pana Blu-ray models that are Quickflix ready include: DMR-BWT820, BWT720, PWT520, HW220, DMP-BDT01, BDT320, BDT220, SC-BTT790, BTT490 and BTT190.

     

    “We are pleased to be expanding our partnership with Panasonic and in turn our addressable market, ” said Quickflix CEO Chris Taylor.

    “Our objective is to be accessible through as many connected consumer devices as possible with a compelling product offering. This is another important milestone towards that ambition.”


    Click to enlarge

    Samsung Forced To Surrender Galaxy Tabs 10.1 & S Phones To Apple

    Samsung has been ordered by a US court to hand over unreleased devices, as their patents battle with Apple intensifies.

    Click to enlarge
    Apple is accusing Samsung for replicating the “look and feel” of its iPad, iPhone and even iPod Touch on its Android Galaxy S 4G, Epic 4G, Nexus S and Galaxy Tab, which the Korean giant is firmly denying.

    This comes as it is due to release its its Galaxy S II in Australia later this week.

    “Rather than innovate and develop its own technology and a unique Samsung style for its smart phone products and computer tablets, Samsung chose to copy Apple’s technology, user interface and innovative style in these infringing products,” Apple alleged in the patent claim lodged on April 15.

    However, the courts appear to think the iPhone creator may have a case and has ordered Samsung to hand over two tabs to Apple: Galaxy Tab 8.9 and Tab 10.1 as well as Galaxy S2, and infuse LTE smartphones, all of which are as yet, unreleased, within 30 days.

    “Apple has demonstrated good cause for some, limited expedited discovery,” said Judge Lucy Koh speaking in San Jos_ Federal Court, California last week.

     “Although the Court expresses no opinion on the merits of Apple’s claims, the Court notes that Apple has produced images of Samsung products and other evidence that provide a reasonable basis for Apple’s belief that Samsung’s new products are designed to mimic Apple’s products.”

     
    “While Apple has not yet filed a motion for preliminary injunction, courts have found that expedited discovery may be justified to allow a plaintiff to determine whether to seek an early injunction,” she added.

    However, if Apple do file for an injunction seeking to ban sales of its devices, then Samsung could face an enormous problem and may put a major spanner in their plan to catch up to the iPad 2 with its 10.1″ Tab.

    According to the Courthouse News Service,  Judge Koh cited a TV news report that quoted a Samsung executive saying, “We will have to improve the parts [of the Galaxy Tab] that are inadequate. Apple made [the iPad 2] very thin.”

    Meanwhile, the Galaxy makers argued surrendering unreleased devices to a rival would give an advantage to Apple, which the courts rejected since it released 5,000 Galaxy 10.1 inch Tabs to the public on May 10.

    However, the judge refused Apple’s request to depose Samsung executives on each product.

    What ever the outcome the case is not as simple as the two tech houses battling it out over a patents issue.

    In fact Steve Jobs’ giant is one of Samsung’s biggest customers and make chips for several Apple products (including A4 and A5 processors found in the iPhone and iPad 2) so the outcome could also impinge on the commercial relationship..and Samsung’s bottom line.

    Forget Apple, Intel TV To Unleash

    Intel are about to throw their hat into the TV ring, says reports.

    Click to enlarge
    The chip maker is currently making its own set-top box and envisions itself as a “virtual cable operator” providing Internet Protocol TV (IPTV) in a bundle similar to cable TV, reports Wall Street Journal.

    It has already developed a user interface for users to browse programs and is pitching media operators it seeks to gain a platform to launch its Internet based Pay TV service, which it hopes to do later this year.

    The web ready Intel box would be capable of streaming and providing on-demand content.

    However, the service is said to be confined to the US.

    And its not just TV business Intel is looking to get a grip of – it is also joining the mobile revolution and announced Motorola,
    Lenovo and ZTE would use its Atom Z2460 (known as ‘Medfield’ chip) in its smartphones at the recent World Mobile Congress in Barcelona, as it plays catch up with rival ARM.

    Read: Intels New Entry Level Smartphone Looks Like An iPhone

    This comes as both Google and Apple are said to be making a dash towards consumer living rooms, and although Apple failed to deliver the holy grail IPTV device everyone was hoping for last week, is said to have more to come up its sleeve.

     
    Google TV is not said to launch in Australia this year although this may change.

    Intel already supply chips for set-top boxes sold by US firm Comcast, which sells Internet, TV and phone services.

    BBC + YouTube Hook Up

    Coming soon: Beeb to launch two new channels on YouTube


    Click to enlarge

    BBC Worldwide has announced a new partnership with YouTube and the launch of two new channels for science boffins.

    One will be a new nature channel, showcasing new films created by BBC Earth, along with another science channel with Top Gear’s James May and his crack team of scientists.

    Both will launch early 2013, BBC Worldwide said today, and believes the move will drive its YouTube subscribers base from its current 1.7 million to dizzy new heights.

    The BBC’s most popular channels out of its six on YouTube are BBC Worldwide, Top Gear and EastEnders.

    BBC Digital boss, Daniel Heaf, says the move to YouTube will give it scope for creativity and to experiment with different platforms.

    Daniel Heaf, EVP & Managing Director Digital at BBC Worldwide says the British broadcaster is “very excited” about expanding our successful relationship with YouTube.

    “Not only is it a place to distribute the best British content around the world it will, through our original content, be a place where we can experiment with new forms of creativity.”

     

    The deal also sees BBC add to its existing selection of over 8,000 YouTube clips across its 6 redesigned channels, including new clips include Top Gear series 18.

    BBC Worldwide will also be launching a selection of long-form programming in the UK and Canada for the first time, including the first ever episodes of EastEnders, The Likely Lads, a selection from the BBC’s Shakespeare Collection and The Trials of Life and other dramas such as Campion and The Onedin Line.

    Samsung To Ditch ‘Hero OS’ Android?

    Goodbye green man?

    Click to enlarge
    Samsung’s new boss has indicated need to rev up its proprietary software and develop “unique platforms and ecosystems”, suggesting it may ditch the green man OS, Google Android.

    “A particular focus must be given to serving new customer experience and value by strengthening soft capabilities in software, user experience, design, and solutions,” Kwon Oh-hyun, Samsung CEO, said in his first speech as boss.

    “Our company is at an inflection point in our bid to be a genuine global number one…complacency will put us on the same path as the countless other companies that have faded into the mist,” Kwon said.

    Kwon who took the top job at Samsung earlier this month has indicated the need to develop more in-house software capabilities if it is to maintain a firm lead in the mobile race, reports AFP.

    This warning comes as Samsung is now No. 1 phone maker globally since its collaboration with Android, knocking former leader Nokia off the top spot and seeing off rivals Apple too.

    Samsung runs Android software on its smartphones as well as its tablet line, although it now developes devices running the Windows platform also.

    But Sammy is still Google’s top Android brand, although the latter’s recent acquisition of Motorola may leave the Koreans feeling a tad insecure, though the Android maker has pledged nothing will change following the buyout.

    Nearly all of the Korean giant’s successful mobiles have used Google’s OS including the Samsung Galaxy S II (and now III), as well as Galaxy mini.

    Samsung already has its in-house Bada OS, released in 2010, which is used for low end “dumb” phones but has collaborated with Android since 2009.

    Samsung has made no secret of the fact they are currently developing Tizen, the Linux based OS, which fuses the Bada platform.

     
    Tizen is based on MeeGo (the OS used on Nokia’s N9) and LiMo (Linux Mobile), and was created in collaboration with Intel.

    Kwon’s aim for his company is to secure an “absolute lead” in the mobile market, he added.

    Former Samsung boss Choi Gee-Sung who stepped down earlier this month is now in charge of strategy for the tech powerhouse.

    Dick, Big W Soar Despite Gloom

    Woolworths today announced full year sales of $55.1 bn, a 4.8% jump on 2011. 


    iPad massive seller at Big W

    Retail giant Woolworths has fared well in what it admits was a “challenging year” as Group sales (including divested Dick Smith operation) was $56.7 bn, a 4.7% on 2011 FY.

    Woolies said it had made “pleasing progress” against its business plan. 

    Total online sales, on everything from food to booze and electronics, increased a massive 95% for the year (48% excluding Cellarmasters).

    On the electronics front, both Dick Smith and Big W sales also enjoyed a major turnaround in the 12 months to 24 June.

    However, Dick Smith which Woollies said it would divest several months ago, climbed in sales by 2.1%, despite the uncertainty over its future.

    Dick’s sales increased to $1.3 bn in FY 2012 and showed a massive increase of 10.4% in Q4, as consumers engaged in an end of financial year spending rush and also cited the success of Ad campaigns such as ‘Dick Does’ and ‘Cheapest Ever’.

    Comparable sales increased 4.3% for the year and 15.4% for Q4, which reflected strong promotions, stock clearances and store closure sales.

    Overall, 52 Dick Smith stores were closed during the year as part of the divesting strategy, which is said to be near completion and there’s currently 286 stores open in Australia and 62 in  NZ.

    BIG W’s sales for the year was $4.2 bn, an increase of 0.5% on 2011, and went from negative growth of (2.7)% in Q1 to 4.6% growth in Q4 y-o-y.

    There was continued improvement in sales, customers and the number of items bought during the year for the discount chain, which is one of Australia’s biggest Apple resellers.

    Sales were driven by 7 new stores, growth in online and strong performance from apparel. Good performers in Q4 Womenswear, Footwear, Menswear, Toys and “everyday essential items ” including the iPad got a special mention as hot sellers.

    Big W’s comparable sales increased 0.3% for the second half and 1.6% in Q4, which Woolies said was “pleasing given the continued price deflation and challenging retail conditions.”

    “There was additional uplift in sales in the last five weeks of the year as aresult of the government assistance programs,” Julie Coates, Director BIG W said.

    ‘Food and Liquor’ sales for FY 2012 were up 3.8% to $37.5 billion, while ‘Home Improvement’ sales increased 24.7% for the year to $828m, attributed to sales from the first 15 Masters stores opened during the year. 

    CEO Grant O’Brien said “Woolworths is pleased with the 4.7% growth in its full year sales result. The result is underpinned by continued growth in customer numbers, market share and units sold. “

    The last quarter in particular was “a stronger end to what was a challenging year” as “retail conditions remained subdued due to consumer and business uncertainty and an unseasonably cold and wet summer period,” which was exacerbated by significant deflation, he added.

     

    “The strong results reflect the resilience of our business as we continually adapt to the changing economic environment.”

    “There is a lot of hard work ahead, but with a lot of upside as well. Despite the tough economic times, we will continue to invest in developing new stores, building our multi-option infrastructure and building new businesses like Masters.”

    Multi-option remains a “key focus” for the retailing stalwart, the company said, and continues to evolve at pace with 2.3 million downloads of Woolworths related apps including the supermarkets app for iPad, the BIG W lay-by app and toysale pop-up stores.

    Other milestones in online retailing were Supermarkets mobile shopping app, a virtual shopping wall, BIG W mobile app, the Door Buster daily deals site, click then collect and a new generation supermarket online platform.

    Total online sales, which jumped 95%, however, are still small compared to the rest of the Woolworths business, it said.