libdir.'/adminlib.php'); require_once($CFG->libdir.'/gdlib.php'); require_once($CFG->libdir.'/clilib.php'); // cli only functions // now get cli options list($options) = cli_get_params(array('dir'=>'')); define ('PIX_FILE_UPDATED', 0); define ('PIX_FILE_ERROR', 1); define ('PIX_FILE_SKIPPED', 2); @set_time_limit(0); raise_memory_limit(MEMORY_EXTRA); process_directory($options['dir'], 'username', 'true', $results); exit; // ----------- Internal functions ---------------- /** * Recursively process a directory, picking regular files and feeding * them to process_file(). * * @param string $dir the full path of the directory to process * @param string $userfield the prefix_user table field to use to * match picture files to users. * @param bool $overwrite overwrite existing picture or not. * @param array $results (by reference) accumulated statistics of * users updated and errors. * * @return nothing */ function process_directory ($dir, $userfield, $overwrite, &$results) { if(!($handle = opendir($dir))) { echo 'cannotprocessdir'; return; } while (false !== ($item = readdir($handle))) { if ($item != '.' && $item != '..') { if (is_dir($dir.'/'.$item)) { process_directory($dir.'/'.$item, $userfield, $overwrite, $results); } else if (is_file($dir.'/'.$item)) { $result = process_file($dir.'/'.$item, $userfield, $overwrite); switch ($result) { case PIX_FILE_ERROR: $results['errors']++; break; case PIX_FILE_UPDATED: $results['updated']++; break; } } // Ignore anything else that is not a directory or a file (e.g., // symbolic links, sockets, pipes, etc.) } } closedir($handle); } /** * Given the full path of a file, try to find the user the file * corresponds to and assign him/her this file as his/her picture. * Make extensive checks to make sure we don't open any security holes * and report back any success/error. * * @param string $file the full path of the file to process * @param string $userfield the prefix_user table field to use to * match picture files to users. * @param bool $overwrite overwrite existing picture or not. * * @return integer either PIX_FILE_UPDATED, PIX_FILE_ERROR or * PIX_FILE_SKIPPED */ function process_file ($file, $userfield, $overwrite) { global $DB; // Add additional checks on the filenames, as they are user // controlled and we don't want to open any security holes. $path_parts = pathinfo(cleardoubleslashes($file)); $basename = $path_parts['basename']; $extension = $path_parts['extension']; // The picture file name (without extension) must match the // userfield attribute. $uservalue = substr($basename, 0, strlen($basename) - strlen($extension) - 1); // userfield names are safe, so don't quote them. if (!($user = $DB->get_record('user', array ($userfield => $uservalue, 'deleted' => 0)))) { $a = new stdClass(); $a->userfield = clean_param($userfield, PARAM_CLEANHTML); $a->uservalue = clean_param($uservalue, PARAM_CLEANHTML); echo 'usernotfound - '.$a."\n"; return PIX_FILE_ERROR; } $haspicture = $DB->get_field('user', 'picture', array('id'=>$user->id)); if ($haspicture && !$overwrite) { echo 'userskipped - '.$user->username."\n"; return PIX_FILE_SKIPPED; } if (my_save_profile_image($user->id, $file)) { $DB->set_field('user', 'picture', 1, array('id'=>$user->id)); echo 'userupdated - '.$user->username."\n"; return PIX_FILE_UPDATED; } else { echo 'cannotsave - '.$user->username."\n"; return PIX_FILE_ERROR; } } /** * Try to save the given file (specified by its full path) as the * picture for the user with the given id. * * @param integer $id the internal id of the user to assign the * picture file to. * @param string $originalfile the full path of the picture file. * * @return bool */ function my_save_profile_image($id, $originalfile) { $context = get_context_instance(CONTEXT_USER, $id); return process_new_icon($context, 'user', 'icon', 0, $originalfile); }