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; } } David Richards, Author at Smart Office - Page 64 of 91

    Smart Office

    Woolworths Release Dick Smith From Upside Obligation As Master Costs Blow Out

    Woolworths who last year sold their Dick Smith operation to concentrate on the roll out of the Master hardware chain has finally admitted that the costs of rolling out the chain has blown out to a pre-tax loss of $157M.

    They have also announced that they have released Anchorage Capital Partners from its obligation to deliver Woolworths any upside resulting from the future sale of electronics group Dick Smith.

    Woolworths sold Dick Smith to Anchorage last year and had agreed to some upside in the future if the business was later sold.

    Woolworths said this morning in return for the new deal it would receive payments of $74 million to be booked as income in 2012-13.

    As a result of these additional proceeds the loss to Woolworths from the sale of Dick Smith of $65.7 million shown in its half year 2013 results will become a profit of $7.9 million in financial 2013.

    Anchorage Capital Management said t5hat today signifies a new chapter in Dick Smith’s independent success as Anchorage Capital Partners and Mangement, led by Nick Abboud have completed a release from the financial obligations to its former partner; Woolworths. 
    The buyout coincides with the Phase 1 completion of Dick Smith’s turnaround initiative which has increased operational efficiency, profit margins and growth, since the initial takeover from Woolworths in 2012. 
    Nick Abboud, CEO of Dick Smith Australia and New Zealand says, “This is a very exciting day for Dick Smith – one that we have been working towards since Anchorage first came on board. The Dick Smith business is in a strong financial position with cash in the bank and no net debt. Based on Dick Smith’s performance over the last six months we are confident the business will continue to experience positive growth and performance as a major player in the Australian consumer electronics industry.”
    “Dick Smith is committed to helping consumers get the most out of their technology and that starts in store. In the coming months we will be announcing a number of exciting initiatives that will see major changes to customers’ retail experience and an expansion of Dick Smith’s footprint throughout Australia and New Zealand.”


    Woolworths are also facing the potential of having to pay out between $700 and $800M to Lowes their US partner in October 2014 due to a “Put Option”.

    Master who is selling white goods and small appliances has admitted that they overestimated the costs of launching the chain up against the Wesfarmers owned Bunnings and Mitre 10.

    A statement to the Australian Securities Exchange said the higher losses were due to overly optimistic sales budgets, relatively higher wage costs for new store openings and lower margins due to the sales mix.

    Insiders are tipping that a new CEO could jettison appliances which are not delivering the returns that were first forecast.

    Recently several Analysts questioned the true cost of the Masters roll out and the losses it was accumulating for two-thirds owner Woolworths.

    Woolworths has also announced revised earnings guidance, saying it now expected net profit after tax from continuing operations, excluding non-recurring items, to grow in the range of 5 per cent to 6 per cent.

    Woolworths is still forecasting that Masters will break even during financial 2016, assuming more moderate growth in sales per store and improvements in gross margins.

    Woolworths expected the losses for financial 2014 not to exceed this year’s levels.

    In its hardware update this morning, Woolworths said there were currently 120 active sites on its books for Masters and at the end of 2012-13, 31 stores were open. But due to the timing of approvals and construction the number of store openings in the first quarter of 2013-14 would be lower than the recent run rate.

    Woolworths also moved this morning to quash any suggestion its one-third partner in Masters, US hardware giant Lowes, was seeking to dump its stake in the Australian business and walk away from the partnership.

    Naughty Digital Camera Lens Launched

    A camera lens that allows one to see through clothes and other hard surfaces has been introduced by a US Company.

    The lens that could well result in it being banned because of its perve potential is called the “Infrared See-Through Filter PF”. The PF is a special optical device that helps to visually penetrate an object’s surface in order to view whatever lies below. The PF makes it possible for you to see images that are normally invisible to the human eye. It sounds like science-fiction but it isn’t, this new product has been developed using newly developed advanced optical technology.


    Click to enlarge
    The lense

    Click to enlarge
    The original Image

     Kaya Special Optics have specialised in manufacturing special optical devices for the past 30 years and their new lense is set to be a big hit with perves and security companies. The 52mm Infra See through PF4 lense has to be fitted to either a digital still or video camera. The manufacturers claim that the Infrared See-Through Filter PF can’t totally penetrate all surfaces but it can provide  a high degree of “see-through”.

     It really is see through. see for yourself: http://www.kaya-optics.com/products/experiments.shtml

    Reflected “See-Through”

    Perhaps you are wondering what makes this ability possible. The answer lies in infrared rays. All reflected light that we can see with the naked eye represents a fractional portion of the electromagnetic spectrum, which is infinite. We refer to this section as “visible light”. All around us, light is reflected which the human retina cannot detect, such as ultraviolet and infra-red radiation.


    Click to enlarge
    What You See. OOP’s

    The visible part of the spectrum falls between the wavelengths of 430nm~690nm. (1nm=10-9m) Infrared rays have much larger wavelengths than this. We divide them into “Near Infrared Rays” (690nm-4,000nm) and “Extreme Infrared Rays” (over 4,000nm).

    Unlike ultraviolet and visible rays, infrared rays tend to penetrate any medium rather easily because of their large wavelengths. This also means that infrared rays are not refracted much at all when passing from one medium to another. When we shine sunlight through a prism, it is refracted at an angle according to its wavelength. The blue end of the visible spectrum has the shortest wavelength, so is refracted the most. At the other end of the spectrum, beyond the red, visible light, infrared rays are barely refracted at all because of their long wavelength.

    The KAYA PF exploits this characteristic of infrared light. It only lets through these long-wavelength rays, which have low refractive rays, and not all the ultraviolet and visible rays. Here’s how this relates to the mannequin experiment:

    1. Light source
    2. Mannequin
    3. Clothes
    4. Infrared rays
    5. Ultraviolet and visible rays
    6. KAYA PF
    7. Camcorder

    Almost all of the ultraviolet and visible rays are unable to permeate the fiber and are reflected back instead. Conversely, almost all of the infrared rays can easily permeate the material due to its low refractive rate. Having passed through the cloth, the infrared rays fail to penetrate the mannequin’s surface and are reflected back.

    The PF is struck by ultraviolet & visible rays that are reflected from the cloth and also the infrared rays that are reflected from the mannequin’s surface. But the PF only lets the infrared rays pass through. The infrared rays are then transformed into electrical signals by the CCD of a camcorder, which forms those signals into a visible-light image.

    In conclusion, the observer will be able to view the scene as though infrared light has become visible.

    Of course, if you were to simply look through the PF, you would not see anything at all. Remember, the PF lets through infrared light only, which is invisible to the human eye. Therefore there must be some media, or device, installed to detect and record, or convert, the image. As mentioned previously, camcorders and digital cameras are suitable devices for this purpose because they employ a CCD which responds to both visible and infrared light.

    Strictly speaking, it would be more accurate to regard these “See-Through” pictures as “near-infrared images” rather than “infrared images” since almost all CCDs can only respond up to 1400nm. Thus from hereon we shall use the term “near-infrared”, or “NIR” when talking about the images the PF allows.

    Fluoresced “See-Through”

    The principle of “Fluoresced See-Through” is very different to the “Reflected See-Through” principle above.

    When some substances are illuminated by certain wavelengths they reflect back not only those same wavelengths but also they may transform some of these into other, usually longer, wavelengths. For example, some substances may transform the illuminating visible light energy into longer-wavelength infrared energy.

    What causes this phenomenon? The answer can be found in atomic physics and quantum mechanics. Within atoms, electrons orbit about a central nucleus. If a packet of light energy (a “photon”) is absorbed by the atom, it causes one of the electrons to move out to a wider orbit. As described by quantum mechanics, atoms will only ever absorb radiation which has the right amount of energy to make one of the electrons perform this “quantum leap” to the next electron “shell”. A photon’s energy is dependent on its wavelength (and therefore, its colour), with violet being higher energy than red. However, an atom with an electron out of place is not stable for long so the electron falls back, re-releasing a ‘photon’ of energy. Some energy is lost so the photon given off is shifted towards the red end of the spectrum compared with the one absorbed.

    A Fluoresced See-Through image is slightly more difficult to achieve. Besides the PF filter, an Infrared Cut Filter (“ICF”) is required to create one. This filter performs the exact opposite task to the PF – it lets through visible light but cuts all infrared light from passing through. To capture a Fluoresced See-Through image, the ICF is placed over the light source to limit the incident light and prevent any infrared rays emitted by the source from reaching the subject. Some of the visible rays, which remain, striking the subject are changed to longer, invisible infrared rays and then the PF filter allows only these newly created infrared rays to pass into the camcorder or digital camera.

    This Fluoresced See-Through technique often reveals characteristics of a subject that are not readily apparent through other examination methods including Reflected See-Through. For example, chlorophyll in plants does not reflect infrared rays, but it does fluoresce. This may provide a means for studying certain plant diseases. Similarly, this technique can be used for the study of inks, hardwoods, forged documents or paintings and sometimes startling results can be obtained.

    To take more effective Fluoresced See-Through pictures, note the suggestions below:

    EnvironmentIf possible, total darkness.
    Light sourceTungsten or Electronic Flash.
    ICFKAYA’s ICF1 over the light source.
    This is not required if there is another way to ensure the subject is only illuminated by visible light. For example, wavelength-tunable lasers or blue-green lasers are ideal. Wavelength-tunable lasers have the advantage of being able to easily select from a wide range of wavelengths.
    PFPF2 or PF4.

    Camera’s that the lense will work with: http://www.kaya-optics.com/check_cameras/digital_cameras.shtml

    GE Money Thugs Bought Into Line By ASIC

    GE Money who are renown for heavy handed collection practises and massive interest rates has been slammed by the Australian Securities and Investment Commission. The Company who partner with several major consumer electronic retailers have been known to send in “thugs” to collect payments and in some cases have used “intimidating practises”, according to State government sources.

    ASIC say that consumer complaints about harassment from the debt collection practices of GE Money included excessive or inappropriate contact with customers, contact at unreasonable hours, and an inflexible approach to repayment arrangements.

    The government agency  has taken action over the sales and debt collection practices of companies in the GE Money group relating to the advice provided by parts of its insurance advice and sales business and also, the debt collection practices of the GE Money consumer credit businesses.

    ASIC has imposed conditions on the Australian financial services license (AFSL) of GE Money’s Hallmark General Insurance Company Ltd and Hallmark Life Insurance Company Ltd after those companies failed to comply with commitments each made in a 2006 Enforceable Undertaking (EU) to ASIC.

    ASIC found that parts of the insurance advice and sales business were often poorly managed and not meeting the legal obligation requiring there be a ‘reasonable basis’ for personal advice given to customers. Specifically, ASIC was concerned that staff were selling insurance to customers whose needs had not been identified or understood.

    Given that the Hallmark companies did not comply with a number of key undertakings given to ASIC in 2006, the regulator has decided the best way to protect consumers is to impose conditions on the AFSLs of GE Money’s Hallmark companies.

     

    The more stringent conditions now included in the AFSLs of the GE Money’s Hallmark companies replace the 2006 EU.

    These additional license conditions require the Hallmark companies:
    to engage an independent expert, over a period of up to 15 months, to review and assess the advice, sales, training, management and corporate governance processes in its branch network and make recommendations to correct any deficiencies, to ensure these processes are at an industry best practice level;
    to engage the same expert to assess the steps already taken by the Hallmark companies to compensate their customers and make recommendations as to any additional compensation steps that may be necessary;
    if the expert makes recommendations, to provide ASIC with an Action Plan to implement those recommendations; and
    to provide ASIC with full details of the compensation already paid to customers by means of a director’s statutory declaration, by 18 July 2008.

    Furthermore, the Hallmark companies are now required to limit the insurance advice their staff provide to ‘general advice’ only and not ‘personal advice’.

    Separate to the imposition of additional licence conditions on the Hallmark companies, GE Money has entered into an EU to address ASIC’s concerns about the debt collection practices of its consumer credit business. This is in response to consumer complaints about harassment from the debt collection practices of that business. Those practices included excessive or inappropriate contact with customers, contact at unreasonable hours and an inflexible approach to repayment arrangements.

    As part of this EU, the GE Money consumer credit business is required:
    to engage an independent expert, over a period of two years, to review and assess its debt collection processes to ensure that it complies with the ASIC/ACCC Debt Collection Guidelines and make recommendations to correct any deficiencies;
    if the expert makes recommendations for improvements, to provide ASIC with an Action Plan to implement those recommendations;
    to pay compensation to affected customers in accordance with guidelines prepared by the Banking and Financial Services Ombudsman; and
    to arrange and pay for an industry workshop to promote best practice in the debt collection industry.

     

    ‘ASIC’s approach to these serious issues has taken into account the major changes in personnel to GE Money’s senior management and the substantive and voluntary changes undertaken by the new regime, including compensation payments and the stated desire of the new management to ensure better compliance with the law’, ASIC Executive Director of Enforcement, Ms Jan Redfern said

    ‘However, financial services licensees should note that GE Money’s previous failure to live up to its undertakings has resulted in conditions being imposed on its AFSL. ASIC will continue to monitor GE Money closely and will not hesitate to pursue additional regulatory options, if required’.

    Logitech Becomes ‘Logi” as Company Drops Tech

    Swiss based Company Logitech, does not want to be the mouse and keyboard company” anymore so they have dropped the tech in their name, in the future they will be simply known as “Logi”.

    Overnight Logitech has announced a major rebranding, which will see the firm shake up its company culture and product range with the new branding set to be rolled out in Australia this year. 

    They said that the new name is part of its evolution into being a more design-focused manufacturer. 

    It has decided to drop the “tech” in its name for certain lines because, unlike when the company was founded in 1981, technology now “rules our lives,” a company spokesman said.  

    “The presence of it is implied, making ‘tech’ nonessential to the name.” The PC accessories stalwart turned tablet accessories standout said the new Logi brand will be featured on both former and upcoming products, most notably new categories it enters and products in its mobility and gaming categories. 

    Its core computer peripherals are also scheduled to integrate the new Logitech logo and bright colours, the spokesman said. Logitech just recently completed a three-year turnaround designed to combat the falling PC sales to which it had once hitched its wagon.

     It was the No. 1 seller of both PC keyboards and mice for the April 2014 to April 2015 period, according to The NPD Group, while its Ultimate Ears division was the No. 4 seller of Bluetooth speakers. 

    A spokesman said the company plans to launch something with the new label “just around the corner,” with more products due by December in Australia.

    The most obvious change concerns the Logitech logo. It has been radically altered, with the abstract, odd-looking eye completely dropped. The font is friendlier, all letters are now lower case, and the “g” almost looks like its smiling.

    The Swiss company says it wants to be more modern, friendly, open, approachable and simple, and a heavier focus on design will be of utmost importance.

    “We’ve been reinventing Logitech for a while,” said Logitech president and CEO Bracken Darrell. “We’re putting design at the centre of everything we do. Our products have come a long way, and now it’s time to bring the brand forward too.”

    Charlotte Johs, Logitech’s global VP of brand development said “Design has become as important as engineering,” she said during a Trusted Reviews interview last night “We are design-led. We are focused on design.”

    Moving forward, Logitech says its products will be deliberately eye-catching. While the company’s biggest focus has traditionally been PC-centric peripherals, it now intends to put aesthetics right at the top of its list of priorities.


    The company doesn’t appear to be doing this by halves, all their meeting rooms are now named after famous artists, including Picasso, Warhol and C?zanne.

    “We want to be at the intersection of art and science,” said Johs.

    However, she adds that it would be a step too far to push the new Logitech as a fashion brand. “Maybe eventually,” she tells us, but that certainly isn’t the current state of affairs.

    Johs also says that the transformation was largely triggered by the decline of the PC market, which wounded Logitech. 

    When asked, she concedes that the rebranding might never have come about if the PC was still going strong.

    There were a number of internal issues too.

    “The company was too hierarchical before,” said Johs, adding that Logitech had become big and clumsy, building hundreds of products for everybody, yet nobody in particular.

    The company has been trying to turn things around for several years, but Johs reckons it’s now in a good place.

    “We didn’t need an evolution, we needed a revolution,” said Johs. “We don’t want to be known as ‘that mouse and keyboard company’ anymore.”

    “Less is more” now appears to be Logitech’s new mantra, although “more is more” could also be applied. While embracing a larger range of product categories, the company will flog fewer products in total.

    Johs says that Logitech will now split its business into three areas of focus: trees, plants and seeds.

    Trees represent the profit-maximising PC-centric products that are Logitech’s staple. Johs says that these will continue to fund the company’s future.

    Plants, meanwhile, signify Logitech’s gaming, video collaboration, speaker and peripherals portfolio, which the company says it needs to nurture and grow.

    Seeds are more exciting. While the company hasn’t yet provided any specific details, it says it’s currently trying things it’s never done before, and will soon launch a number of brand-new product categories.

    To do this, Johs says it had to adopt a start-up mindset: intending to fail or succeed quickly, and then move on to the next project.

    She adds that no product categories will be dropped, but under-performing areas – such as webcams and headsets – will be “streamlined”. Keyboards and mice are still selling well, according to Johs, but will also require some tweaking.

    Projectors Still Growing

    Both professional and consumer projector sales rose 17% to more than 4.1 million global units in the first quarter of 2006.

    Shipments for the last quarter of 2005 reached 1,219,000 units, which was nearly 20% higher than 4Q ’04 and beat the previous quarterly high set in the third quarter of 2005 claims projector research group PMA.

    “In 2005, we saw innovative consumer products come to market, such as instant theater models – with build-in DVDs – and the first pocket projector,” said PMA Vice President Michael Abramson. “We also saw the introduction of higher-performance 720p models as well as the first of many attractively priced 1080p models. In the professional market, the news was more than just XGA breaking the US $1,000 barrier. In 2005, we saw the beginnings of a shift toward even higher resolution with more affordable, portable SXGA+ projectors as well as the burgeoning market for 1080p digital cinema projectors.”

    In the Americas, a large tender in Mexico helped the region register the highest annual growth in the world. In the U.S. market, strong holiday sell-in of instant theater projectors and enhanced 720p models drove the market to an all-time quarterly high in shipments of widescreen projectors.

    In Australia sales of consumer models helped lead the market to another quarter of overall double-digit growth. Sales of professional projectors eased Among the big winners in the projector market were BenQ.

    A New Smartphone Or Better Upgrades, What Would You Like?

    The smartphone market is booming but the big question now is whether manufacturers are unnecessarily churning out new phones in an effort to drive sales.

    Did we really need a new Galaxy S4? Or would an upgrade of the OS, along with all the new bells and whistles found in the new S4 sufficed most owners?

    The S3 was launched in August, now some nine months ago, and users are being told that their S3 is an “old model”.

    As manufacturers battle for supremacy, the once mighty benchmark for the smartphone industry, the Apple iPhone, is looking a tad “old hat”.

    At the same time Microsoft is struggling to get traction with their Windows 8 OS, as HTC, Samsung and Nokia report poor sales when compared to the demand for Android smartphones.

    Telstra, the big carrier who is reporting record sales of 4G phones, has told SmartHouse consumers are “confused” about all the features found in new models. In response the company is limiting the range of models they sell to key smartphones that they believe deliver speed and a rich range of capabilities.

    LG is one company who recently stepped up to the top smartphone table with their all new Optimus G smartphone. This is a cutting edge smartphone that the Korean Company badly needed in Australia to put them in the race alongside Apple, Sony, HTC and Samsung.

    Despite being late into the Australian market, the Optimus G is packed with power and features and can be easily updated with new software. While a lot of journalists got their knickers in a twist over the fact it had already been launched in the US, the fact remains it is a state of the art smartphone that has the capacity to handle any new upgrades thrown at it.

    Recent data from Counterpoint Research shows that LG is now a serious player in the smartphone market. In the US recently LG overtook Apple to claim the second-largest stake of the U.S. phone market. Samsung is still way ahead in first spot.

    The LG flagship Optimus G had recently surpassed the one million sales mark, and the Korean company is enjoying plenty of success with its Nexus 4.

    One of the standout new smartphones is the HTC One, due to be launched this month. This new Android OS offering is beautifully designed and is already being labelled “the best phone” in the world by reviewers.

    I have been using the device for the past two weeks and I am not only impressed by the design and the features, but the way in which HTC-who were desperate for a leg up in the market-has gone about delivering new capabilities via their Ultrapixel camera or their scrolling new information system that easily delivers news and information to a screen.

    The Optimus G and the HTC One usher in enough innovation to warrant a phone upgrade. But the verdict is still out on the Galaxy S4, with its subtle redesign and its software overhaul.

    What I would rather see is less models and more software upgrades that improve the functionality of a device.

    BREAKING News: Gerry Harvey Avoids Strike Motion Over Executive Salary Packages

    BREAKING NEWS: Retailer Harvey Norman has avoided a second strike against the Companies pay packages for executives.

    The spill motion that was proposed by the Australian Shareholders Association was dismissed when approximately 94.6 per cent of shareholders voted in favour of the remuneration report and 5.36 per cent voted against it.

    Executive chairman Gerry Harvey, his wife, managing director Katie Page, Directors David Ackery and John Slack Smith and other key management personnel on the board were not entitled to vote their shares. 

    Mr Harvey dismissed the ASA’s concerns, saying Harvey Norman did not pay directors or executives too much and directors needed to have “skin in the game”.

    “A lot of (under performing) retailers are not run by people who have skin in the game … they have had a lot of independent directors on the board, ” Mr Harvey told shareholders.

    Shareholders concerned about the lack of independent directors were being “fooled by experts who had never run a retailer in the lives,” he said.

    Mr Harvey said pre-tax earnings had risen 27.8 per cent in the first quarter of 2016, which compared with a 26 per cent increase in the year-earlier period.

    COMMENT: Choice Bangs On About Cheap Pricing But Fail To Identify The Risks Associated With Cheap CE Pricing.

    Harvey Norman who in the past have been labelled Australia’s most expensive consumer electronics and appliance retailer have again been singled out for selling expensive CE goods, despite several major brands moving to match overseas pricing prior to the decline in the value of the Australian dollar.

    Choice who are constantly looking for publicity to spruik subscriptions to their publication is now claiming that Australians pay an average of 50 per cent more for PC games, 34 per cent more for software, 52 per cent more for iTunes music and 41 per cent more for computer hardware than the US. Several of the comparisons were made based on Harvey Norman pricing Vs overseas web sites.  

    According to Gary Munitz, managing director of data analytics firm Invigor Group and creator of price comparison site ShoppingNinja, big retailers are facing a serious problem unless they can become more price-competitive.

    news.com.au claims that ‘consumers are turning to VPN services in droves to navigate around geoblocks, online stores are increasingly importing products through the back door and reselling them at significantly cheaper prices than traditional bricks-and-mortar retailers such as Harvey Norman’.

    ShoppingNinja now attracts more than 50,000 users a month and Mr Munitz says the majority of its sales are being funnelled to grey importers, with the mobile phones, cameras, tablets and headphones the most popular categories.

    ShoppingNinja collects a commission on all sales made via the platform. It’s aiming for $3 million in revenue in the first 12 months, and expects that to increase to $20 million over the following two years.

    The average discount is 20 to 30 per cent, with phones generally at the higher end. Other comparisons are even more stark. A Nikon Coolpix P610 digital camera is $384 from grey importer CameraSky, compared with $599 at Harvey Norman – more than 55 per cent more expensive.


    “It’s more to do with old-world commercial models,” said Mr Munitz, a highly regarded tech entrepreneur who founded Global Group and helped develop platforms including Menulog and Get Price.

    “Across every product category now there are a significant number of grey importers that sell online, and as consumer behaviour increasingly shifts online, this is going to be a big problem for Australian bricks-and-mortar retailers.”

    Mr Munitz said the likes of Harvey Norman were still operating on business models put in place decades ago. “Sony would say, okay, [Australia] has a population of 20 million, this is what our profit needs to be. But the internet has bridged the gap.
    .
    Choice spokesman Tom Godfrey said local providers had been holding up prices for so long, that frustrated Australian consumers were finally taking things into their own hands”.

    What Godfrey has failed to communicate on behalf of Choice is that retailers such as Harvey Norman, JB Hi Fi and Dick Smith are actually employing tens of thousands of Australians who expect to be paid each week. 

    They also have operating costs such as rent and warehousing and for Choice to single out Australian retailer pricing Vs online retailers who are selling products that often have no warranty in Australia or have been manufactured in questionable factories that don’t necessarily comply with Australian manufacturing regulations especially electrical goods raises questions as to whether Choice actual care about Australian consumers or whether they are isolating issues to create publicity for themselves like they did with their recent Samsung washing machine stunt.  


    Mr Godfrey said local companies needed to start competing on price. “If they haven’t realised by now then they’re a bit late to the party,” he said.

    Maybe Mr Godfrey and the team at Choice, should pay a visit to the family of Sheryl Aldeguer who left behind two young children and a husband when she was electrocuted by a cheap faulty USB phone charger.

    Authorities used Ms Aldeguer’s death to warn consumers against buying cheap USB chargers from online stores.

    Sony Samsung Relationship At Breaking Point

    Sony, who is fed up playing second fiddle to its LCD TV manufacturing partner Samsung, is considering a proposal to merge with a Taiwanese maker of LCD screens.

    Makoto Kogure, head of Sony’s TV group, was recently quoted  as saying that Sony is considering using Taiwanese Company M&A to secure panel supply, as opposed to continuing to invest in S-LCD, its joint venture with Samsung Electronics.

    Sony currently manufactures its large LCD screens via its joint venture partner  S-LCD however the relationship between Sony and Samsung has beome strained. Samsung has its own LCD TVs and recently overtook Sony to become the top TV brand worldwide. Internal memo’s at Sony claim that Samsung production needs are being priotised ahead of those of Sony. Other Sony executives claim that Samsung is “deliberatly” slowing down production of Sony branded LCD TV’s as they both fight for market share. S-LCD is 51% owned by Samsung with Samsung management being responsible for the day to day management of the S-LCD plant.

    A senior Sony executive in Japan told SHN that the relationship was doomed from day one. “Trying to get the Koreans and the Japaneses to work together while also competing against one another was never going to work. The quicker sir Howard Stringer gets out of the relationship the quicker Sony’s LCD business will grow”.

    In the overall TV market Samsung overtook Sony last quarter with Sony falling to the third position as it lost share in most TV segments, DisplaySearch said. To be effective Sony needs to secure a regular supply of smaller-size LCD TV panels (20- to 32-inch), as the main segments supplied by its seventh-generation (7G) plant (overseen by S-LCD) are 40- and 46-inch panels. In recent weeks Sony placed orders with two Taiwanese manufacturers.

    Digi Times in Taiwan claims that Sony needs to forge relationships with companies that have 5G, 5.5G or 6G plants, which include Japan-based IPS Alpha Technology, a joint venture between Hitachi, Matsushita Electric Industrial and Toshiba, Taiwan-based panel makers and China-based Shanghai SVA-NEC Liquid Crystal Display (SVA-NEC) and Beijing BOE Optoelectronics Technology (BOE OT).

    However It is unlikely that Sony will cooperate with IPS Alpha, as the joint venture was established to meet the needs of the three investors for 32-inch LCD TV panels and Sony is a competitor to these home appliance makers. Nor is it likely that it will partner with the two China-based makers, as the makers are not as experienced as their Taiwan-based counterparts.

    AU Optronics (AUO) and Chi Mei Optoelectronics (CMO) are currently the only two panel makers in Taiwan able to supply large amounts of LCD TV panels and they are already shipping TV panels to Sony. However, it will be difficult for Sony to acquire the companies, as the scale of the two Taiwan-based companies is too big.

    In addition, the 6G plants from Chunghwa Picture Tubes (CPT) and Quanta Display are still in their initial stages, while HannStar Display’s 5G technology is from its partnership with Hitachi.Sony insiders now claim that it is far more feasible, for Sony to  purchase a Taiwanese LCD plant rather than merging with an entire panel maker.


    Click to enlarge
    Sony Corp. Executive Deputy President Katsumi Ihara unveils Sony Corp’s new Bravia brand LCD TV models in Tokyo Wednesday, Sept. 14, 2005. Electronics was once Sony’s mainstay. Now it’s a huge money-loser. Sony has fallen miserably behind in televisions, watching Samsung Electronics Co. rake in profits from popular flat-panel TVs. Apple Computer Inc.’s iPod players now dominate the handheld music market Sony’s Walkman once ruled. Such are the challenges facing the sprawling Japanese technology and entertainment company as it prepares to announce a far-reaching turnaround strategy Thursday, Sept. 22 in Tokyo. (AP Photo/Katsumi Kasahara)
     

    Sony has fallen miserably behind in televisions, watching Samsung rake in profits from popular flat-panel TVs. Apple’s iPod players now dominate the handheld music market Sony’s Walkman once ruled. Such are the challenges facing the sprawling Japanese technology and entertainment company as it prepares to announce a far-reaching turnaround strategy today  in Tokyo.

    The expected shake-up also marks the first major test for Sony’s new leader, Howard Stringer, a dual American and British citizen who took over as chief executive earlier this year — the first foreigner to ever head Sony. Whatever Stringer may have in mind, analysts say it better be quick and decisive.

    Battered by the plunge in prices of electronics products that experts say have turned once fancy gadgets into mere commodities, Sony has lost money in its electronics operations for two years straight and has relied on hits from its movie division such as the “Spider-Man” series to bail out its earnings. “Sony has to get out of the cycle of making things for its own self-satisfaction and then having to sell them at bargain prices,” says Mitsuhiro Osawa, analyst with Mizuho Investors Securities in Tokyo.

    But Osawa hasn’t given up hope on Sony because of its historical technological finesse and is expecting new management to come up with a convincing revival plan — although no one is expecting an overnight cure. “All they have to do is show us enough to give us a good feeling about future prospects for Sony,” he said.

    The Tokyo-based company has fallen behind in TVs to South Korea’s Samsung as well as domestic rivals Matsushita Electric, creator of the Panasonic line, and Sharp. It’s been slow in developing new types of TVs with liquid-crystal and plasma displays that are proving a hit worldwide. Sony also fell behind Apple’s iPod in players that handle the popular MP3 music files, choosing to stick to its own more proprietary format, fearing copyright violations of products dear to its music division, which includes artists such as pop singer Beyonce and cellist Yo-Yo Ma.

    Sony, which built its fame over the last half-century with first the transistor radio and later the Walkman portable, has fallen into troubled times in recent years. In the last five years, its stock price has lost about two-thirds of its value, and in recent months has been hovering at about 4,000 yen (A$42).

    In July, Sony lowered its group profit forecast for the fiscal year through March 2006, citing tumbling television prices and higher than expected restructuring costs at the ailing electronics unit.

    Sony projects a 10 billion yen (US$89.3 million) profit, compared with an April forecast for 80 billion yen (US$715 million) profit.

    Sony, which employs more than 151,000 people worldwide, has been carrying out cost cuts and other restructuring for years.

    But it’s only in recent months the results are starting to show in products, such as the recently announced Bravia TVs, including liquid-crystal display and rear-projection models, some co-developed with Samsung that Sony says marks a break from its older-style CRT, or cathode ray tube, TVs known as Wega.

    And after brushing off the iPod for years, Sony is now coming out with various MP3 players, including the Walkman Bean that’s round and shaped like a lima bean, unlike the rectangular Walkman models of the past.

    Some analysts say Sony has spread itself out too thin.Japan’s top business daily said Sony is considering discontinuing its esoteric and extremely expensive Qualia brand products. It also said Sony may shrink its Aibo and Qrio robot operations, which may be eye-catching but don’t bring much profits. Sony declined comment, saying the plan was still being hammered out.

    But it denied a report in the same paper that Sony will sell off its financial businesses, such as its bank and insurance companies, to better concentrate funds on developing electronics products. Yuji Fujimori, analyst with Goldman Sachs (Japan) Ltd. in Tokyo said Sony needs to do more. And there’s no question Sony faces an uphill battle.

    “The reform contents would appear an extension of strategies pursued thus far and leave an impression of not going far enough,” he said in a report, adding that Sony should expand investment in entertainment and software businesses because electronics profitability is bound to be low. Sony has promised a powerful computer chip called “Cell” that will drive its next-generation video-game console PlayStation 3, scheduled to go on sale in spring next year, as a way it will one-up rivals.

    The Cell, codeveloped with Japan’s Toshiba Corp. and IBM Corp. of the U.S. will also power new digital home gadgets although no one has yet to see any specifics. That’s causing some skeptics to doubt its potential beyond video games.

    Meanwhile, Sony continues to face the challenge of a wide range of rivals, all of which would love to see the company stumble further. Fumio Ohtsubo, a senior managing director who oversees Matsushita’s TV business, is determined to keep Sony at bay for good. “Our mission is to do our utmost to prevent Sony’s Bravia offense from beating us,” he said at a party with Matsushita executives this week in Tokyo.

    JB Hi Fi To Take On Officeworks & Staples In B2B Market

    EXCLUSIVE: JB Hi Fi is moving into the SMB and telecommunications market in an effort to capture a larger share of the Australian business market.

    According to JB HI Fi CFO Richard Murray the mass retailer is in an excellent position to offer small medium business customers who have up to 50 employees a range of services including access to Telstra telecommunication products.

    Earlier this week the Company appointed Tony Nikolovski as B2B Telecommunications Manager, his job according to Murray is to work with store managers across Australia in developing a business engagement program with business customers who are looking for a combination of software, hardware and telecommunication services.

    “There is a big of opportunity for us to grow the office side of JB HI Fi from providing gift cards for business to delivering their telecommunication and hardware needs. As one of Telstra leading retail partners, this is a natural extension of our successful Consumer telecommunications business”.

    “We have the buying power with partners to deliver value for money and in the same way that we deliver for our consumer customers we can deliver for small medium businesses in Australia”.

    Murray said that in 2013 the Company will look at delivering a separate business web site that allows small medium business to engage with the mass retailers. Services such as cloud based software to IT and display hardware along with communication services and devices will be offered”.
     
    Tony will work within our Commercial Division to development and implement JB’s National BSB Communications Strategy, focusing on mobility, fixed and data.

     “The appointment of Tony Nikolovski who was most recently a National Account Manager with Telstra Retail delivers for JB Hi Fi a person who is experienced in the needs of small medium business. He will be responsible for utilising JB Hi Fi resources and engaging with our partners to deliver a new service for business in Australia”.