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

    Smart Office

    Telstra Slash 650 Jobs

    Telstra to cut 650 staff from Sensis business

    Telstra’s Sensis yellow pages directory, which has suffered a hit in the digital age, is cutting 648 jobs nationally, it has been confirmed.

    The cuts will include 391 back of house and customer care roles for  White and Yellow Pages which will be outsourced, possibly to India or Philippines, reports suggest.

    Sensis Managing Director, John Allan, confirmed the move and said the proposals to cut staff are now the subject of consultation with staff and unions.

    Sensis currently employs approximately 3500 staff.

    Telstra also announced a restructure of Sensis’ business model to “accelerate its transition to a digital media business.”

    The proposed restructure includes a new digital Customer Management Centre with 50 new roles.

    “Sensis needs to change in order to compete effectively,” said Telstra’s Sensis boss.

    “While these decisions are never easy, they are designed to position the company for future digital growth.”

    “Until now we have been operating with an outdated print-based model – this is no longer sustainable for us.

    “As we have made clear in the past, we will continue to produce Yellow and White Pages books to meet the needs of customers and advertisers who rely on the printed directories, but our future is online and mobile where the vast majority of search and directory business takes place,” Allen said.

     

    More than 60% of Sensis customers now are advertising online and in mobile apps.

    White and Yellow Pages digital services received 18.4 million hits in January last.

    Telstra is also proposing reduced duplication of senior and middle management roles and improved IT capabilities.

    “We need to simplify our operation and invest in areas that make us more efficient, and meet our customers’ growing demand for online and mobile services,” said Allen.

    Look Out JB Hi-Fi: New eTailer To Be “Big Player”

    Appliance king invades online consumer electronics, promising to be a “big player” in the space.


    Click to enlarge

    Appliance Online’s (AO) new retail venture will sell many of the brands already on Brown Box such as Sony, Panasonic, Toshiba, as well as budget brands TCL, Palsonic, Changhong, the Company’s General Manager, Peter Harris, told Channel News.

    However “we are looking to expand this” he says. Owned by the Winnings Group, it has a sizeable e-tail portfolio including Winning Appliances, Big Brown Box and Handy Crew.

    Founded in 2005 by John Winning, the pure e-tailer is one of the biggest seller of white goods in Oz and recently added deals site Power Buys to its portfolio.

    Considering Appliances’ strong position in the white goods space, it now appears to be well positioned to attack the ultra competitive consumer electronics market head on.

    Smart TVs (125 models in all, including LED, Plasma and 3D), Blu-ray players and PVRs are all among the major product categories AO is offering, as it makes its first foray into the CE market, announced last week.

    Audio wise, everything from Samsung’s mini Hi-Fis, Panasonic’s home theatre systems, Grundig’s DAB + Radio and iLuv speaker docks are all on offer on Appliance Online, alongside white goods like freezers, dishwashers and ovens.

    Accessories, iPhone docks, headphones and TV accessories and stands are also being sold.

    It’s new electronics sector will remain under the AO brand and website, rather than develop a separate standalone site. “We consider an appliance to be anything with a plug” so didn’t see the need to create a new platform, said Harris.

    Third party feedback prompted the move, including Facebook, emails and other in-house 3rd party feedback systems. “A lot of customers wanted this” – basically a ‘one stop shop’ for all appliances from a freezer to a TV.

    But it must be noted AO is staying away from smartphones and iPads, so far, although “we rule nothing out..its not on our radar at the moment,” says its GM.

    “Its an attractive category but very competitive,” he adds, noting the complexity attached to mobile business with contracts and other issues.

    So does AO think there is plenty room in the market for yet another online electronics seller?

    “There is demand there, as several major companies including Myer, David Jones and Harvey Norman are all reducing their footprint in CE” Harris told Channel News.

    “We’ve such a solid brand now and loyal customer base, so they like to shop with us.”

    The company as one of the largest appliance seller Down Under is now far more well known, which it says helps in its new electronics venture.

    So what’s Appliances’ website traffic numbers like to date?”

    AO has “several hundred thousand” hits per month although Harris would not be drawn on precise figures, saying “we’re (Harris and John Winning) less focused on numbers now,” as their marketing dept. deal with that, a sign of how far the web company has come.

    But AO are no shrinking violets and “hope to be one of the big players” in the CE space and are “ambitious…we ‘re not just dipping our toes in the market.” 

    So who does AO see as its competitors in the CE space?

    “Bing Lee, JB Hi-Fi ..all the big guys, “says Harris, but adds” we’re looking at the market as a whole not just online players. ”

     

    But Appliances doesn’t want to drive prices into the ground, either noting the massive price deflation and intense competition  are major issues for retailers looking to compete in the Aus market at the moment.

    “There are a lot of smaller sites who have a ‘price to the bottom’ strategy but that not for us”..although “we are going to be competitive,” Harris warns.

    Applainces’ also reckons his 24/7 customer service will be a big step towards giving it the competitive edge. “It’s all about service” and what customers want.

    The 365 days/round the clock customer service announced last week, means consumers can buy an appliance anytime they want, even 3am. The company’s new warehouse in Perth is also a major boost to its business and logistical capabilities out west.

    “A lot of people work shifts and can’t access stores easily, but still want to buy appliances and other CE goods.”

    “We listen to our customers.”

    Only Way is Up… For Downloads

    As Aussie downloads soar in the last year, it now seems this is only the beginning for the digital revolution.As it emerged Aussie downloads have soared 36% in the last year, it now seems this is only the beginning for digital downloads.

    Australia’s digital TV and film industry was worth almost $128 million in 2012 and entertainment industry boss predict further growth in digital downloads, streaming and VOD, which now accounts for 10% of total home entertainment sales including physical sales of DVDs, Blu-Ray. 

    Downloads of TV series and movies are set to rise as much as 30%, Simon Bush, the CEO of Australian Home Entertainment Distributors Association (AHEDA), told SmartHouse this week.

    “Expect strong growth to continue, another 30 per cent growth target is not out of reach.”

    However, pesky digital pirates need to be stamped out first of all, if the industry is to thrive, he warns.

    “When the government cracks down on piracy, research shows that sales increase and yes I would expect VoD service to mature in Australia but which platform will be dominant and when an SVoD service becomes available is unknown at this stage.”

    Top selling TV shows in Oz last year included Game of Thrones, True Blood and Gossip Girl, while The Hunger Games,  What to Expect When You’re Expecting, SherlockHolmes and Red Dog were among the top movie titles.

    The largest digital market in Australia in terms of revenues were video on demand (VoD) services like Telstra’s Bigpond Movies and Quickflix (56%), followed by electronic TV (23%) and movie sales. 

    “Digital sales in 2012 really took off and now exceed 10 per cent of total sales for the $1.174 billion Australian home entertainment industry” says Bush.

    Bye Bye TV: Sony, Sharp & Samsung Flee Big Displays – Tabs Takeover

    Traditional TV giants are fleeing the industry en masse as tight margins, poor demand and falling prices blight the sector.


    Click to enlarge

    LCD TVs once hailed as the consumer ‘must have’ now appears to be hitting a wall, as the tablet category, kicked off by the iPad and followed closely by a stream of Android clones, now reigns supreme. 

    So much so that three major TV makers, Sony, Toshiba and Hitachi, today announced a merger of its display businesses to create a bulwark against the likes of Samsung and Sharp, lower costs and get a grasp of the small display industry. 
     Read Team LCD: Sony, Toshiba & Hitachi Shock Merger As Tabs Boom Here 
     The Japanese display giant aims to “establish a leading global company by integrating three companies’ businesses” to make displays for tablets and smartphones as well as invest in OLED technology, it said today. 
    “The global market of small- and medium-sized displays is expected to grow rapidly due to anticipated strong demand for high resolution, high value-added products” the trio said. 
     The tech powerhouse will be ran in partnership with government innovation body, backed by 200 billion yen in public investment, a welcome funding boost for all three makers, who have recorded dramatic falls in their display operations, with Sony noting dropping global demand for its flagship Bravia LCDs in its most recent financial report. 
    And Samsung and LG, two of the top Australian TV brands, are also to follow suit, with reports this week suggesting both Korean smart 3D TV makers are planning to slash panel production and convert lines into tab and small display factories.
    Samsung, the current No.1 display maker globally, are said to be to be planing to cut LCD TV production by a massive 80% and concentrate on notebook and tablet screens, with LG also set to cut production as its panel business struggles with major losses, and chop capital investment by 25%. 
    “We plan around 3 trillion won ($2.8 billion) of capital spending next year and have no plans to build a new factory,” a LG Display spokesman confirmed. 
     In July, the 3D Cinema TV maker reported an 87.3% plunge in net profits for Q2 and its display division posting a 96 per cent dip in net profits to 21.3 billion won. 
    This comes as a sales of Android handsets grew over 350% during Q2 alone and tablet sales reach record heights, and estimated to be worth $35 billion as an industry next year, with global shipments of around 80 million, according to JP Morgan Securities forecasts. 
     

    In June, Sharp said it would cut large display production from October and focus on small screens in its TV-panel plant in the Japan’s Kameyama city. 

    Read Tab Threat: LG Slash LCDs As iPad 2 & Androids Call The Shots Here
    Sony net profit also slumped into negative territory in its most recent quarter, to -$191m, compared to a profit of 25.7bn yen the same period in 2010, blamed partly on losses in its consumer business, including TVs, forcing it to downgrade LCD sales forecasts even further. 
    The Bravia maker, who has never made a profit selling flat panel TVs, has seen global sales fall to 22 million during the past 12 months, had previously said it would reconfigure its TV production operations. 
    In the past, Sony has partnered with Samsung and Sharp in the production of flat panel TVs. It also banked on 3D to give them an edge in the TV market, although boss Howard Stringer is confident the new venture will help resurrect its troubled display business. 
    “By integrating each partner company’s wealth of display expertise and know-how, I am confident the new company will become a driving force for technological innovation and new growth in the rapidly expanding small- and medium- sized display market, said Stringer, Sony CEO and President. 
    “It’s been one of the losers,” Keith Wirtz, the chief investment officer at Fifth Third Asset Management, which owns 40,000 Sony shares, previously observed about its TV business.

    Fancy That! Apple Eyes Social Site

    Apple taking a Fancy to social stuff.
    The execs at Cupertino are said to be eyeing up ‘The Fancy’ a social commerce site that lets members buy cool stuff at a deal.

    The New York based start-up is being courted by Apple, with the two companies locked into talks on a buyout, reports Business Insider.

    The deal would “secure a role for Apple in the growing e-commerce market,” according to the report, as social networking king Facebook looks to further increase its commercial interests, buying a number of start-ups including Karma, the gift giving site.

    It would also be Apple’s answer to Pinterest, the wildly popular virtual pinboard. 

    Although Apple is undoubtedly a hardware king, success in the social commerce side of its business has largely eluded it.


    Click to enlarge

    ‘The Fancy’ site lets members “discover amazing stuff, collect the things you love, unlock crazy good deals,” and “fancy” the items on its site, a la Facebook “likes.”

    Fancy’s “stuff” includes everything from electronics, gadgets, to books and hotel rooms and currently has 400 million users but would probably garner a hell of a lot more if Apple got its claws into it.

    Fancy even has Apple boss Tim Cook among its user base.

     

    Some of the goods being fancied at the moment are a Breville pie maker, selling for $150, V-MODA Crossfade M-80 Shadow Headphones elegantor and the book ‘Born To Run” by Albert Lewis.

    The Fancy was co-founded by Joe Einhorn in 2010 and has just 20 staff, and is said to have be valued at $100m, reports Insider.

    No word on how mauch Apple would cough up for its latest Fancy, however.

    Apple TV By Foe Samsung?

    Apple look set to launch iOS TV using hardware from an arch rival.Rumor is rife within the industry that Apple are looking to relaunch its TV offering, first unveiled in 2007, but this time its actual branded Apple sets, as opposed to set top boxes of previous. 

     The latest project inside Apple is a devious plot to “blow Netflix and all those other guys away” with an internet ready TV kitted out with iTunes, one unnamed former Apple exec told Dailytech. 
     Last year it launched low cost $99 Apple TV device that gives users access to IPTV content and this is the latest move by Steve Jobs’ operation to give Google TV and other internet streamers a run for its money. 
     And the Cupertino firm is said to be teaming up with OEM manufacturer in the guise of rival Samsung – the arch enemies who cant seem to help not getting into bed together despite a highly publicised legal dispute, to make this happen. 
     That aside, Apple are one of Korean maker Samsung’s biggest customers behind Sony, making parts for its products including A4 and A5 processors found in the iPhone and iPad 2, so this rumoured partnership, if true, would certainly make business sense.
    Samsung, one of the high kings of the TV industry are certainly no stranger to smart TV’s and could do nicely out of the deal. “You’ll go into an Apple retail store and be able to walk out with a TV. It’s perfect” the source chirped. 
     

     However, when this is to launch is yet unknown although the source indicated a timeline between the fall (ie September) and next year was on the cards. 

    Baseless: Nokia Scoffs Off $19bn Microsoft Takeover

    Nokia chief has scoffed off rumours of a possible Microsoft takeover as rumours suggest otherwise.


    Click to enlarge

    Stephen Elop told a reporter at D9 event in the US yesterday that the rumours were without truth.

    “There’s absolutely no discussion. The rumours are baseless. It is as clear as that.”

    However, online speculations persists that a deal has already been done, to the tune of $19bn, based on claims from industry insider Eldar Murtazin, regarded as a reliable source and tipped the initial billion dollar Microsoft mobile deal with Nokia, which saw it pledge allegiance to Windows 7 platform for smartphones, according to BGR.com.

    But Elop, a former Microsoft exec, was quick to kill suggestions he was planted into the top spot at Nokia last year until his former employer made its next move.

    “The Trojan horse theory has been well overplayed,” he said. “I refer you to the grassy knoll for that one,” referring to a conspiracy theory about a second assassin of John F Kennedy in Dallas.

    This comes as Nokia warned investors it may not make a profit in the next quarter, admitting it may only manage break even between April and June 2011.

    The Finnish phones giant, admitted that profits will be “substantially lower” than the 6 – 9 percent margin it had initially expected, due to faltering handset sales across the globe and the demise of its Symbian OS. Its share prices slid after the announcement on Wednesday.

    However, Nokia, who is still the number one mobile company by sales has lost market share to smartphones like iPhone and Android handsets like Samsung Galaxy and HTC, which has whetted consumer appetites for high end devices.

    “My principal focus and the focus of the team is to take care of the short term but make sure that the execution is flawless”, Elop added, although admitted the changes “certainly feels painful right now.”

     

    And it is hoping its hook up with Microsoft earlier this year, which will see it binning its own Symbian OS and running Microsoft 7 platforms on a whole family of devices, covering the high and low end market, according to the Nokia boss.

    “In the first launch you’ll see the first device, but then a whole family of devices. We’ll be at many price points all over the world.”

    In the interview with Walt Mossberg, Elop also admitted Nokia tablets could be in the pipeline. “We’ll have to address that space,” he said.

    Rate Cut To “Save The Furniture”?

    AS rate cut was announced yesterday, there’s uncertainty if it will enliven consumer spending

    Retailers Association (ARA) Executive Director Russell Zimmerman said the decision to lower rates was the RBA’s bid to ‘save the furniture’ in the face of the upcoming Federal election and political instability. 

    Yesterday, the Reserve Bank moved to lower the cash rate by 25 basis points to 2.5 percent – putting them at an all time low. 
    Several retailers were unwilling to comment on record about the latest rate cut, today, as reporting season gets into full swing. 
    However, the ARA boss was uncertain about the impact on spending, saying “retailers are optimistic that this interest cut may encourage consumers to let go of their purse strings somewhat.”
    Will falling rates convince consumers to part with their cash?

    He also said the summer months ahead may bring some light to retailers. 

    Nab Economist Alan Oster told CN last week there was no end in sight for the dull spending environment, as consumers continue on their saving spree.
    Retail figures from ABS this week show retail growth was flat in June. 
    “The RBA have provided some relief to Australian retailers, although it is concerning that this cut has come on the back of flat retail sales, predictions of rising unemployment and falling consumer and business confidence,” said Zimmerman.
    The ARA are now calling on the banks to pass this rate cut in full. 

    Zimmerman also called for “clear commitments from both political parties regarding business growth, flexibility and lower taxes along with genuine tax and workplace reform.”

    Aussie ‘Happy’ In Work: LinkedIn

    Australians are a content bunch in their work, with lofty ambitions for the future, a new survey reveals. LinkedIn professionals’ career ambitions show we rank 10th out of global ranking as showing the most positive attitude in the workplace. The disgruntled Japanese were ranked as the least happy of the lot.


    Click to enlarge
    Who needs work when you’ve got waves! Aussies have a positive outlook on the 9 to 5. Image: Aquabumps.

    The survey asking 900 Aussie professionals, showed most had workplace ambitions including promotion, working overseas or a complete career change.

    64 percent told LinkedIn they are “happy” or “very happy” with their current job, behind the Americans (6th place) and the Dutch who ranked as happiest with 80% happy rating.

    “A tough economy can make professionals appreciate facets of their job they might otherwise overlook when business is booming,” said LinkedIn’s Connection Director, Nicole Williams.

    “Perhaps you didn’t get the raise you wanted this year, but you are appreciative of an amazing supportive manager who keeps an eye out for opportunities that will help you grow in your career.”

    The survey also listed out seven different career ambitions and asked professionals to select which ones applied to them.

    On a global scale, the No. 1 career ambition for professionals globally is getting promoted.

    With regards to the future, Aussie came 10th place as among the most optimistic workers globally, behind Brazilians who came out top, saying if they work hard and demonstrate results, they have a good opportunity to advance in their company.

     

    Spanish professionals ranked as being the least optimistic with only 44% agreeing that if they work hard and demonstrate results, they have a good opportunity to advance in their company.

    In the U.S. the top three career ambitions professionals selected were:to get promoted, staying in the current job or to retire early.

    Hello Stiletto: Westpac Backs World’s Biggest Brothel

    Westpac is financing the world’s biggest ever brothel, set for Sydney’s Paramatta Road.

    Parramatta Rd, synonymous with heavy traffic will now be know for something else – a ‘three-storey 42-room mega-sex-plex’ to be built opposite Sydney University, reports SMH.

    No. 84 and 86 will be joined with the existing establishment at No. 82 Parramatta Road, and those pesky pile ups will also be a thing of the past – the enlarged premises will also boast a large underground car park.

    The super brothel plan, devised by porn king, Malcolm Day, will also include seven swanky suites kitted out with pool tables and dual beds set up for parties and group booking on the top floor. 

    Stiletto, the current brothel occupying No.82, owned by racing industry figure, Eddie Hayson, is to be bought out. 

    Day, who is currently raising investment backing is already said to have a major backer – one of Australia’s biggest banks, Westpac, who are set to be key to the go ahead of the mega brothel, investing $12.1 million in the sex scheme. 

    If Day’s plan come to light, Stiletto will be the largest known brothel in the globe.

    And it also looks as if it will a good money spinner: “The new complex will create the largest short-stay bordello globally. On completion, earnings are projected to double to $40 million of revenue and $12 million of EBITDA,” according to a stockbroker presentation.

     

    The presentation also claims the plan is approved by state and regulatory bodies and already a “fully incensed and legal premises, with all regulatory approvals obtained – 10 year operating history.”