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 16 of 91

    Smart Office

    EXCLUSIVE: Top Executive Quits HTC OZ

    Anthony Petts the man credited with helping build HTC into a major Smartphone brand in Australia has quit the Company to take on a senior role at Motorola.

    Anthony Petts the man credited with helping build HTC into a major Smartphone brand in Australia has quit the Company to take on a senior role at Motorola.

    Petts who joined Taiwanese Company HTC, 3 years ago from Ericsson, when they were a struggling mobile phone brand has been credited with being able to open the doors of carriers to encourage them to sell the HTC brand shortly after senior management in Australia walked out on the Company.

    In May 2008, HTC’s then Managing Director John Featherstone and other members of the executive team claimed that they had “had enough” of dealing with Taiwanese management and quit on mass.

    HTC’s PR agency, Upstream now Bite, issued a two paragraph media statement shortly after the mass exit which said “Australia continues to be a key market for HTC. We are actively recruiting for a new country manager and building the local team. We have one of the most innovative ranges of smart phones available in Australia today, and our presence here continues to grow. In the coming weeks, we will launch our most exciting products shortly”.

    The person appointed was Anthony Petts who went on to make HTC one of the most successful Smartphone Companies in Australia.

    In his new role at Motorola, Petts has taken on the role of Strategic Sales Director. The US company who are currently making a comeback in Australia with a new range of Smartphone’s and their impressive new Xoom Tablet are tipped to be a major player in Australia with several senior carrier executives meeting with the Company at CES to view their new 2011 offerings.

    Motorola is also expected to have a major stand at next month’s Mobile World Congress in Barcelona next month when several new models will be released.

    The first inkling of a split at HTC emerged when an update was posted to Petts Linkedin page.

     Petts who has over 21 years experience in Sales, Marketing, and Technical, Management with Companies like Ericsson, HTC, and Vodafone is set to deliver valuable contacts to Motorola who during the past 4 years has cut back their operations in Australia as they struggled to get traction among the carriers.

    Their recent Motorola Druid phone, which is currently being carried by Telstra is proving to be a big success for the US Company due to the fact that it is waterproof and has an almost unbreakable “gorilla glass” display screen. 
    In August 2010, Ben Hodgson who formerly worked for Brightstar Logistics and i-mate Australia, a brand who struggled to get market share in Australia was appointed Country Manager for HTC Australia, at the time many observers expected Petts to get the top job.

    Hodgson has not returned calls to ChannelNews nor has Bite Australia executives.

    Sony Sack 32 With Simple 98 Word Email

    At Sony a product press release is worth a thousand words but the sacking of 32 staff which was tipped by ChannelNews last week is only worth a 98 word email.

    In a statement issued late this afternoon Sony CEO Carl Rose has engaged in pure PR spin in an effort to minimise the brand impact of the sacking of the 32 employees across the Sony Australia operation.

    Rose who came back from the UK to head up the Australian operation said” Today I announced some structural changes within Sony Australia. These changes will result in 32 redundancies across the company”

    The changes reflect a strategic shift to protect our competitive position in the local market as well as the impact of the global economic slowdown on projected sales growth.

    After a thorough review across the business, we have made structural changes in the areas of AVIT Sales, Marketing, Strategy & Brand Development, Customer Service & Operations and Commercial Management”.

    Late last week Rose was bragging about how the Company intended to spend millions on marketing and PR in 2009.
     
    He added “As always, we remain committed to reviewing and monitoring the environment to ensure the long term viability of our business.

    Missing from the press release is any reference to whether any senior management have been retrenched or whether another wave of retrenchments are expected later this year.

    Waterproof, Stomp Proof, New Smart Lenovo ThinkPad X1 Is A Tough Little Bugger

    Lenovo have launched a premium high end 13 inch notebook that you can literally pour water over and then stamp on without doing any damage to the device. I know I tried it.

    The device which will sell for $1,950 is aimed at the commercial business market despite the fact that it will have huge appeal with consumers who are tossing up between the Apple MacBook Air and the sleek new Lenovo offering. It comes with Corning’s new Gorilla display screen which Lenovo claims is unbreakable.

    Lenovo Executive Pours Water on the New ThinkPad X1. Channels under the keypad direct it to side vents.

    The ThinkPad X1 laptop, is wafer thin, packs a demon performance punch and has all the trapping that a top end notebook should have including a built in 3G wireless card capability.

    The only problem is that you won’t be able to walk into a mass retail store and buy it.

    According to Chris Kelly, director of SMB and consumer business the Chinese company is working on a consumer strategy but at this stage the device will only be sold via specialist retailers.

    Lenovo who is the world’s fastest growing PC company and the #1 commercial notebook supplier is set to expand their operations in Australia following the recent appointment of Alan Munro as Managing Director of the Australian operation.  

    The new ThinkPad X1 is set to be Lenovo’s answer to Apple’s MacBook Air line of ultra-thin notebook computers it will also compete up against the new Samsung 9000 notebook which is being sold for $2,499 via retail outlets.

     

    The Lenovo offering, measures less than 17mm and can be purchased in with an Intel Core i3, i5 and i7 processors which are typically offered on Lenovo’s larger 14 and 15-inch laptops.

    Weighing less than 1.7kg, the ThinkPad X1 has an interior roll cage and magnesium chassis and is so sturdy that it could be a threat to the Panasonic Tough Notebook.

    Another key feature is the RapidCharge battery technology that charges up to 80 percent in just 30 minutes. This technology charges two and a half times faster than a typical ThinkPad battery.

    RapidCharge combines fast charge cells with a 1,000 cycle battery designed to last three years3. Users can also opt to purchase a RapidCharge external slice battery for the ThinkPad X1 laptop to double their battery life to 10 hours. The cost of the additional battery is around $200.

    The ThinkPad X1 laptop will be available starting May 17 through business partners and online at www.lenovo.com.au. Pricing for models starts at approximately $1959.

    All prices quoted include GST.

    Microsoft Mobile OS Hurt By Android Sales

    Microsoft’s Windows Mobile platform is in trouble with new research revealing that Google and their Android software is more popular than the Microsoft offering this is despite the fact that one of the biggest selling phones at Telstra last month was the HTC HD2 which runs on a Windows Mobile platform.

    According to research Company Gartner, Google’s Android was the fourth most popular operating system on smartphones sold in the first quarter, research firm Gartner said overnight.
    Android, which was in 10 percent of smartphones sold in the quarter, still lags Nokia’s Symbian, Blackberry-maker Research in Motion and Apple.
    Gartner said Android phones were already outselling the iPhone in some markets less than two years after the Internet search giant entered the market.
    More and more start-ups are developing applications for Android, boosting interest among consumers and posing increasing risk to Apple, venture capitalists told a Reuters Summit in San Francisco.
    While Apple’s app store offers more than 200,000 games, tools and other software to jazz up the iPhone, against just 38,000 for Android, the openness of Google’s mobile operating system is helping it gain popularity with developers.

    eBooks Fail To Save Angus & Robertson & Borders

    Australian book chains Angus & Robertson and Borders have been placed into administration only hours after Borders in the USA was placed into Chapter 11. Neither company has a relationship other than a common name.

    Also placed into voluntary administration by its private equity owners (PEP), is the Whitcoulls chain of newsagencies in New Zealand. It was only six months ago that the Managing Director of REDgroup Retail Pty Ltd Dave Fenlon was spruiking new $199 Kobo eReader in Australia. At the time he categorically denied that the Borders chain of stores in Australia was in trouble.

    At the time Fenlon said that the launch of Kobo ‘would change the way we read forever’. “Through our partnership with global eBook retailer Kobo, we are bringing a whole new level of choice, control, and flexibility to Australian book lovers,” said Fenlon.

    The local group of companies have a combined staff of over 2,400 who are today waiting to see what their future holds.

     During the past six months the REDgroup has been desperately trying to compete with Amazon in Australia, who is selling books online at up to 80% cheaper than what the local book stores can offer the same books for in Australia.

    PEP is the same Company that was sued after they sold the George Patterson Agency to European based WPP.

    They have also had trouble in the past with previous Companies that they owned when they breached a number of lending covenants with its banks.

    REDgroup insiders said that the Borders chain of stores is expected to remain open in the short term, following a board meeting earlier today when directors were told that the group was facing the possibility of trading while insolvent.  Ferrier Hodgson partners have been appointed voluntary administrators.

     

     

    One source told ChannelNews that the recent hype concerning a 10% GST on overseas web site purchases under $1000 had not helped as a “lot of consumers” suddenly discovered that books were significantly cheaper on Amazon.co.

    One franchisee said “The book Companies also have to be held responsible for this collapse as they are selling books to Australia book stores at significantly higher prices than they do to the likes of Amazon and European and US bookstores. This is going to have a devastating impact in Australia if the chain is not acquired and is closed down”.

    Angus & Robertson has operated in Australia since1886 when David Angus and George Robertson opened a bookshop in Sydney.

    Ferrier Hodgson partner Steve Sherman said that as far as possible it would be business as usual while the administrators conducted an urgent assessment of the business’s financial status and to prepare for the first meeting of creditors, according to a statement.

    Samsung OZ Announce Major Marketing Restructure

    UPDATED: A major marketing restructure is tipped to be announced by Samsung later today that will see Lambro Skropidis take over all marketing roles in the Company under a centralised structure.

    A major marketing restructure is tipped to be announced by Samsung later today that will see Lambro Skropidis take over all marketing roles in the Company under a centralised structure.

    Mark Leathan the recently departed head of consumer electronics marketing will not be replaced.

    The marketing restructure at Samsung comes as arch rival LG gets set to announce the appointmentv of a new marketing director to replace the dumped David Brand who was in charge of marketing when false marketing statements were made about LG appliances that is set to attract a multi million dollar Australian Competition and Consumer Commission fine.

    In a statement issued later today, Samsung confirmed that Lambro Skropidis, the current Head of Marketing for the Corporate Marketing Division will take over the running of the newly formed marcomms and corporate marketing team which will include all marcomms marketing staff from each of Samsung’s product divisions across AV, Mobile, Home Appliances, IT and Digital Imaging.

    Samsung said that the newly centralised marketing team will work collaboratively on growing Samsung’s brand in Australia.

    “Our ambition to build the most iconic, leading and consumer loved brand is quite aggressive.  We want our brand to be transformed into this position over the next few years.  To do that, we believe we will need to approach our marketing activities in a different way.  Our aspiration from a marketing perspective is not only to be the best in the industry, but to be the best in class overall,” said Lambro Skropidis, Head of Marketing for Marcomms and Corporate Marketing, Samsung Electronics Australia.

     

    “The formation of our new Marcomms and Corporate Marketing team will help drive our marketing communications to the next level and help stimulate consumer demand and trade support to deliver an ongoing leadership and growth position in the years to come.”

    Samsung has increasingly become known for its world firsts in cutting edge innovation and excellence across multiple categories in consumer electronics. In 2010 Samsung was the first manufacturer to launch 3DTV in Australia; was the first to launch and create the new category of compact DSLR cameras with the debut of the Samsung NX10; and launched the smartphone that globally holds the Guinness Book of World Records for the fastest texting with the new Samsung Galaxy ‘s’ smartphone.

    The structural change to the marketing team symbolically comes on the eve of the launch of the inaugural Samsung masterbrand TV campaign featuring Simon Baker as brand ambassador in Australia, which also brings all of Samsung’s product categories under one banner. Bringing the strengths of all of the Samsung marketing teams together under one lead marks a sign of things to come for this world-leading consumer electronics giant.

    Dell Moves To AMD Processors

    Dell which has used only Intel processors until now, has announced that it would begin using a chip made by Advanced Micro Devices, as part of a broader plan to improve its flagging sales and market share.

    The move has seen Intel shares fall and AMD’s rise.

    Dell who are struggling to increase sales, said that by the end of the year, it would start using an AMD Opteron chip in one of its high-end servers with multiple processors. “It’s a fairly small category,” Kevin B. Rollins, chief executive of Dell, said on a conference call with analysts.

    He did not rule out using AMD chips in Dell’s PCs or in other servers, but he said that Intel would remain the supplier of the “vast majority of processors we use.” Rollins outlined several personal computer products that the company planned to introduce this year, and all of them will use Intel chips.

    Dell, the world’s largest seller of personal computers, had previously said growth suffered in the quarter as it cut prices to gain market share and spent more on improving customer service. “The competitive environment has been more intense than we had planned for or understood,” said Rollins.

    Rollins said Dell planned to accelerate efforts to reduce costs by $3 billion so it could continue to reduce prices where needed.

    “We’ve allowed our growth essentially to come to a stall,” he said

    Seagate To Cull 6,000 Maxtor Employees

    Disk-drive manufacturer Seagate Technology has completed its acquisition of Maxtor by saying it will fire about half of Maxtor’s 12,000-person workforce.

    Disk-drive manufacturer Seagate Technology has completed its acquisition of Maxtor by saying it will fire about half of Maxtor’s 12,000-person workforce.

    Most of those cuts will occur in the United States not Australia or Asia Pacific. Seagate will keep Maxtor’s new disk-drive factory in China, along with roughly 6,000 people who work for Maxtor in Asia. No Seagate employees will be eliminated. The deal leaves Seagate with a worldwide workforce of 55,000.

    Seagate, is officially based in the Cayman Islands, is the world’s largest maker of disk drives for personal computers. It announced in December that it would acquire Maxtor, a rival disk-drive company, in a stock swap valued at roughly $1.9 billion. Shareholders of both firms approved the deal last week.

    Mark Geenen, president of TrendFocus, a market research firm called the deal a surgical operation that cut out the expensive parts of Maxtor, while allowing Seagate to boost its manufacturing capacity. “This is a very clear-headed move,” said Geenen, describing disk drives as a commodity market that’s been great for consumers but tough on manufacturers.

    In 1997, for instance, a 10-gigabyte hard-disk drive was rare and cost $650, Geenen said. Today, an 80-gig drive runs less than $50, he said. To profit amidst plunging prices, disk-drive manufacturers have been consolidating and the number of brands has been shrinking. But Seagate Chief Executive Officer William Watkins made clear Monday that this deal would not be a merger so much as a meal in which Seagate swallowed only those parts of Maxtor that made sense.

    “When you announce a merger or acquisition, and intend to blend roadmaps, processes, etc. . . . you end up with two companies in turmoil,” he said Monday.

    Other than the factory in China and some facilities in Singapore, what Seagate found most appetizing was Maxtor’s popular line of backup-storage products and some high-end disk-drive development being done in Colorado and Massachusetts. Fewer than 100 people in Milpitas will be retained to continue the backup-storage line, said Seagate spokesman Brian Ziel .

    John Rydning, an analyst with IDC market research in Massachusetts, said even before acquiring Maxtor, Seagate had a 29 percent market share, ahead of second-place Western Digital (18 percent) and third-place Hitachi (14 percent). Maxtor had been fourth with a 12 percent share.

    “While it’s painful for the people involved, it’s healthy for the industry and for Seagate and its shareholders,” Rydning said

    BMW Technology And Art Worth Millions Coming Back To OZ

    The now famous BMW Art Car Collection is coming back to Australia for the first time in 18 years. The collection which had its world premiere at the Powerhouse Museum in Sydney in 1989 includes a car painted by Andy Warhol. It has been described as priceless.

    They may not be the latest in technology on the surface, but the BMW Art Car Collection, which is due back in Australia in June, is definitely packed with technology under the bonnet.  In fact some of the technology such as multi valve engines and BMW braking systems first appeared in the cars painted by the BMW Art Car artists. 
    Ken Done paints his Art Car

    The collection which had its world premiere at the Powerhouse Museum in Sydney in 1989 is due back in Australia in June 07 at the Museum of Contemporary Art in Sydney. Among the rare BMWs coming back to Australia are Art Cars painted by Andy Warhol, Roy Lichtenstein and Frank Stella.

    Michael Jagamara Nelson Paints his BMW Art Car

     


    Between 1989 and now, millions of people have seen the collection around the world at locations like the Museum of Modern Art in New York.  Under the bonnet of each Art Car is a BMW motor car than has won a World Championship, Le Mans or a European Touring car championship. In 1989, Australians Ken Done and Michael Jagamara Nelson were commissioned to paint a BMW Art Car. As a creator of one of these unique pieces, they joined an elite group of global artists, which includes Andy Warhol, Roy Lichtenstein, Frank Stella and Robert Rauschenberg.

     

     

     The Art Car concept began in1976, when Alexander Calder was commissioned to embellish the BMW of his friend, French racing driver Herve Poulain.  However the project stalled and the cars were warehoused at the BMW 5series plant in Germany until they were resurrected and bought to Australia.

     As the project manager for the BMW Art Car Collection I worked closely with both Ken Done and Aboriginal artist Michael Jagamara Nelson.


     

     

     

     

     

     

    When commissioned, Ken Done, made his racing car as optimistic and colourful as his pictures. The style he chose was intended on one hand to express the fascinating appeal of the M3 as a fast and dynamic automobile, while on the other hand it had to be typically Australian.

    This is why Done intentionally chose an abstract rendition of parrots and parrot fish: ‘Both are beautiful and move at fantastic speed. I wanted my Art Car to convey the same impression.” He said at the time.

    The Art Car Collection was not without its dramas. In an effort to test the baking capability of Aboriginal Art in an automotive oven used to bake the paint dry on a motor car, a BMW 3 series door was shipped to Michael Jagamara Nelson in the Northern Territory outback. When the door was returned it was baked and taken to the Powerhouse Museum. Mysteriously the door which overnight was suddenly worth tens of thousands of dollars, disappeared only to turn up months later in the office of the then director of the Powerhouse Museum.  It was later donated to the Powerhouse Museum by BMW Australia.

    New Moto Q Coming To OZ

    Motorola’s new Moto Q which is a cell phone and e-mail device and a competitor to the BlackBerry will be launched in Australia soon.  Peter Joblin PR director of Motorola Australia confirmed to us that the device will be sold in Australia. Motorola also say it will achieve sales similar to those of its popular Razr.

    Ron Garriques the head of Motorola’s phone division told analysts at an investment conference that the company has high expectations for next week’s U.S. release of the Moto Q followed soon after by its launch in several Countries including Australia. 

    Motorola, CEO Ed Zander holds the new “Moto Q”. According to Motorola, the multi-tasking device works with Microsoft Windows Mobile 5.0 software, features electro-luminescent keys, QWERTY keyboard, thumbwheel for single-handed control, and internal antenna.

    Motorola expects to sell 750,000 Moto Qs in the first three months, 1.5 million in the next 3 months and 3 million in the three months after that. Those are the same numbers racked up by the Razr, the ultra-thin phone whose enduring success has helped Motorola pick up market share on industry leader Nokia since 2004.

    “We think we’ll follow the exact same curve as Razr did,” Garriques said at the conference in San Francisco, which was Webcast.

    Motorola now projects at least 300 million total sales of Razrs and their related spinoff phones over the lifetime of the product family, Garriques said.

    He also said the company is talking to customers about a new line of super-thin cell phones it plans for next year called the SCPL (“scalpel”), although he did not give specifics.

    The Moto Q will be available through Verizon Wireless starting May 31 for $200 when purchased with a two-year commitment to a Verizon plan. Besides e-mail capability and Windows Mobile software, its features include voice-activated dialing, speakerphone and Bluetooth capabilities.