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

    Smart Office

    Len Wallis On Sound, Big TVs And Why Foxtel Better Watch Out

    Len Wallis a leader in the specialist AV market is restructuring in an effort to better engage with customers.

    The Sydney based AV specialist is undertaking a major refit to better engage with his customers who spend up to a million dollars on AV and automation fitouts. 

    Len Wallis’ showroom at Sydney’s Lane Cove already has 10 sound-lounge/theatres, a virtual smart-house and an on-site service centre.

    But in a time when bricks-and-mortar stores is in decline and facing economic uncertainty, why is Wallis developing his state of the art showroom even further?

    The “substantial drop in price points of AV equipment” is driving traffic into his store, owner Len Wallis admits, but is also the result of “genuine increased interest in better quality by the consumer,” he says.


    Click to enlarge

    Demonstrating the gear in the connected environment is also critical, says Wallis, as is a WiFi network.

    Having an in-house wireless network is “absolute and we developed our system over time,” he says but “we’re pulling it out and have just installed a really stable network.”

    “Its got to be done” he admits.

    So what are the big in the AV business at the moment?

    Security is a big issue for custom gear but from Len Wallis’ point of view, entertainment is the main one.

    “The changes in Australia over six months are going to change everything as far as content provision goes ..the days of listening to music the way we used to are totally dead now. 

    “Entertainment is now about the sheer amount of content available and the ease of getting it as you can stream content straight to your system rather than messing around with iPods and downloads.”

    This means content players of old may be in for a shock.

    Traditional content providers including the likes of Pay TV giant Foxtel “is going to have to be very careful that a video version of Mogg suddenly appears on their doorstep and then they will have real problems.”

    There are a few players working on delivery at the moment so, watch this space, he says.

    The likes of Google, Apple and Microsoft are “perfectly positioned” to enter this market and Wallis reckons it’s where content is going to go.

    “Foxtel is going to have to pick a side and partner up with someone,” if they are going to make it in the new content provision era of cloud, streaming and IPTV.

    Quality of devices is also improving in general, with most now starting at 320Kbps instead of 128Kbps and there’s now an upgrade path available on audio files, but the sheer amount of content available is the big thing.

    Quality of projectors has also jumped and customer feedback has been extremely positive, Wallis adds.

    In the custom space, the AV guru says there is still traction in non-dedicated theatre systems which is going away from the general trend.

     

    Sonos is still “enormous..it’s everywhere and people are still going to multiple boxes as its simply, cheaper and easier to handle.”

    The issue of service provision is also on the horizon for Wallis but there’s an interesting twist on it.

    “Some customers are looking to us as service companies to install and program devices they bought at somewhere cheaper like Bing Lee.

    “They’re looking at us to do the service on it as they perceive someone else as cheaper.

    “However, we’re not geared up as a service company of that nature just yet..but it’s certainly something we are going to look at”, he says.

    So what about the TV market?


    Click to enlarge

    Wallis cites Panasonic VT series 65″ Plasma TV which he says is “unbelievable..a stunning screen” models but availability is scant on the Australian market.

    However, you “cannot get a Panasonic screen for love nor money in Oz at the moment,” he says.

    This supply side issue is due to Pana’s local entity not ordering enough, despite the company saying otherwise.

    “I would have sold 30-40 on orders [if the stock was there], which for us is a lot as we’re not a screen company. “

     And is the demand for larger screens like 75″ or 80″ growing as prices fall and bigger OLED screens emerge?

    “We don’t stock anything above 65″ in the shop, but we’re certainly looking at it,” Wallis says.

    “We’re being very cautions of who were dealing with at the moment,” he tells ChannelNews.

    “We’re selling screens but not making any money out of them in some cases,” resounding the battle cry on every retailers lips at present.

    The old reliables of pricing and margin squeeze are still a big problem, and customers are still not sure about spending which is a “big issue,” Wallis says.

    “But those customers who are spending are bringing their expectations down,” he notes. 

    Gerry Hits Out At ‘Bouncy’ Wayne

    Forget e-tailers, Gerry Harvey has hit out at Treasurer Wayne Swan, lamenting the misery Aussie retailers are feeling at present.


    Click to enlarge

    “We’re having a horrible time in retail … there’s certainly no bounce in our step,” Harvey Norman boss Gerry Harvey said.

    This was in response to comments made by Treasurer Wayne Swan this week, saying Aussies should have a “bounce in their step” considering it is one of the only recession-free nations in the western world.

    Swan’s comments came on the back of yesterday’s revelation the economy’s GDP grew to an impressive 1.3% in the March quarter, latest ABS stats show – a 0.6% rise on December’s figure.

    This also marks a 4.3% lift year-on-year.

    And even the Treasurer admitted he was surprised by the prosperous figures, added:

    “Let’s make these figures an extraordinary circuit breaker. This tide of negativity, this relentless negativity from the doomsayers has to stop. It insults the hard work that so many Australians put in to make our economy strong.”

    The main industry contributors to Gross Domestic Product were Mining (up 2.3%), Financial and insurance services (+1.7%) and Professional, scientific and technical services (+2.8%).

    However, no sign of retail making any contribution to the country’s GDP, as every retailer from the high street to the sole trader are feeling the pinch as consumers play it safe with their cash.

     

    Some retailers, including JB Hi-Fi, say 2012 may not be as gloomy as last year, noting sales have got incrementally better during Q1 2012.

    Other big name retailers including Myer are also positive about the year ahead, amid a serious to its omni channel offering and e-commerrce site.

    Harvey Norman recently reported a massive  8.1%  sales slump and a 43.9% plunge in pre tax profits blaming falling demand for IT and consumer electronics.

    Optus Boot No. 1 Dealer TeleChoice

    As Optus customers complain ever louder, the yellow telco is dumping retail partner Telechoice

    As consumers complain ever louder about Optus, the yellow telco is giving its biggest dealership TeleChoice the boot, and opening up a slew of Optus ‘Yes’ stores instead.

    Killing the agreements between TeleChoice and Optus-owned Virgin Mobile and pre-paid services are also part of the telco’s new retail rationalisation strategy, announced today.

    TeleChoice is the biggest independent Optus dealers in OZ, set up in 1995 with 155 stores, both franchise and company owned.

    The new Optus retail grand plan will see tighter integration between the yellow telco’s retail online and in store, so customers who e-buy can collect instore.

    The move to ditch TeleChoice is the telco’s bid towards customer retention, it said today, in the wake of a telco ombudsman report out yesterday, which showed complaints about the telco soared 50% in 2011-12, while complaints about rival Telstra fell significantly.

    “As the Australian mobile market matures and we move from a period of growth to one of customer retention, we need a distribution model that reflects this,” Rohan Ganeson, Optus Managing Director, Sales said today.

    Ganeson reckons there is too much capacity in the mobile market and wants Optus to become a gung-ho retail tech powerhouse.

    The retail agreement with TeleChoice will end on 31 March 2013 and it is not known what the Optus (and Virgin mobile) exclusive dealers next move will be.

    TeleChoice was not responding to media queries when contacted by SmartHouse today.

     

    Optus says it plans to transform its sales channels to become a ‘full service customer channel’ to meet the changing consumers needs, it said in a statement today.

    “As the products and services we sell become more diversified and sophisticated, so too do the needs of our customers. There is too much capacity in the mobile distribution market and we have made a decision to rationalise our third party distribution channels, while strengthening our branded Optus channels,” Ganeson said.

    “Retail is no longer just a sales channel – it’s a channel where customers come to better understand technology and how to get the most from it.”

    The telco also announced the opening of an additional 33 ‘Yes’ Optus stores and over 200 new jobs.

    Optus is also adding other customer initiatives including: dedicated product experts, improved IT systems and infrastructure to better support retail staff, to provide “more consistent service and product knowledge. “

    The Singapore owned telco already gave the pre pay operator Boost brand the boot last week, which will be taken over by Telstra in early 2013.

    Optus says it will retain the pre-paid customers acquired during the partnership with Boost, providing them with continued access to their current plans under its own pre-paid service.

    BlackBerry Bold 9790 Punches NFC As Reality Bites

    There is a new Bold in town – the BlackBerry 9790. Launched in Indonesia yesterday, the new Bold boasts next gen technology like Augmented Reality and Near Field Communications (NFC) on the BlackBerry 7 OS.
    The 2.45″ Bold 9790 (480 X360 pix) is highly responsive to touch and is also keyboard ready – coming with the much loved QWERTY, optical trackpad, and a 1 GHz processor.

    But this is no standard Bold – BB have embraced NFC, which will allow the smartphone make payments, pair accessories or read SmartPoster tags with a tap of the device.

    And the Bold-er BlackBerry also come with Augmented Reality, allowing users to connect via apps – like the Wikitude AR application, which allows users find nearby BlackBerry Messenger (BBM) contacts in real-time, or get the story behind an interesting landmark nearby.


    This looks like a regular BlackBerry, but there’s more than meet the eye.

    Bold 9790 also comes with a 5MP camera, a flash, continuous auto focus, face detection, image stabilization, scene modes, 2x digital zoom and VGA video recording (640 x 480).

    BlackBerry’s latest OS 7 delivers an enhanced browser that provides a significantly faster web experience, JIT (just in time) JavaScript compiler to improve the load time speed of web pages and it offers HTML5 performance for better gaming and multimedia.

    And not to be left behind by the iPhone’s Siri – the Canadians have also enhanced Bold 9790 with voice-activated search, so users talk to their device for information.

    It includes 8GB of onboard memory and an expandable memory card slot for up to 32 GB of additional storage.

    The new BlackBerry also sports a narrow design that is easy to carry and exceptionally comfortable to hold.

    The BlackBerry Curve 9380, announced yesterday, is the first all-touch smartphone in the Curve family, which comes with a “brilliant” 3.2″ high resolution display, 5MP camera with flash and video recording, and is NFC and AR ready as the Bold 9790.
     
    This latest Bold and Curve punches comes as smartphone charts show BlackBerry trailing behind Android, Nokia and Apple in fourth place with 11% market share – selling 12.7 million units in Q3 2011, with analysts Gartner noting “lack of exciting new products on alternative operating systems such as RIM.”

    “Continued pressure is impacting RIM’s performance” and its US marketshare reached its lowest point ever –  dropping to a dismal 10%.


    Click to enlarge
    BB Curve 9380 and Bold 9790

    The new smartphone will be available in Indonesia from 25th November but is to be unleashed in the US along with new and Curve 9380 soon.

    However, BlackBerry Australia say they have no local availability info about the 9790 at present.

    “Indonesia is an important market for RIM and we are very excited to introduce the new BlackBerry Bold 9790 smartphone here first,” said Gregory Wade, Regional Managing Director at RIM.

    “The BlackBerry Bold 9790 combines a fluid touch display with the iconic BlackBerry keyboard in an impressively slim and stylish design. It’s powered by the new BlackBerry 7 operating system and delivers a truly outstanding mix of communications, multimedia, productivity and social connectivity features.”

    Hi-5 Foursquare: Obama Social ‘Check In’ Boost

    US president serves up a dose of street cred to the ‘check-in’ site by signing on.


    Click to enlarge


    Obama’s social networking quadrant is now complete – Facebook, Twitter, LinkedIn and now Foursquare, where members check-in via smartphone and find out where friends are.


    President Barack Obama has joined in the check-in fun and will be checking in to various locations as he embarks on an economic policy bus tour of USA and “is the latest way for you to engage with the administration,” according to the White House blog. 


    Foursquare, which has 10 million members, could also be handy web tool as Democrats looking to drum up support for his next presidential campaign in 2012.

    Many are already citing the move as ‘crucial’ for the success of his bid for re-election. 

    The web friendly President already has racked up over 12,000 followers. 

    “You can follow the President on the road through Cannon Falls, Minnesota; Decorah and Peosta, Iowa; and Atkinson and Alpha, Illinois. Through the new White House page on Foursquare, you can keep up with the President’s tour and check-in to let your friends know you’re there.”

    The White House will also be giving tips from the cities it visits. Can’t wait. 

     

    The move could also prove a massive boost for the social network, set up in 2009. 



    Can Apple, Samsung Kiss & Make Up?

    They’re filthy rich with cash to burn.
    But still, why are Apple and Samsung wasting time fighting in courts over patents and technology, some of which are now out of date 2 years after the fight first kicked off?

    There are a multitude of reasons why the tech giants won’t give up without a fight – and its not just about the cash, or patented technology each side is claiming the other has pinched.

    “There is a high dollar value attached to the outcome of the cases, so it would be very costly for either party to capitulate,” Chris Baxter, Baxter IP lawyers told SmartHouse.

    Read: Apple V Samsung: ‘Most Complicated Case Ever’?

    “Further, although the features are not new anymore, Apple and Samsung still want to incorporate at least some of them (such as rubberband zoom) into their new products – that is they are still current features that are important for usability, for example.”

    Baxter says the Apple V Samsung case is “highly complex” due to the technical nature of the issues involved.

    The Apple V Samsung patent infringements case is being played out again in Australia’s Federal Court since late February and is scheduled to keep going until June 13.

    The technology patents case is now being heard before two judges which the IP lawyer admits is a “unusual step” but makes sense given the complexities involved.

    Last week, a US Federal Judge slashed the $1.05bn fine Samsung has to pay Apple by half a billion, as the highly contentious case there continues, as in courts throughout Europe and Korea.

    And it looks like Samsung is taking no chances either after having suffered some early losses in courts worldwide including last year’s billion dollar fine, and has upped its lobbying expenditure in the US to close to $1 billion in 2012 – from just $150,000 the year prior, according to Bloomberg.

     

    The sum is the biggest ever the Koreans has payed out to lobbyists who push its interests in areas including patent regulation and telecommunications.

    The Galaxy Note makers says the enhanced lobbying spend is ”a prudent step as part of day-to-day business operations, our growing presence outside of our headquarters country, and our commitment to transparency.”

    It is probably a smart move since Apple is US company through and through, and one of Silicon Valley’s most revered titans.

    The launch of Samsung’s next hero smartphone – Galaxy S IV in the US next week also highlights the importance of that market to the Koreans, now the world’s biggest phone maker – of both ‘dumb’ and smartphones.

    And with Apple hot at its heels at No. 2 in the smartphone race and as one of the world’s most valuable companies, it wants to protect marketshare – and technologies.

    Forget Grindr, Fancy A Blendr?

    Gay or straight or ‘just friends’ these apps have mateship on a button. The follow up to Blendr, the hit app that allows gay guys to track each other down, Grindr is a dating app for straight folks, but also designed for purely platonic hooks ups based on common interests, says creator Joel Simkhai.


    Click to enlarge

    “Now everyone can try it,” referring to the Grindr for straights.

    “It’s much, much deeper than ‘hey, do you want to go on a date?’,” said Simkhai.

    “It’s about finding new friends. It is very difficult to meet new people who are interested in the same things you are – Blendr will help solve the problem.”

    “It could end up in a date, but the main goal is meeting new people,” he told the Guardian.

    The Grindr free app has about 2.6 million downloads worldwide to date, available on iPad, iPhone and Android, BlackBerry platforms, set up by Simkhai who got fed up of how hard it was to meet other gay men.

    The average user now spend around 1.5 hours on a day on the app (well with that many people to choose from) and just slightly south of half a million (450K) pictures are exchanged every day. Wow.

    Blendr, Simkhai new offering, however,  will also have a location edge to it, allowing users exchange info on club, restaurants, bars and to check in to locations and find one another.

    “If you’re sitting in the park all on your own there’s really nothing you can do about it – now you can do something about it with Blendr.”

     

    Dating will never be the same again.

    Telstra 1 Million IPTV Play

    Telstra looks at IPTV domination as it seeks to lure mobile customers over to Internet TV services.


    Rick Ellis, Group Managing Director of Telstra Media, is setting an ambitious target of 1 million Internet TV (IPTV)  devices sold by 2016, he told  Australian Media

    Telstra plans to introduce more content ‘bundles’ of T-Box and Foxtel content, Big Pond Movies and other TV services, which he says is “a first” for Australia.  
    Telstra’s set-top box known as T-Box currently gives subscribers access to free-to-air TV channels delivered via the Internet. As he revealed to Australian Media, half a million T-Boxes have been sold since 2010, meaning it aims to effectively double its user numbers. 
    “Up until now we have basically bundled a T-Box just as a personal video recorder device that gives you access to IP (internet protocol) content and acts as a digital terrestrial PVR (personal video recorder) for free-to-air TV and basic account access to transaction video on demand which is BigPond movies,” Ellis said.

    “But what we are doing now is…bundling up subscription linear (scheduled programming) channels, and further down the track we will be bundling subscription video-on-demand as well as movies and TV services.” 
    The largest telco in Australia is gearing up to drive more value from its millions of mobile and fixed-line customers, which could mean even more bundling of phone, Internet and TV services in the future; something which analysts have predicted for some time. 

    Recently, Telstra launched “entertainer bundles” with 11 Foxtel channels (on T-Box), BigPond broadband, unlimited calls on home phone, at an attractive price. 
    Telstra’s new IPTV push will be aimed at “pay-light” users: those that do not want to be locked in to long term contracts – something which it recently kicked off in its mobile services offering no commitment contracts. 
    Ellis, a former Chief Executive Officer of TVNZ,  is eyeing major growth in the Media business ahead of the rollout of the NBN which will mean all homes will have access to cheap, high speed Internet, making Internet TV the norm in future. 
    Telstra have pushed hard into its new Digital Media business in the last year, and have made Foxtel content available on more of its Telstra T-Box services, as traditional revenue streams from fixed line and Sensis business slides. 
    Telstra owns 50% of the Pay TV giant. 
    Foxtel, too, has upped the IPTV ante in a big way, allowing users to view Foxtel channels on iPhones, tablets and other devices, as it seeks to fend off competition from Internet TV services like Quickflix, Fetchtv. 
    Last week, Seven Network revealed it is working on plans to deliver an ad-free subscription TV service via the Internet, hybrid broadcast broadband television, which broadcasts digital TV content from a number of sources including traditional TV, Internet and connected devices at home.

    Tab OR Notebook? Asus “Transformer” Hits $499

    Its the tab that is a notebook.
    Meet Asus Transformer Pad TF300T – the colourful and much hyped Android Ice Cream Sandwich tablet hitting Oz this week.

    The 10.1″ (1280 X 800) Asus is ultra mobile at 9.9mm slim and 635g light, and when docked up to ASUS Mobile Dock, literally transforms into a workstation.

    The dock boasts a Qwerty keyboard and multi-touch touchpad for a notebook experience, and comes with USB port and SD card slot for extra storage. 

    When docked, total battery life is 15 hours, while the tab on its own goes for “up to” 10 hrs, Asus claim. 
    The Transformer Pad is powered by a powerful NVIDIA Tegra 3 quad-core processor (with integrated 12-core GeForce GPU), for “superior performance, multi-tasking” say its makers.


    Click to enlarge

    ASUS SonicMaster technology gives it good sound and an 1.2MP front camera, and 8MP auto-focus camera (rear) takes Full HD 1080p video playback.

    It also has 32GB of internal memory, a microSD slot and 8GB of free storage on ASUS WebStorage for life.

    The Transformer Pad’s Android 4.0 OS is upgradable and features “exclusive” software says Asus.

    Software onboard include preinstalled SuperNote application to take notes and Polaris Office, which gives users the ability to read or create Word, Excel and PowerPoint (MS Office 97-07 version compatible) files.


    Click to enlarge

    The Transformer will set you back $499 for the basic model while the docking station will cost you another $100.

    Looks wise, the 10″ tab/notebook wears a concentric patterned finish similar to Transformer Pad Prime, and comes in three colours, Royal Blue, Iceberg White and Torch Red.

     

    Additional accessories (optional) include TranSleeve Dual, a multi-view angle sleeve that supports handheld video watching and ergonomic typing.

    Also available are micro HDMI to VGA or HDMI cables, an external SD Card reader, external USB Port adapter and a USB to Ethernet adapter, all designed to complement your ASUS Transformer Pad.

    Crazy John Killed Off

    Maybe John wasn’t crazy enough, as Vodafone kills the mobile store.

    Owner of the retail chain, Vodafone, will exit from the Crazy John on 20 February.

    Some Crazy John’s stores will close, while others will be transformed into Vodafone stores over the coming months.

    The telco says its wants to “streamline our retail brand offering to one single brand – Vodafone ” and will be closing or rebranding all Crazy John’s stores.

    “Existing Crazy John’s customers will continue to enjoy the value and great service through the Vodafone store network, as well as online, customer care 132299 and mobile MyAccount service,” a Vodafone spokesperson told SmartHouse this afternoon.

    Vodafone says it wants to prioritise spending to improve its network, and said the surprise move was “necessary to remain competitive.”

    “We are continuing to focus our investments on our network to provide customers with better mobile coverage and fewer dropped calls. “

    “It wasn’t an easy decision to make and to ensure we focus our investment where our customers and people will benefit most.” 
    It also hopes to redeploy as many Crazy John’s employees as possible to Vodafone stores.