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; } } Human Resources Archives - Smart Office https://smartoffice.com.au/category/human-resources/ Wed, 12 Aug 2020 04:43:47 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 Seek’s Earnings Down 9% In ‘Weak Ad Environment’ https://smartoffice.com.au/seeks-earnings-9-weak-ad-environment/ https://smartoffice.com.au/seeks-earnings-9-weak-ad-environment/#respond Wed, 12 Aug 2020 04:43:47 +0000 http://smartoffice.com.au/?p=97902 Seek Group’s full year earnings fell by 9% in FY20 to $414.9 million as the company was impacted by the COVID-19 crisis and a weak macro environment. However, Seek was still able to achieve revenue growth of 3%. Although Seek’s revenues fell by 12% in Australia and New Zealand, it remained the market leader with ... Read more

    The post Seek’s Earnings Down 9% In ‘Weak Ad Environment’ appeared first on Smart Office.

    ]]>
    Seek Group’s full year earnings fell by 9% in FY20 to $414.9 million as the company was impacted by the COVID-19 crisis and a weak macro environment. However, Seek was still able to achieve revenue growth of 3%.

    Although Seek’s revenues fell by 12% in Australia and New Zealand, it remained the market leader with 33% of placements, highlighting how tough the job postings market is in the current climate.

    In FY20 Seek maintained a lead of five times over their nearest competitor in the local market.

    “Seek ANZ delivered a resilient result in challenging conditions. In a weak ad volume environment, we saw robust results from our depth products and SMEs,” said Seek CEO and Co-Founder Andrew Bassat.

    “When labour markets return to more normal conditions, we expect to generate a high ROI given our market leadership and track record of generating strong returns from investing in product, technology and data. The near-term will continue to pose challenges, but we will remain agile to take advantage of new growth opportunities as they arise.”

    Citing the difficult operating conditions, Seek is not paying a final FY20 dividend. “Once economic conditions improve, we intend to resume payment of dividends,” Seek stated.

    Seek’s share price tanked when the COVID-19 pandemic hit, falling by 38% in March. It has since recovered, closing at $21.40 yesterday.

    Seek ASX 12.08.2020

    The post Seek’s Earnings Down 9% In ‘Weak Ad Environment’ appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/seeks-earnings-9-weak-ad-environment/feed/ 0
    Shutdown? Airbnb Lives Again https://smartoffice.com.au/shutdown-airbnb-lives/ https://smartoffice.com.au/shutdown-airbnb-lives/#respond Tue, 07 Apr 2020 23:57:05 +0000 http://smartoffice.com.au/?p=97643 SYDNEY: The NSW Government has backed away – at least for the time being – on what appears to have been a planned shutdown of the Airbnb home-sharing business, due to the coronavirus. In a number of media reports on Monday, the NSW Minister for Innovation Kevin Anderson was quoted as saying short-term accommodation had ... Read more

    The post Shutdown? Airbnb Lives Again appeared first on Smart Office.

    ]]>
    SYDNEY: The NSW Government has backed away – at least for the time being – on what appears to have been a planned shutdown of the Airbnb home-sharing business, due to the coronavirus.

    In a number of media reports on Monday, the NSW Minister for Innovation Kevin Anderson was quoted as saying short-term accommodation had been declared illegal and that there was “zero reason for someone to stay in an Airbnb”.

    However yesterday both Anderson and Airbnb said this was not correct. Airbnb said its clients were still operating while Anderson said that in the current circumstances, “the provision of short-term accommodation is often critical, particularly for our frontline health workers”.

    Still, many Airbnb premises may still find themselves un-occupied. Many commentators, and some police, have warned that long-distance travelling to an attractive Airbnb holiday property may be near-impossible, given police warnings and shutdowns.

    The post Shutdown? Airbnb Lives Again appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/shutdown-airbnb-lives/feed/ 0
    Is Kinect Paving The Way for Biometrics? https://smartoffice.com.au/is-kinect-paving-the-way-for-biometrics-2/ https://smartoffice.com.au/is-kinect-paving-the-way-for-biometrics-2/#respond Thu, 06 Jul 2017 09:00:00 +0000 http://smartoffice.com.au/is-kinect-paving-the-way-for-biometrics-2/ It may yet prove to be a sign of things to come.

    The post Is Kinect Paving The Way for Biometrics? appeared first on Smart Office.

    ]]>
    It may yet prove to be a sign of things to come.

    Socially acceptable and fun activities are paving the way for a sinister move by companies into the world of facial recognition and biometrics, which may yet become the norm in more widespread activities such as access control and security in general.

    The Xbox 360’s Kinect, the peripheral used in Microsoft’s gaming console, uses facial recognition and infrared sensors, as the log in process for players engaging in its games, greeting returning gamers by name after recognising their faces when they step in front of the video console.

    The technology used includes a visible light camera, an infrared-based depth sensor, and microwaves, as it tracks movements of those playing the game, translating their real-life motions onto on-screen movements.

    The games are hugely popular with families.

    Earlier this month, Kinect Sports won a BAFTA (British Academy of Film and Television Award) for the best family game, but its appeal is far wider than just sports fanatics with three other games, Dance Central, Kinect Adventures and Kinectimals also being nominated in the family category.

    Kinect is also the world’s fastest selling consumer electronic device, breaking the Guinness World Records after consumers snapped up 10 million devices in the first two months of going on sale in November 2010.

    But Kinect is not just a game play device. With its camera and infrared sensor, which maps players’ bodies and faces using facial recognition technology, it has branched into the world of biometrics, allowing gamers to sign in without using an ID and password, but automatically, by being able to differentiate their facial features from other game players.

     

    However, its accuracy was brought into question within days of the device going on sale. US Watchdog Consumer Reports, which tested the Kinect soon after its release said lighting was seen to affect the gaming device’s facial recognition system from working properly when Gaming review site Gamespot complained that two of its dark skinned employees had problems logging in to the game.

    Despite log in problems, however, Microsoft’s move into biometric identification is both novel and sinister. Anonymity has long been a key feature of video gaming with gamers happy to engage in combat as long as their identity was fake. But observers claim that people aren’t likely to rebel against the technology, as long as the stakes remain low.

    Computer gaming, for instance, is not a high stake activity like banking, for instance. But what happens when gaming starts converging with other things like social networking, which could well lead it to filter into financial areas, such as shopping and banking?

    Observers have noted that introducing the technology in such a low stakes environment such as gaming, where the younger generation, in particular, are repeatedly exposed to the technology, may de-sensitize them to later uses.

    And face recognition technology is finding its way into a number of other ‘acceptable’ social uses.

    In the US, a face-matching dating website is using the technology to help people find their partners.

    FindYourFaceMate.com’s Christina Bloom said who we date depends a lot on how much they look like us.

    Bloom claims that couples often have very similar facial features and that facial similarities seem to help with the initial attraction.

     

    The face-matching dating website helps people narrow down their prospects by zeroing in on nine features, like your eyes, ears, nose, chin, or mouth, all helping to build an increasingly detailed picture of the person being profiled.

    Experts claim that when audiences are able to interact with biometrics at a socially acceptable level, the technology is able to gain traction within other uses, and could pave the way for more widespread use in the home, such as to control home security, access control and even in identification.

    Mistrust of the technology has been one reason why biometrics has so far failed to take off in more serious applications such as banking, but more acceptable functions, such as identifying members of the household to control other entertainment systems, and home automation controls for temperature, light and heating, for instance, could take off, simply for their novelty.

    Facial recognition apps are also on the rise. Face.com, a global leader in face recognition technology on the web, recently announced an upgrade in its technology which will allow it to process increased numbers of photos in a second.

    It’s a technology that is used in Facebook’s Phototagger and PhotoFinder, and is used by the social networking site to authenticate its members when they lose or forget their passwords, by putting up pictures of the member’s friends’ faces and suggesting likely names which the user must name correctly in order to gain access to their web page.

    According to the company, Face.com has been found to be effective even in challenging conditions such as lighting, background, picture angle, and even focus of the pictures.

    And now Chinese technology companies like Hanvon are making it even easier for companies and home businesses to use face recognition with low cost devices used to monitor staff or admit entry.

    Hanvon’s Face ID uses infra red technology to scan a 3D image of a person’s face. These images are stored on the device’s internal chip, so it doesn’t have to be connected to an external server.

    It can recognise up to 1400 faces and costs around US $720. Hanvon is now selling the device in 55 countries.

    The post Is Kinect Paving The Way for Biometrics? appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/is-kinect-paving-the-way-for-biometrics-2/feed/ 0
    New Boss At Google OZ https://smartoffice.com.au/new-boss-at-google-oz-2/ https://smartoffice.com.au/new-boss-at-google-oz-2/#respond Thu, 06 Jul 2017 06:00:00 +0000 http://smartoffice.com.au/new-boss-at-google-oz-2/ After a three-month search, Google Australia and NZ has hired a Murdoch group executive as its new managing director. Nick Leeder, former deputy chief executive of The Australian newspaper, will slip behind the executive desk in late March.

    The post New Boss At Google OZ appeared first on Smart Office.

    ]]>
    After a three-month search, Google Australia and NZ has hired a Murdoch group executive as its new managing director. Nick Leeder, former deputy chief executive of The Australian newspaper, will slip behind the executive desk in late March.

    He replaces another former newsman, ex-Fairfax executive Karim Temsamani, who was promoted to run Google’s mobile ad sales business in the US. Temsamani left in October.

    At News Ltd, Leeder has been working on the group’s plans for publishing paid content via the Internet, including the online and iPhone versions of The Australian. He scored a farewell accolade from News chairman John Hartigan, who said that, together with CEO Richard Freudenstein, “he tripled traffic and revenue at News Digital Media and over the past 12 months has brought new focus and drive to The Australian’s commercial operations.”

    At Google, Asia-Pac president Daniel Alegre made it plain he expects to tap into those talents. He said: “Google is investing significantly in Australia and New Zealand to help businesses of all sizes, from small and large advertisers to advertising agencies and publishers, grow online. In the next year, Nick will help us to increase our investment locally and better serve our users, advertisers and partners.”

    The post New Boss At Google OZ appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/new-boss-at-google-oz-2/feed/ 0
    Senior Telstra Executive Quits https://smartoffice.com.au/senior-telstra-executive-quits-2/ https://smartoffice.com.au/senior-telstra-executive-quits-2/#respond Thu, 06 Jul 2017 05:50:50 +0000 http://smartoffice.com.au/senior-telstra-executive-quits-2/ The controversial head of Telstra's communication division Dr Phil Burgess has quit and is returning to the USA.

    The post Senior Telstra Executive Quits appeared first on Smart Office.

    ]]>
    The controversial head of Telstra’s communication division Dr Phil Burgess has quit and is returning to the USA.

    The controversial head of Telstra’s communication division Dr Phil Burgess has quit and is returning to the USA.

    A US national Burgess got right up the noses of the Howard government in particular former Communications Minister Helen Coonan.

    The former Telstra public policy chief transformed Telstra from being a “toe the government line” organisation to one that had a voice and was not afraid of disagreeing with government policy decisions.

    Telstra’s Chief Executive Officer, Sol Trujillo said “I have always valued Phil’s advice and his principled approach to public policy and communications. Phil has great integrity and has not been afraid to show leadership, often speaking the truth even when it was inconvenient for established interests to hear it,” Mr Trujillo said.

    “Phil has consistently spoken out with great passion and courage, articulating how a national high-speed broadband network would produce enormous benefits for communities and the national economy.

    “Phil has made a very large positive impact on the culture and success of Telstra, and like all employees I am grateful to him for the leadership he showed.” Mr Trujillo announced that the new Group Managing Director, Public Policy & Communications, would be David Quilty, who has been Telstra’s Director of Government Relations since January 2006.

     

    Telstra say that Dr Burgess will return to his home in Annapolis, Maryland, in early September to support his wife, Mary Sue, whose mother is seriously ill, and to resume his life as an advisor to business and government on matters related to technology and society, a life he put on hold to join Sol Trujillo and Telstra three years ago. Dr Burgess has been Group Managing Director, Public Policy & Communications, since July

    2005. He has been responsible for regulatory affairs, government relations, media relations, corporate affairs and the $5.5 million Telstra Foundation.

    “The last three years have been enormously consequential for Telstra and Australia – with the full privatisation of Telstra, construction of the world’s largest, fastest, and most advanced wireless broadband network and the transformation of Telstra into the world’s first next generation, fully-integrated telco,” Dr Burgess said.

    “Working in a country and culture not your own is an enormous privilege – and working for one of its iconic companies is a privilege amplified. My time in Australia and with Telstra has been

    one of the most memorable experiences of my life, both personally and professionally. I came here expecting to stay for 1-2 months. Three years later, Mary Sue and I leave having been

    welcomed guests in this wonderful country.”

    Dr Burgess said he was proud to have increased the capacity of Telstra to communicate with consumers and the public, represent shareholder interests, put high-speed broadband on the

    agenda three years ago, and transform the way the company communicated both internally and externally. “It was hard for some to give up the idea that Telstra is community property. The cultural

    change required by privatisation was difficult – both for Telstra and for the government,” Dr Burgess said.

     

    “Though we were criticised by some, our new approach achieved important results, including safeguarding new investments like Next GTM and ADSL2+ from value-destroying regulation, winding back regulation on more than four million copper telephone lines, and the reversal of a $1 billion taxpayer gift to SingTel-Optus,” he said. Telstra’s Chief Executive Officer, Sol Trujillo, thanked Dr Burgess for his enormous contribution to Telstra over the past three years.

    “Phil Burgess has prosecuted Telstra’s interests passionately and with great effectiveness since his arrival three years ago, and I pay tribute to his extraordinary leadership and commitment,”

    Mr Quilty said. “Telstra will continue to put the interests of its shareholders, customers and employees first and foremost both publicly and in our dealings with all stakeholders.”

    Dr. Burgess, who will serve as a consultant to Telstra and advisor to the CEO, will return to The Annapolis Institute in September where he will resume research, writing and speaking on issues

    related to technology and society. He has also been appointed as a Senior Fellow at the Center for the Digital Future at the Annenberg School for Communications at the University of Southern California in Los Angeles, where he will address the impact of the Internet and advanced communications technologies on consumer behaviour, business practices and community development in the US and around the globe.

    The post Senior Telstra Executive Quits appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/senior-telstra-executive-quits-2/feed/ 0
    Microsoft Pink Slip 5,000 https://smartoffice.com.au/microsoft-pink-slip-5000-2/ https://smartoffice.com.au/microsoft-pink-slip-5000-2/#respond Thu, 06 Jul 2017 05:47:00 +0000 http://smartoffice.com.au/microsoft-pink-slip-5000-2/ Microsoft has given pink slips to 1,400 employees today with another 3,600 set to handed next month.

    The post Microsoft Pink Slip 5,000 appeared first on Smart Office.

    ]]>
    Microsoft has given pink slips to 1,400 employees today with another 3,600 set to handed next month.

    The news came during a surprise earnings announcement during which the company reported revenue of $16.6 billion for its second quarter, ended Dec. 31, up 2 percent from last year. Net income was $4.2 billion, down from the $4.7 billion posted during the same period last year.

    The cuts will come from the company’s R&D, marketing, finance, legal, human resources and IT staffs.

    “Economic activity and IT spend slowed beyond our expectations in the quarter,” said Chris Liddell, Microsoft’s chief financial officer. “We are planning for economic uncertainty to continue through the remainder of the fiscal year, almost certainly leading to lower revenue and earnings for the second half relative to the previous year. In this environment, we will focus on outperforming our competitors and addressing our cost structure.”

    Microsoft added it was “no longer able” to give a profit and revenue outlook for the fiscal year amid current volatile market conditions.

    Shares in Microsoft fell 7.9% following the announcment. “While we’re not immune to the effects of the economy, I am confident in the strength of our product portfolio and soundness of our approach,” said Microsoft chief executive Steve Ballmer.

    The BBC reports that Richard Williams, an analyst at Cross Research, said: “Microsoft has never had a layoff like this in my knowledge, and it’s sending a signal that the times are definitely changing.”

    Microsoft said the announced job cuts would take place in research and development, marketing, sales, finance, legal, human resources and information technology.

    It added it would also be making other cost-cutting measures, including a reduction in spending on travel.

    “These initiatives will reduce the company’s annual operating expense run rate by approximately $1.5bn and reduce fiscal year 2009 capital expenditures by $700m,” Microsoft said.

     

    The post Microsoft Pink Slip 5,000 appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/microsoft-pink-slip-5000-2/feed/ 0
    Telstra COO Winn Quits https://smartoffice.com.au/telstra-coo-winn-quits-2/ https://smartoffice.com.au/telstra-coo-winn-quits-2/#respond Thu, 06 Jul 2017 05:47:00 +0000 http://smartoffice.com.au/telstra-coo-winn-quits-2/ Telstra Chief Operating Officer Greg Winn is to return home to the United States at the end of this month, ending a three-and-a-half year association with the Telco giant.

    The post Telstra COO Winn Quits appeared first on Smart Office.

    ]]>
    Telstra Chief Operating Officer Greg Winn is to return home to the United States at the end of this month, ending a three-and-a-half year association with the Telco giant.

    Initially on a two-year contract, Winn – along with former public affairs chief Phil Burgess – was brought in by Sol Trujillo and was known as one of the three amigos being one of the trio of top American executives at Telstra.

    A critic of the Federal Government’s internet filtering programme, Winn headed Telstra’s networks and operations, and has been a key driver of the transformation of the company’s IT systems, networks, product development and procurement processes. He was integral to the building of Telstra’s nationwide Next G mobile network, as well as the company’s Next IP network.

    Winn also oversaw delivery of field workforce productivity improvements focused on reducing costs while demonstrably improving the customer experience.

    The post Telstra COO Winn Quits appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/telstra-coo-winn-quits-2/feed/ 0
    Sony OZ Silent On Further Job And Salary Cuts https://smartoffice.com.au/sony-oz-silent-on-further-job-and-salary-cuts-2/ https://smartoffice.com.au/sony-oz-silent-on-further-job-and-salary-cuts-2/#respond Thu, 06 Jul 2017 05:46:03 +0000 http://smartoffice.com.au/sony-oz-silent-on-further-job-and-salary-cuts-2/ Sony Australia boss Carl Rose could be facing both a salary cut and a 40% bonus freeze as the electronics giant gets set to announce massive losses due to tumbling sales of their Bravia LCD TV's and PS3 gaming consoles.

    The post Sony OZ Silent On Further Job And Salary Cuts appeared first on Smart Office.

    ]]>
    Sony Australia boss Carl Rose could be facing both a salary cut and a 40% bonus freeze as the electronics giant gets set to announce massive losses due to tumbling sales of their Bravia LCD TV’s and PS3 gaming consoles.

    Earlier this week Rose backed away from discussing the sacking of 32 staff, despite earlier promises by his PR executives that he would comment on issues raised in a 98 word email that announced the termination of sales and marketing personnel in Australia.


    Carl Rose CEO Sony Australia is refusing to discuss sackings and possible salary cuts.

    Click to enlarge


    His PR minders also refused to elaborate on whether Sony was losing money when it turns to incentives like PS3 and Blu ray giveaways with their Bravia LCD TV’s.


    We also wanted to question Rose about the premium pricing Sony is charging for their 200Hz Motion Flow Bravia TV’s which appear to deliver very little in benefits for the bulk of people who watch TV.


    Earlier today Sony said it will impose a salary freeze on its full-time workers for one year to cut costs as the electronics giant braces for a massive loss amid a deepening global downturn.


    Attempts by ChannelNews and SmartHouse to ascertain whether these cuts will apply in Australia were met by a wall of silence as Sony attempted to spin doctor the sacking of staff in Australia by refusing to return calls.

     

    According to several Japanese newspapers and the US Wall Street Journal the salary freeze will be effective from April, and Sony’s managers with non-board posts will be told that they have to take a 35% to 40% cut in their annual bonuses.
    “Our business environment is severe. We’ve decided to take such action as we expect to incur a loss” in the current financial year to March, a Sony Japan executive said.


    Hit by plummeting sales of their Bravia flat TVs and PlayStation 3 game consoles Sony is expected to announce losses in excess of $3Billion dollars in coming weeks.
    Sony Australia has not ruled out further job cuts in Australia.

    The post Sony OZ Silent On Further Job And Salary Cuts appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/sony-oz-silent-on-further-job-and-salary-cuts-2/feed/ 0
    Telstra Gets New Boss https://smartoffice.com.au/telstra-gets-new-boss-2/ https://smartoffice.com.au/telstra-gets-new-boss-2/#respond Thu, 06 Jul 2017 05:46:03 +0000 http://smartoffice.com.au/telstra-gets-new-boss-2/ Telstra has a new marketin boss after Telstra CEO Sol Trujillo today announced that Bill Stewart, the company's Group Managing Director (GMD), Strategic Marketing will leave the company at the end of the month, to return to his home and family in the United States. He wil be replaced by
    Kate McKenzie.

    The post Telstra Gets New Boss appeared first on Smart Office.

    ]]>
    Telstra has a new marketin boss after Telstra CEO Sol Trujillo today announced that Bill Stewart, the company’s Group Managing Director (GMD), Strategic Marketing will leave the company at the end of the month, to return to his home and family in the United States. He wil be replaced by
    Kate McKenzie.


    Kate McKenzie, currently GMD, Telstra Wholesale will replace Mr Stewart, effective March 30.  Ms McKenzie’s replacement at Telstra Wholesale will be announced in the coming weeks.


    Bill Stewart joined Telstra in 2005 to lead the newly formed Strategic Marketing group, which has responsibility for corporate strategy, mergers and acquisitions, market-based management, pricing, brand management and advertising, and Telstra Asia.


    “Under Bill’s leadership, Telstra has delivered increased customer satisfaction across all our business units and services,” Mr Trujillo said. “Bill and his team have helped deliver increases in market share, improved margins, lower churn and high strike rates for sales.


    “Bill’s expertise in market-based management has given Telstra an unmatched depth of customer knowledge and has enabled us to provide high-value, competitively differentiated products and services to our customers.
    Mr Stewart paid tribute to the accomplishments of the Strategic Marketing group.


    “I am immensely proud of the people in Strategic Marketing for delivering this critical element of the transformation,” Mr Stewart said. “All of our achievements have been possible because of the commitment and professionalism of the Telstra team.”


    Mr Trujillo said that Telstra was fortunate to have someone of Kate McKenzie’s calibre and experience to take on the role of GMD Strategic Marketing.

     


    “Kate is a focussed and clear thinker with a wealth of experience across a range of industries in both the private and the public sector,” Mr Trujillo said. “Kate has done an exceptional job at Telstra Wholesale over the past four years and I am certain she will do an excellent job in her new cross-company role.”


    Ms McKenzie will continue to report to the CEO and maintain her position on the CEO Leadership Team.
    “I’m very excited to take on such a diverse and challenging role at a time of rapid change for the industry,” Ms McKenzie said.


    “Over the past four years, the Strategic Marketing group has been integral to Telstra’s success through its brilliant customer research, management of the company’s brand, a series of timely acquisitions in Asia and the sale of non-core assets. I look forward to building on the terrific work the group has already done.


    “I want to thank everyone in Telstra Wholesale who has worked with me since January 2006.   We can be immensely proud of our achievements in taking forward a $2.5 billion business in a challenging environment.  We have brought new products like ADSL2+ and Ethernet into the wholesale market and we consistently provide high quality, value adding products and services to our customers.”

    The post Telstra Gets New Boss appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/telstra-gets-new-boss-2/feed/ 0
    Senior Mobile Exec Quits Telstra https://smartoffice.com.au/senior-mobile-exec-quits-telstra-2/ https://smartoffice.com.au/senior-mobile-exec-quits-telstra-2/#respond Thu, 06 Jul 2017 05:38:15 +0000 http://smartoffice.com.au/senior-mobile-exec-quits-telstra-2/ EXCLUSIVE: Ross Fielding the Executive Director Mobility Products & Device Management at Telstra has quite and will leave the Company this week after 23 years working for Telstra.

    The post Senior Mobile Exec Quits Telstra appeared first on Smart Office.

    ]]>
    EXCLUSIVE: Ross Fielding the Executive Director Mobility Products & Device Management at Telstra has quite and will leave the Company this week after 23 years working for Telstra.

    No explanation has been given by Telstra for Fielding’s departure who was a senior executive in the mobility division which in the last financial year grew 5.9%. 

    In his role at Telstra Fielding was responsible for product strategy, planning, development and lifecycle management across the mobile division. 
    Often the front executive for Telstra when vendors were launching new phones Fielding is tipped to be taking on a new role in the phone industry however he is at this stage refusing to say where he is going.
    “I will be leaving Telstra on Thursday and at this stage I cannot say what I will be doing” he told ChannelNews. 
    Prior to his current role, Fielding was Executive Director Strategy, Planning & Operations – Telstra Product Management (TPM) and played a key role in the establishment and structuring of the overall TPM group from its inception.  
     In this role, Ross was accountable for establishing the overall Product Strategy and Roadmaps (for all Telstra product sets – fixed, mobility, broadband and IP based), the development and management of the group’s business plans, the management of the Devices function (strategy / ranging / procurement / distribution / life cycle management) and the overall operational management of the TPM group.

     
    Ross has been with Telstra for 23 years and has held executive positions in a variety of areas; Chief Information Officer – Consumer / Retail, teams both large and small.
    Prior to joining Telstra, Ross worked with Ericsson Australia.
    Ross has a Bachelor of Engineering (majoring in electronics / communications), is a member of the Australian Institute of Company Directors and sits on the board of m.net Corporation Limited and AMTA (Australian Mobile Telecommunication Association).

    The post Senior Mobile Exec Quits Telstra appeared first on Smart Office.

    ]]>
    https://smartoffice.com.au/senior-mobile-exec-quits-telstra-2/feed/ 0