<?php
// $Id$

function _profile_init() {
  /*
  ** Add here any field you might need.  Leave array[0] blank if you
  ** need a special tool (like birthday or avatar).
  **  TODO: add a clear description/explanation.
  */

  $GLOBALS["profile_fields"] = array(
    "realname"      => array("textfield", t("Name"), "", 64, 64, ""),
    "address"       => array("textfield", t("Address"), "", 64, 64, ""),
    "city"          => array("textfield", t("City"), "", 64, 64, ""),
    "state"         => array("textfield", t("State, province or region"), "", 64, 64, ""),
    "zip"           => array("textfield", t("Zip or postal code"), "", 7, 10, ""),
    "country"       => array("textfield", t("Country"), "", 64, 64, ""),
    "birthday"      => array("", t("Birthday"), ""),
    "gender"        => array("select", t("Gender"), "", array(0 => "-", "m" => t("male"), "f" => t("female")), "", 0, 0),
    "job"           => array("textfield", t("Job title"), "", 64, 64, ""),
    "icq"           => array("textfield", t("ICQ messenger ID"), "", 12, 12, ""),
    "msn"           => array("textfield", t("MSN messenger ID"), "", 64, 64, ""),
    "yahoo"         => array("textfield", t("Yahoo messenger ID"), "", 64, 64, ""),
    "aim"           => array("textfield", t("AIM messenger ID"), "", 64, 64, ""),
    "homepage"      => array("textfield", t("URL of homepage"), "", 64, 64, t("Make sure you enter a fully qualified URL: remember to include \"http://\".")),
    "biography"     => array("textarea", t("Biography"), "", 64, 4, ""),
    "interests"     => array("textarea", t("Interests"), "", 64, 4, ""),
    "publickey"     => array("textarea", t("Public key"), "", 64, 4, ""),
    "avatar"        => array("", t("Avatar or picture"), t("Your virtual face or picture.  Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get("profile_avatar_dimensions", "85x85"), "%size" => variable_get("profile_avatar_file_size", "30"))))
  );

  $GLOBALS["profile_days"] = array_merge(array(0 => t("day")), drupal_map_assoc(range(1, 31)));
  $GLOBALS["profile_months"] = array(0 => t("month"), 1 => t("January"), 2 => t("February"), 3 => t("March"), 4 => t("April"), 5 => t("May"), 6 => t("June"), 7 => t("July"), 8 => t("August"), 9 => t("September"), 10 => t("October"), 11 => t("November"), 12 => t("December"));
}

function profile_help($section) {
  $output = "";

  switch ($section) {
    case 'admin/system/modules#description':
      $output = t("Support for configurable user profiles.");
      break;
    case 'admin/system/modules/profile':
      $output = t("When a user creates an account you can ask for some extra information, as well as letting the user have a small picture, called an avatar.  <ul><li>In order for a user to enter information, you <strong>must</strong> check <em>enable</em>.</li><li>In order for other people to see the entered information, you must make it <em>public</em>.</li><li>If an item is <em>public</em>, but not enabled, the user can never give it a value and it will never be seen.  <em>Public</em> does <strong>not</strong> imply <em>enable</em>.</li></ul>", array("%edit" => url("user/edit")));
      break;
  }
  return $output;
}

function profile_settings() {
  global $profile_fields;

  if (!$profile_fields) {
    _profile_init();
  }

  if (!file_check_directory(file_create_path(variable_get('profile_avatar_path', 'avatars')))) {
    $error['profile_avatar_path'] = theme('error', t('Directory does not exist, or is not writable.'));
  }

  $profile_public_fields = variable_get("profile_public_fields", array());
  $profile_private_fields = variable_get("profile_private_fields", array());
  $profile_required_fields = variable_get("profile_required_fields", array());

  $header = array(t("field"), t("enable"), t("public"), t("required"));
  $i = 0;
  foreach ($profile_fields as $key => $field) {
    $row[$i][] = $field[1];
    $row[$i][] = form_checkbox("", "profile_private_fields][", $key, in_array($key, $profile_private_fields));
    $row[$i][] = form_checkbox("", "profile_public_fields][", $key, in_array($key, $profile_public_fields));
    $row[$i][] = form_checkbox("", "profile_required_fields][", $key, in_array($key, $profile_required_fields));
    $i++;
  }

  $avatar  = form_textfield(t("Avatar image path"), "profile_avatar_path", variable_get("profile_avatar_path", "avatars"), 30, 255, t("Subdirectory in the directory '%dir' where avatars will be stored.", array('%dir' => variable_get('file_directory_path', 'files') . FILE_SEPARATOR)) . $error['profile_avatar_path']);
  $avatar .= form_textfield(t("Avatar maximum dimensions"), "profile_avatar_dimensions", variable_get("profile_avatar_dimensions", "85x85"), 10, 10, t("Maximum dimensions for avatars."));
  $avatar .= form_textfield(t("Avatar maximum file size"), "profile_avatar_file_size", variable_get("profile_avatar_file_size", "30"), 10, 10, t("Maximum file size for avatars, in kB."));

  $output  = theme("table", $header, $row);
  $output .= form_group(t('Avatars'), $avatar);

  return $output;
}

function profile_user($type, $edit, &$user) {
  global $profile_fields;
  if (!$profile_fields) {
    _profile_init();
  }

  switch ($type) {
    case "edit_form":
      // when user tries to edit his own data
      return _profile_form(object2array($user), "private");
    case "edit_validate":
      // validate user data editing
      return _profile_validate($edit, "private", $user);
    case "view_public":
      // when others look at user data
      return _profile_user_view($user, "public");
    case "view_private":
      // when user looks at his own data
      return _profile_user_view($user, "private");
  }
}

function profile_required($title) {
  // this pleads "theme, theme" ;)
  return $title ." ". theme("mark");
}

function _profile_form($edit, $mode) {
  global $profile_fields, $user;

  $reg_fields = _profile_active_fields($mode);
  $required_fields = _profile_active_fields("required");

  foreach ($profile_fields as $name => $field) {
    if ($field[0] && in_array($name, $reg_fields)) {
      $f = "form_". $field[0];
      $t = "profile_". $name;
      $output .= $f((in_array($name, $required_fields) ? profile_required($field[1]) : $field[1]), $t, $edit[$t], $field[3], $field[4], $field[5], $field[6]);
    }
  }

  if (in_array("birthday", $reg_fields)) {
    $output .= form_item((in_array("birthday", $required_fields) ? profile_required($profile_fields["birthday"][1]) : $profile_fields["birthday"][1]), _profile_edit_birth(array2object($edit)), $profile_fields["birthday"][2]);
  }

  if (in_array("avatar", $reg_fields)) {
    if ($edit["profile_avatar"] && file_exists($edit["profile_avatar"])) {
      $output .= form_item(t("Avatar"), '<img src="'. file_create_url($edit["profile_avatar"]) .'" alt="" title="" />');
    }
    $output .= form_file($profile_fields["avatar"][1], "profile_avatar", 64, $profile_fields["avatar"][2]);
  }

  return array(t('Personal information') => $output);
}

function _profile_validate($edit, $mode, $user) {

  global $profile_fields;

  $enabled_fields = _profile_active_fields($mode);

  if (in_array("birthday", $enabled_fields) && ($birth_error = _profile_validate_birth($edit))) {
    $error .= $birth_error ."<br />";
  }

  if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) {
    $error .= $avatar_error ."<br />";
  }

  foreach (array_keys($profile_fields) as $field) {
    // replicate any key which was saved during registration but is not in this form
    if (!$edit[$field] && $user->$field) {
      $edit[$field] = $user->$field;
    }
  }

  // now check for required fields
  foreach (_profile_active_fields("required") as $required) {
    if ($required != "0" && in_array($required, $enabled_fields)) {
      if (!$edit["profile_". $required]) {
        $error .= t("This required field is missing: %a", array("%a" => $profile_fields[$required][1])) ."<br />";
      }
    }
  }

  return $error ? $error : $edit;
}

function _profile_user_view(&$user, $mode) {
  global $profile_fields;

  foreach (_profile_active_fields($mode) as $name) {
    $field = $profile_fields[$name];
    $t = "profile_". $name;

    if (!empty($user->$t)) {
      switch ($field[0]) {
        case "textfield":
        case "textarea":
        case "checkbox":
          $value = ($t == "profile_homepage") ? "<a href=\"". drupal_specialchars($user->$t) ."\">". check_output($user->$t) ."</a>" : check_output($user->$t);
          $output .= form_item($field[1], $value);
          break;
        case "select":
          $output .= form_item($field[1], check_output($profile_fields[$name][3][$user->$t]));
          break;
        case "":
          // special
          if ($t == "profile_avatar") {
            if (file_exists($user->$t)) {
              $output .= form_item(t("Avatar"), '<img src="'. file_create_url($user->$t) .'" alt="" title="" />');
            }
          }

          if ($t == "profile_birthday") {
            if (isset($user->profile_birthday) && isset($user->profile_birthmonth) && isset($user->profile_birthyear)) {
              // this is very european-centric, can we use format_date?
              $time = mktime(0, 0, 0, $user->profile_birthmonth, $user->profile_birthday, $user->profile_birthyear);
              $output .= form_item(t("Birthday"), format_date($time, "custom", "F j, Y"));
            }
          }
      }
    }
  }
  return $output;
}

function profile_file_download($file) {
  if (strpos($file, variable_get("profile_avatar_path", "avatars") . FILE_SEPARATOR . 'avatar-') === 0) {
    list($width, $height, $type, $attr) = getimagesize(file_create_path($file));
    $types = array(
      IMAGETYPE_GIF => 'image/gif',
      IMAGETYPE_JPEG => 'image/jpeg',
      IMAGETYPE_PNG => 'image/png',
      IMAGETYPE_SWF => 'application/x-shockwave-flash',
      IMAGETYPE_PSD => 'image/psd',
      IMAGETYPE_BMP => 'image/bmp',
      IMAGETYPE_TIFF_II => 'image/tiff',
      IMAGETYPE_TIFF_MM  => 'image/tiff',
      IMAGETYPE_JPC => 'application/octet-stream',
      IMAGETYPE_JP2 => 'image/jp2',
      IMAGETYPE_JPX => 'application/octet-stream',
      IMAGETYPE_JB2 => 'application/octet-stream',
      IMAGETYPE_SWC => 'application/x-shockwave-flash',
      IMAGETYPE_IFF => 'image/iff',
      IMAGETYPE_WBMP => 'image/vnd.wap.wbmp',
      IMAGETYPE_XBM => 'image/xbm'
    );
    return array('Content-type: '. $types[$type]);
  }
}

function _profile_validate_avatar(&$edit, $user) {
  // check that uploaded file is an image, with a maximum file size and maximum height/width

  unset($edit["profile_avatar"]);

  if (!$file = file_check_upload('profile_avatar')) {
    $edit["profile_avatar"] = $user->profile_avatar;
    return;
  }

  $extension = strtolower(strrchr($file->name, "."));
  $size = getimagesize($file->path);
  list($maxwidth, $maxheight) = explode("x", variable_get("profile_avatar_dimensions", "85x85"));
  if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
    $error = t("The uploaded file was not an image.");
  }
  else if ($file->size > (variable_get("profile_avatar_file_size", "30") * 1000)) {
    $error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get("profile_avatar_file_size", "30")));
  }
  else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
    $error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get("profile_avatar_dimensions", "85x85")));
  }
  else if ($file = file_save_upload('profile_avatar', variable_get("profile_avatar_path", "avatars") . FILE_SEPARATOR .'avatar-'. $user->uid . $extension, 1)) {
    $edit["profile_avatar"] = $file->path;
  }
  else {
    $error = t("Failed to upload the avatar image; the '%directory' directory doesn't exist.", array("%directory" => variable_get("profile_avatar_path", "avatars")));
  }

  return $error ? "$error<br />" : "";
}

function _profile_active_fields($mode) {
  return variable_get("profile_". $mode ."_fields", array());
}

function _profile_edit_birth($edit = "") {
  global $profile_months, $profile_days;
  $output = _profile_select("profile_birthday", $edit->profile_birthday, $profile_days);
  $output .= "&nbsp;";
  $output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months);
  $output .= "&nbsp;";
  $output .= "<input type=\"text\" maxlength=\"4\" name=\"edit[profile_birthyear]\" size=\"5\" value=\"$edit->profile_birthyear\" />";
  return $output;
}

function _profile_validate_birth(&$edit) {
  if (!$edit["profile_birthday"] && !$edit["profile_birthmonth"] && !$edit["profile_birthyear"]) {
    // change this if you want required birth
    return;
  }

  if ($edit["profile_birthyear"] > 1900 && checkdate($edit["profile_birthmonth"], $edit["profile_birthday"], $edit["profile_birthyear"])) {
    return;
  }
  else {
    return t("The specified birthday is not valid.") ."<br />";
  }
}

function _profile_select($name, $value, $options, $extra = 0, $multiple = 0) {
  if (count($options) > 0) {
    foreach ($options as $key=>$choice) {
      $select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($key == $value ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
    }
    return "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>";
  }
}

?>