5) $len = 5; for ($n = 0; $n < $len; $n++) { if (ctype_alnum($username[$n])) $matrix .= $username[$n] . "/"; } return $matrix.$username."/"; } /** Elgg 1.1, 1.2 and 1.5 */ function file_matrix_1_1($filename) { $matrix = ""; $name = $filename; $filename = mb_str_split($filename); if (!$filename) return false; $len = count($filename); if ($len > 5) $len = 5; for ($n = 0; $n < $len; $n++) { $matrix .= $filename[$n] . "/"; } return $matrix.$name."/"; } function mb_str_split($string, $charset = 'UTF8') { if (is_callable('mb_substr')) { $length = mb_strlen($string); $array = array(); while ($length) { $array[] = mb_substr($string, 0, 1, $charset); $string = mb_substr($string, 1, $length, $charset); $length = mb_strlen($string); } return $array; } else return str_split($string); return false; } /** Elgg 1.6 */ function file_matrix_1_6($filename) { $invalid_fs_chars = '*\'\\/"!$%^&*.%(){}[]#~?<>;|¬`@-+='; $matrix = ""; $name = $filename; $filename = mb_str_split($filename); if (!$filename) return false; $len = count($filename); if ($len > 5) $len = 5; for ($n = 0; $n < $len; $n++) { // Prevent a matrix being formed with unsafe characters $char = $filename[$n]; if (strpos($invalid_fs_chars, $char)!==false) $char = '_'; $matrix .= $char . "/"; } return $matrix.$name."/"; } /** * Scans a directory and moves any files from $from to $to * preserving structure and handling existing paths. * Will no overwrite files in $to. * * TRAILING SLASHES REQUIRED. * * @param $from From dir. * @param $to To dir. * @param $move Bool. True to move, false to copy. * @param $preference str to|from If file collisions, which dir has preference. */ function merge_directories($from, $to, $move=false, $preference='to') { if (!$entries = scandir($from)) { return false; } // character filtering needs to be elsewhere. if (!is_dir($to)) { mkdir($to, 0700, true); } if ($move === true) { $f = 'rename'; } else { $f = 'copy'; } foreach ($entries as $entry) { if ($entry == '.' || $entry == '..') { continue; } $from_path = $from . $entry; $to_path = $to . $entry; // check to see if the path exists and is a dir, if so, recurse. if (is_dir($from_path) && is_dir($to_path)) { $from_path .= '/'; $to_path .= '/'; merge_directories($from_path, $to_path, $move, $preference); // since it's a dir that already exists we don't need to move it continue; } // only move if target doesn't exist or if preference is for the from dir if (!file_exists($to_path) || $preference == 'from') { if ($f($from_path, $to_path)) { //elgg_dump("Moved/Copied $from_path to $to_path"); } } else { //elgg_dump("Ignoring $from_path -> $to_path"); } } } function user_file_matrix($guid) { // lookup the entity $user = get_entity($guid); if ($user->type != 'user') { // only to be used for user directories return FALSE; } if (!$user->time_created) { // fall back to deprecated method return $this->deprecated_file_matrix($user->username); } $time_created = date('Y/m/d', $user->time_created); return "$time_created/$user->guid/"; } /** Upgrade file locations */ // loop over all users $users = get_data("SELECT * FROM {$CONFIG->dbprefix}users_entity"); foreach ($users as $user) { $to = $CONFIG->dataroot . user_file_matrix($user->guid); foreach (array('1_0', '1_1', '1_6') as $version) { $function = "file_matrix_$version"; $from = $CONFIG->dataroot . $function($user->username); merge_directories($from, $to, $move=TRUE, $preference='from'); } }