view msite.inc.php @ 629:894a4a6bfb5f fap2013

Better fix for the DB migration issue.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 01 Nov 2014 07:03:10 +0200
parents 8e6331d7870d
children a376521c7bd1
line wrap: on
line source

<?
//
// FAPWeb - Simple Web-based Demoparty Management System
// Generic and miscellaneous site support code
// (C) Copyright 2012-2014 Tecnic Software productions (TNSP)
//
require_once "msitegen.inc.php";

// Define modes of party information display system
define("SMODE_DISABLED", 0);
define("SMODE_ROTATE", 1);
define("SMODE_COMPO", 2);


// Define sizes of database fields, see createdb.php
// and also the places where input is validated.
define("SET_LEN_USERNAME", 32);
define("SET_LEN_GROUPS", 64);
define("SET_LEN_ONELINER", 64);
define("SET_LEN_EMAIL", 80);

define("SET_LEN_NEWS_TITLE", 128);
define("SET_LEN_NEWS_TEXT", 4096);
define("SET_LEN_NEWS_AUTHOR", 64);

define("SET_LEN_COMPO_NAME", 128);
define("SET_LEN_COMPO_DESC", 4096);
define("SET_LEN_COMPO_PATH", 128);

define("SET_LEN_ENTRY_NAME", 64);
define("SET_LEN_ENTRY_AUTHOR", 64);
define("SET_LEN_ENTRY_FILENAME", 128);
define("SET_LEN_ENTRY_INFO", 1024);
define("SET_LEN_ENTRY_NOTES", 1024);
define("SET_LEN_ENTRY_PREVIEW_FILE", 128);

define("SET_LEN_DISP_SLIDE_TITLE", 64);
define("SET_LEN_DISP_SLIDE_TEXT", 4096);
define("SET_LEN_ROT_LIST_NAME", 128);

define("SET_LEN_VOTEKEY", 64);


//
// Entry preview type (value) and flags (bitfield)
//
define("EPREV_IMAGE", 1);           // Preview is image (PNG, JPEG)
define("EPREV_AUDIO", 2);           // Preview is audio (MP3)

define("EFLAG_DISQUALIFIED", 1);    // Entry is disqualified
define("EFLAG_PROBLEMS", 2);        // Has some problems


//
// Competition types
//
define("COMPO_NORMAL", 0);          // Normal voting compo, points determine placement
define("COMPO_POINTS", 1);          // Assigned points, points determines placement (no voting)
define("COMPO_ASSIGN", 2);          // Assigned places (no voting)


$compoModeData = array(
  COMPO_NORMAL => array("Normal",
    "Normal voting compo.",
  ),
  COMPO_POINTS => array("Points",
    "Assigned points (no voting).",
  ),
  COMPO_ASSIGN => array("Assigned",
    "Assigned places (no points, no voting).",
  ),
);

//
// Different voting modes
//
define("VOTE_FREELY", 0);
define("VOTE_ACTIVATE", 1);
define("VOTE_ASSIGN", 2);

$voteModeData = array(
  VOTE_FREELY => array("Freeform voting",
    "Vote keys are not tied to attendees, and do not need to be activated. ".
    "Take one printed key slip, give it to attendee."
    ),
  VOTE_ACTIVATE => array("Key activation",
    "Vote keys are not tied to attendees, but require manual activation. ".
    "Take one printed key slip, find it by the index number in the list below, set to activated. ".
    "Give key slip to attendee."
    ),
  VOTE_ASSIGN => array("Assigned keys",
    "Votekeys are tied to attendees, activated by assigning the key to attendee. ".
    "Take one printed key slip, find attendee in the list below, enter key ID number, assign, check. ".
    "Give key slip to attendee."
    ),
);


//
// Party infromation system data/variables handling
//
function stReloadDisplayVars()
{
  global $displayVars, $displayVarsChanged;

  $displayVars = array();
  $displayVarsChanged = array();

  if (($res = stExecSQL("SELECT * FROM display_vars")) !== FALSE)
  {
    foreach ($res as $row)
      $displayVars[$row["key"]] = stGetSQLSettingData($row);
  }
}


function stSaveDisplayVars()
{
  global $db, $displayVars, $displayVarsChanged;

  foreach (stExecSQL("SELECT * FROM display_vars") as $item)
  if (isset($displayVarsChanged[$item["key"]]))
  {
    $val = $displayVars[$item["key"]];
    stExecSQL(
      "UPDATE display_vars SET ".stGetSettingSQL($item, $val).
      " WHERE key=".$db->quote($item["key"]));
  }
}


function stDisplayUpdated()
{
  stSetDisplayVar("lastUpdate", time());
}


function stSetDisplayVarUpd($name, $value)
{
  if (stGetDisplayVar($name) != $value)
  {
    stSetDisplayVar($name, $value);
    stDisplayUpdated();
    return TRUE;
  }
  else
    return FALSE;
}


function stGetDisplayVar($name)
{
  global $displayVars;
  if (isset($displayVars[$name]))
    return $displayVars[$name];
  else
    die("No display var for '".$name."'.\n");
}


function stSetDisplayVar($name, $value)
{
  global $displayVars, $displayVarsChanged;
  if (isset($displayVars[$name]))
  {
    $displayVars[$name] = $value;
    $displayVarsChanged[$name] = true;
  }
  else
    die("No display var for '".$name."'.\n");
}


//
// SQL database handling / helpoer functions
//
function stExecSQLCond($sql, $msg = FALSE)
{
  global $db;
  if (($res = stDBExecSQL($db, $sql)) !== FALSE)
  {
    if ($msg !== FALSE)
      stSetStatus(200, $msg);
    return $res;
  }
  else
  {
    stSetStatus(902, "Error in SQL execution.");
    return FALSE;
  }
}


function stPrintAttendee($item, $row, $tr, $full, $edit, $eclass = "")
{
  $id = $item["id"];
  $prefix = "at";
  
  if ($tr)
  {
    echo
      "  <tr class=\"".($row % 2 == 1 ? "rodd" : "reven").$eclass.
      "\" id=\"attendee".$id."\" ".($full ? "onClick=\"activateAttendee(".$id.")\"" : "").">";
  }
  
  echo
    stGetTDEditTextItem($edit, 20, SET_LEN_USERNAME, "name", $id, $prefix, $item["name"]).
    stGetTDEditTextItem($edit, 20, SET_LEN_GROUPS, "groups", $id, $prefix, $item["groups"]).
    "<td class=\"regtime\">".date("d.m. H:i", $item["regtime"])."</td>".
    stGetTDEditTextItem($edit, 30, SET_LEN_ONELINER, "oneliner", $id, $prefix, $item["oneliner"], "autocomplete=\"off\"");

  if ($full)
  {
    echo
      stGetTDEditTextItem($edit, 20, SET_LEN_EMAIL, "email", $id, $prefix, $item["email"], "autocomplete=\"off\"");

    if ($edit)
    {
      echo
        "<td>".
        "<button class=\"button\" id=\"atupd".$id."\" type=\"button\" onclick=\"updateAttendee(".$id.")\"> Upd </button>".
        "<button class=\"button\" id=\"atdel".$id."\" type=\"button\" onclick=\"deleteAttendee(".$id.")\"> Del </button>".
        "</td>";
    }
    else
      echo "<td></td>";
  }
  
  if ($tr)
  echo "</tr>\n";
}


function stPrintNewsItem($item)
{
  echo
  "<div class=\"newsItem\" id=\"news".$item["id"]."\">\n".
  "  <h2>".chentities($item["title"])."</h2>\n".
  "  <div class=\"newsText\">".dhentities($item["text"])."</div>\n".
  "  <div class=\"newsAuthor\"><span class=\"newsSig\">-- ".chentities($item["author"])."</span>".
  "<span class=\"newsDate\">".date("d M Y / H:i", $item["utime"])."</span></div>\n".
  "</div>\n";
}


function stGenerateUserKey()
{
  global $db;
  $keyChars = "abdefghjkmnpqrstwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
  
  while (TRUE)
  {
    // Generate one randomized keycode
    $key = "";
    for ($n = 0; $n < stGetSetting("userKeyLength"); $n++)
      $key .= $keyChars[rand() % strlen($keyChars)];

    // Check if it already exists, to avoid duplicates
    // We need custom query code here, because stFetchSQLColumn()
    // won't work due to it returning FALSE in error cases.
    $sql = stPrepareSQL("SELECT * FROM votekeys WHERE key=%s", $key);
    if (($res = @$db->query($sql)) !== FALSE)
    {
      // Did we get results?
      if ($res->fetchColumn() === FALSE)
      {
        // Nope, return key
        return $key;
      }
    }
    else
    {
      stLogSQLError($sql);
      return FALSE;
    }
  }
}


function stCheckRegistrationAvailable()
{
  global $maxAttendeesHard, $maxAttendeesSoft, $numAttendees;

  $maxAttendeesHard = stGetSetting("maxAttendeesHard");
  $maxAttendeesSoft = stGetSetting("maxAttendeesSoft");
  if (($numAttendees = stFetchSQLColumn("SELECT COUNT(*) FROM attendees")) === FALSE)
    $numAttendees = 0;

  return stChkSetting("allowRegister") && ($maxAttendeesHard <= 0 || $numAttendees < $maxAttendeesHard);
}


function stValidateRequestUserData($admin)
{
  if (!stChkRequestItem("name", $fake,
    array(CHK_ISGT, VT_STR, 0, "Handle / name not given."),
    array(CHK_LTEQ, VT_STR, SET_LEN_USERNAME, "Handle / name is too long, should be less than ".SET_LEN_USERNAME." characters.")
    )) return FALSE;

  if (!stChkRequestItem("groups", $fake,
    array(CHK_LTEQ, VT_STR, SET_LEN_GROUPS, "Groups are too long, should be less than ".SET_LEN_GROUPS." characters.")
    )) return FALSE;

  if (!stChkRequestItem("oneliner", $fake,
    array(CHK_LTEQ, VT_STR, SET_LEN_ONELINER, "Oneliner is too long, should be less than ".SET_LEN_ONELINER." characters.")
    )) return FALSE;

  $email = stGetRequestItem("email");
  if (!$admin && stGetSetting("requireEMail") && strlen($email) < 4)
  {
    stError("E-mail address not given, or it is too short.");
    return FALSE;
  }

  if (strlen($email) > 0 && preg_match("/^[a-z0-9][a-z0-9\+\-\.\%_]*@[a-z0-9.-]+\.[a-z]{2,4}$/i", $email) != 1)
  {
    stError("E-mail address not in proper format.");
    return FALSE;
  }

  if (strlen($email) > SET_LEN_EMAIL)
  {
    stError("E-mail address too long, max ".SET_LEN_EMAIL." characters.");
    return FALSE;
  }
  
  return TRUE;
}


function stGetOptionListStart($id, $indent, $outer, $size = 10, $onChange = "")
{
  return
    ($outer ? $indent."<div id=\"".$id."\">\n" : "").
    $indent."<select class=\"selectBox\" id=\"".$id."Sel\" size=\"".$size."\"".
    ($onChange != "" ? " onChange=\"".$onChange."\"" : "").">\n";
}


function stGetOptionListItem($value, $active, $name)
{
  return
    "<option value=\"".$value."\"".
    ($active ? " selected=\"selected\"" : "").
    ">".str_replace(" ", "&nbsp;", chentities($name))."</option>\n";
}


function stGetOptionListEnd($indent, $outer)
{
  return
    $indent."</select>\n".
    ($outer ? $indent."</div>\n" : "");
}


function stConvSwitchMode(&$str, &$mode, $newMode)
{
  if ($newMode != $mode)
  {
    if ($mode != "")
      $str .= "\n</".$mode.">\n";

    $mode = $newMode;

    if ($mode != "")
      $str .= "<".$mode.">\n";
  }
}


function stConvertCommonDesc($desc, $chent)
{
  $str = "";
  $mode = "";

  foreach (explode("\n", $desc) as $line)
  {
    if (preg_match("/^\s*\s*\*(.+)$/", $line, $m))
    {
      stConvSwitchMode($str, $mode, "ol");
      $str .= "<li>".($chent ? chentities($m[1]) : $m[1])."</li>\n";
    }
    else
    if (preg_match("/^\s*-\s*(.+)$/", $line, $m))
    {
      stConvSwitchMode($str, $mode, "ul");
      $str .= "<li>".($chent ? chentities($m[1]) : $m[1])."</li>\n";
    }
    else
    {
      stConvSwitchMode($str, $mode, "p");
      $str .= ($chent ? chentities($line) : $line);
    }
  }

  stConvSwitchMode($str, $mode, "");

  return $str;
}


function stGetNumberSuffix($val)
{
  switch ($val)
  {
    case  1: return "st";
    case  2: return "nd";
    case  3: return "rd";
    case  4: case 5: case 6:
    case  7: case 8: case 9: return "th";
    default: return "th";
  }
}


function stGetCompoResultsSQL($mode, $compo)
{
  //
  // Act based on competition type
  //
  switch ($compo["type"])
  {
    case COMPO_NORMAL:
      //
      // "Normal" competition, where results are somehow
      // based on points / voting.
      //
      switch ($mode)
      {
        case VOTE_FREELY:
          $sql =
            "SELECT entries.*,SUM(votes.value) AS votesum ".
            "FROM entries ".
            "LEFT JOIN votes ON votes.entry_id=entries.id";
          break;

        case VOTE_ACTIVATE:
          $sql =
            "SELECT entries.*, ".
              "(SELECT SUM(votes.value) FROM votes ".
              "LEFT JOIN votekeys ON votes.key_id=votekeys.id ".
              "WHERE votes.entry_id=entries.id AND votekeys.active<>0) ".
              "AS votesum ".
            "FROM entries";
          break;

        case VOTE_ASSIGN:
          $sql =
            "SELECT entries.*, ".
              "(SELECT SUM(votes.value) FROM votes ".
              "LEFT JOIN votekeys ON votes.key_id=votekeys.id ".
              "LEFT JOIN attendees ON votekeys.id=attendees.key_id ".
              "WHERE votes.entry_id=entries.id AND attendees.key_id<>0) ".
              "AS votesum ".
            "FROM entries";
          break;
      }

      $extra = 
        "GROUP BY entries.id ".
        "ORDER BY votesum DESC";
      break;

    case COMPO_POINTS:
    case COMPO_ASSIGN:
      //
      // These essentially do the same ...
      //
      $sql = "SELECT entries.* FROM entries";
      $extra = "ORDER BY entries.evalue DESC";
      break;
  }

  return $sql." ".
    "WHERE entries.compo_id=".$compo["id"]." ".
    "AND (entries.flags & ".EFLAG_DISQUALIFIED.")=0 ".
    $extra;
}


function stGetCompoResultsASCIIStr($showAuthors, $html)
{
  $sql = "SELECT * FROM compos WHERE visible<>0 ORDER BY name DESC";
  if (($res = stExecSQL($sql)) === false)
    return "";

  $voteKeyMode = stGetSetting("voteKeyMode");
  $out = "";

  // For each compo that has been set visible
  foreach ($res as $compo)
  {
    // Check if there are any entries for it
    $sql =
      "SELECT COUNT(*) FROM entries ".
      "WHERE compo_id=".$compo["id"]." ".
      "AND (entries.flags & ".EFLAG_DISQUALIFIED.")=0";

    if (($nentries = stFetchSQLColumn($sql)) !== FALSE && $nentries > 0)
    {
      // Get voting results by mode
      $sql = stGetCompoResultsSQL($voteKeyMode, $compo);

      // List results
      $prev = FALSE;
      $index = 0;

      if ($html)
      {
        $out .=
          "<pre>\n".
          "<b> ".chentities($compo["name"])." </b>\n".
          str_repeat("=", strlen($compo["name"]) + 2)."-- - .\n\n";
      }
      else
      {
        $out .=
          " ".$compo["name"]."\n".
          str_repeat("=", strlen($compo["name"]) + 2)."-- - .\n\n";
      }

      foreach (stExecSQL($sql) as $entry)
      {
        if ($entry["votesum"] !== $prev)
        {
          $index++;
          $out .= sprintf("%3d%s.", $index, stGetNumberSuffix($index));
        }
        else
          $out .= "  -''-";

        $name = stStrChopPad($entry["name"], 30);
        $author = stStrChopPad($showAuthors ? $entry["author"] : "-", 30);
        
        $out .= sprintf("  %s  by  %s (%d pts)\n",
          $html ? chentities($name) : $name,
          $html ? chentities($author) : $author,
          $entry["votesum"]);

        $prev = $entry["votesum"];
      }
      $out .= "\n\n".($html ? "</pre>\n" : "");
    }
  }
  
  return $out;
}



function stNormalizeListSlideOrder($list_id)
{
}


// Get link helper function
function stGetMainPageLink($id, $name, $show = TRUE)
{
  global $currPagename;
  if ($show)
    return "    <a class=\"".($id == $currPagename ? "active" : "inactive")."\" href=\"".$id."\">".$name."</a>\n";
  else
    return "";
}

?>