view www/loc.php @ 2763:78ad0e51b7b5

Improve wizards.txt parser, add functionality for specifying alternative / additional names as some wizards have used more than one. Also other improvements in wizard data handling.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 12 Mar 2024 15:47:58 +0200
parents 7948d14d3893
children b58f261314f8
line wrap: on
line source

<?php
require "config.inc.php";
require "world.inc.php";
require "common.inc.php";


// Wizard info box special formatting tags
$specTags =
[
  "b"     => "<b>",
  "\/b"   => "</b>",
  "i"     => "<i>",
  "\/i"   => "</i>",
  "p"     => "<br /><br />",
  "br"    => "<br />",
];


function printTitleLink($afilter, $filter, $authors, $desc, $qname, $qclass)
{
  global $setName;

  $s = "";
  if ($afilter)
    $s = "f=".$filter;

  if (!$authors)
  {
    if ($s !== "") $s .= "&amp;";
    $s .= "s";
  }

  if ($qname !== "")
  {
    if ($s !== "") $s .= "&amp;";
    $s .= "n=".$qname;
  }

  if ($setName == $qname || ($setName == "" && $qname == "all"))
    $qclass .= " active";

  echo
    "  <a class=\"control continent ".$qclass.
    "\" href=\"?".$s."\">".$desc."</a>\n";
}


function qcheck($arr, $key, &$result)
{
  if (isset($key) && isset($arr[$key]))
  {
    $result = $arr[$key];
    return TRUE;
  }
  else
  {
    unset($result);
    return FALSE;
  }
}


function locCompare($va, $vb)
{
  return strcmp($va["name"], $vb["name"]);
}


//
// Initialization
//
// Special backwards compatibility case for pcities
if (isset($_REQUEST["c"]))
{
  $filterID = "C";
  $applyFilter = TRUE;
}
else
// Try to get the filter ID
if (($filterID = mpGetRequestItem("f", "", TRUE)) != "")
{
  if (!array_key_exists($filterID, $locationTypes))
  {
    mpError("Invalid location filter rule '".chentities($filterID)."'.");
    $filterID = "";
    $applyFilter = FALSE;
  }
  else
    $applyFilter = TRUE;
}
else
// No filter ID specified, default to showing everything
{
  $filterID = "";
  $applyFilter = FALSE;
}


$showCoders = !isset($_REQUEST["s"]);

if (($tmpName = mpGetRequestItem("a", FALSE, TRUE)) !== FALSE)
{
  if (preg_match("#^([a-z]{1,15})#i", $tmpName, $matches))
  {
    $authorName = $matches[1];
    $authorName = strtoupper(substr($authorName, 0, 1)).strtolower(substr($authorName, 1));

    $wizTable = apcu_fetch("wizTable");
    if (empty($wizTable))
    {
      $wizTable = mpReadWizInfoFiles();
      apcu_store("wizTable", $wizTable, 3600);
    }

    // Correct aliases
    if (isset($wizTable[$authorName]))
      $authorName = $wizTable[$authorName]["name"];
  }
  else
  {
    $authorName = "???";
    mpError("Invalid wizard name.");
  }
}

if (($tmpName = mpGetRequestItem("n", FALSE, TRUE)) !== FALSE)
{
  $locTable = [];
  $setName = strtolower(trim(basename($tmpName)));
  if (file_exists($setName.".loc"))
  {
    $locTable = apcu_fetch("loc_".$setName);
    if (empty($locTable))
    {
      $locTable = [];
      mpParseLocFile($setName, $locTable, $applyFilter, $locationTypes[$filterID][LTI_INVERT_FLAGS], $locationTypes[$filterID][LTI_FLAGS]);
      apcu_store("loc_".$setName, $locTable, 3600);
    }
  }
  else
  {
    mpError("No such continent ID!");
    unset($setName);
  }
}
else
{
  $locTable = apcu_fetch("loc_locTable");
  if (empty($locTable))
  {
    $locTable = mpParseLocFiles($applyFilter, $locationTypes[$filterID][LTI_INVERT_FLAGS], $locationTypes[$filterID][LTI_FLAGS]);
    apcu_store("loc_locTable", $locTable, 3600);
  }
}


// Make alphabetically sorted table of locations
$alphaTable = [];
foreach ($locTable as $id => $data)
if (isset($data["name"]))
{
  $idx = strtolower($data["name"][0]);
  if (isset($authorName))
  {
    foreach ($data["authors"] as $author)
    {
      if ($authorName == $author["name"])
        $alphaTable[$idx][] = $data;
    }
  }
  else
    $alphaTable[$idx][] = $data;
}

ksort($alphaTable, SORT_STRING);


//
// Start of the page
//
if ($applyFilter)
  $mtitle = $locationTypes[$filterID][LTI_PAGE_DESC];
else
  $mtitle = "Locations";

$mtitle .= " of ";

if (isset($setName) && isset($continentList[$setName]))
{
  $mtitle .= $continentList[$setName][CTI_NAME].
    ($continentList[$setName][CTI_SPECIAL] ? " in " : " continent in ");
}

mpPrintPageHeader($pageTitle." - Locations",
  "  <script type=\"text/javascript\" src=\"tooltip.js\"></script>\n".
  "  <meta name=\"robots\" content=\"nofollow\" />\n",
  " onload=\"mapOnLoad()\"");

echo
  "<h1>".$mtitle."BatMUD".(isset($authorName) ? " by ".chentities($authorName) : "")."</h1>\n".
  "<form action=\"?\" method=\"get\">\n".
  "<div class=\"controls\">\n";

if (isset($setName))
  echo "  <input type=\"hidden\" name=\"n\" value=\"".chentities($setName)."\" />\n";

echo "  <select class=\"control dropdown\" name=\"f\" onChange=\"this.form.submit();\">\n";
foreach ($locationTypes as $lid => $ldata)
{
  echo
    "    <option value=\"".$lid."\"".
    (($applyFilter && $filterID == $lid) ? " selected=\"selected\"" : "").
    ">".$ldata[LTI_MENU_TITLE]."</option>\n";
}
echo
  "  </select>\n".
  "  <noscript><input type=\"submit\" value=\" Update \" class=\"control submit\" /></noscript>\n";


printTitleLink($applyFilter, $filterID, $showCoders, "All&nbsp;continents", "", "all");
foreach ($continentList as $continent => $data)
{
  if ($data[CTI_HAS_MAP])
    printTitleLink($applyFilter, $filterID, $showCoders, $data[0], $continent, $continent);
}
printTitleLink($applyFilter, $filterID, $showCoders, "Special", "special", "special");

echo
  "</div>\n".
  "</form>\n";


//
// Wizard/author/creator information box
//
if (isset($authorName))
{
  if (isset($wizTable[$authorName]))
  {
    $entry = &$wizTable[$authorName];

    // Profile picture
    //$imageURL = $wizImageURL.(qcheck($entry, "imageURL", $imageName) ? $imageName : "unknown.png");
    $imageURL = $wizImageURL."unknown.png";

    echo
      "<div class=\"wizInfoBox\">\n".
      "   <div class=\"wizImage\"><img src=\"".$imageURL."\" alt=\"".$entry["name"]."\" /></div>\n".
      "   <div class=\"wizInfo\">\n".
      "    <h2>".$entry["name"];

    if (count($entry["names"]) > 0)
    {
      echo " (aka ".implode(" aka ", $entry["names"]).")";
    }

    echo
      "</h2>\n";

    // Description block
    if (qcheck($entry, "desc", $str))
    {
      // Handle special tags
      $str = preg_replace("/\~([A-Z][a-z]+)\~/i", "<a href=\"?a=\${1}\">\${1}</a>", $str);

      foreach ($specTags as $tag => $rep)
        $str = preg_replace("/\[".$tag."\]/i", $rep, $str);

      echo "    <p>".$str."</p>\n";
    }

    // Links, etc.
    echo "    [<a href=\"".mpFingerURL($authorName)."\">Finger</a>]\n";

    if (qcheck($entry, "homeURL", $s))
    {
      if ($s == "bat")
        $s = "https://wiz.bat.org/~".strtolower($authorName)."/";

      echo "    [<a href=\"".$s."\">Homepage</a>]\n";
    }

    if (qcheck($entry, "countries", $s))
    {
      echo "    [".implode(" | ", array_map(
        function ($item)
        {
          return strtoupper($item);
        }, $s))."]<br />\n";
    }

    echo
      "   </div>\n".
      "</div>\n";
  }
  else
    mpError("No information entry for this wizard.");
}


//
// Print out errors
//
if ($errorSet)
{
  echo
    "<div style=\"color: red;\">\n".
    " <ul>\n";

  foreach ($errorMsgs as $msg)
    echo "  <li>".$msg."</li>\n";

  echo
    " </ul>\n".
    "</div>\n";
}


//
// Print list of locations
//
if (count($alphaTable) > 0)
{

  $locationTips = [];
  $totalLoc = 0;
  $maxColumns = 6;
  foreach ($alphaTable as $alpha => $alphaLocs)
  {
    if (count($alphaLocs) <= 0) continue;
    $letter = strtoupper($alpha);

    uasort($alphaLocs, "locCompare");

    echo
      "<h3 class=\"alpha\"><a id=\"ch".$letter."\"></a>".$letter."</h3>\n".
      mpSpecialDate("loc", 2).
      "<div class=\"locTable\">\n";

    $n = 0;
    foreach ($alphaLocs as $ik => $iv)
    {
      $totalLoc++;

      // Print location entry
      echo
        "  <div class=\"locCell ".$iv["continent"]."\">".
        "<div class=\"locHeader\">".
        "<span class=\"locTitle\">".
        mpGetMapLink($iv, $continentList[$iv["continent"]][CTI_HAS_MAP], TRUE, TRUE).
        "</span>";

      // If either freeform desc or URL field are set, we add those
      if (isset($iv["url"]) || isset($iv["freeform"]))
      {
        // Free form description
        $desc = isset($iv["freeform"]) ? chentities($iv["freeform"]) : "";

        // Add URL information, chopped, if any
        if (isset($iv["url"]))
        {
          $urlEnt = $iv["url"];
          $urlBegin = "<a href=\"".chentities($urlEnt)."\" target=\"_blank\">";
          $urlEnd = "</a>";
          if (strlen($iv["url"]) > 40)
            $urlEnt = substr($urlEnt, 0, 40)."...";
          $desc .= "<div class=\"locURL\">".chentities($urlEnt)."</div>";
        }
        else
        {
          $urlBegin = $urlEnd = "";
        }

        echo
          " ".$urlBegin.
          "<span onmouseover=\"stt(".$totalLoc.
          ");\" onmouseout=\"htt();\">&#x1F354;</span>".
          $urlEnd;

        $locationTips[$totalLoc] = [
          "title" => $iv["name"],
          "desc" => $desc
        ];
      }

      echo "</div>"; // locHeader

      // Alternative names
      if (($nnames = count($iv["names"])) > 1)
      {
        $fs = [];
        for ($nname = 1; $nname < $nnames; $nname++)
        {
          $qname = $iv["names"][$nname];
          $norig = $qname["flags"] & NAME_ORIG;
          $fs[] =
            ($norig ? "<b>" : "").
            chentities($qname["name"]).
            ($norig ? "</b>" : "");
        }
        echo "<div class=\"locAltNames\">".implode(" | ", $fs)."</div>";
      }

      // Coder / society names
      if (count($iv["authors"]) > 0 && $showCoders)
      {
        $fs = [];
        foreach ($iv["authors"] as $name)
        {
          // Tags/flags of this author in relation to the area
          switch ($name["flags"])
          {
            case AUTHOR_ORIG:       $qs = "title=\"Original creator\" class=\"wizorig\""; break;
            case AUTHOR_RECODER:    $qs = "title=\"Converter, recoder\" class=\"wizrecoder\""; break;
            case AUTHOR_MAINTAINER: $qs = "title=\"Maintainer\" class=\"wizmaintainer\""; break;
            case AUTHOR_EXPANDER:   $qs = "title=\"Implemented new content, expansion(s)\" class=\"wizexpander\""; break;
            default: $qs = "";
          }

          // Pcity entries do not get "author" links as they are actually SS+
          if ($filterID != "C" || !$applyFilter)
            $fs[] = "<a ".$qs." href=\"?a=".$name["name"]."\">".$name["name"]."</a>";
          else
            $fs[] = $name["name"];
        }
        echo "<div class=\"locCoders\">".implode(", ", $fs)."</div>";
      }

      if (/* isset($authorName) && */ $iv["added"] > 0)
      {
        echo "<div class=\"locAdded\">".mpLocFormatTime($iv)."</div>";
      }

      echo "</div>\n";
    }
    echo "</div>\n";
  }

  echo
    "<p><b>".$totalLoc."</b> locations.</p>\n".
    "</div>\n"; // end of contents div

  // Print out location tooltip HTML code
  foreach ($locationTips as $tipID => $tip)
  {
    echo
      "<div class=\"tooltip\" id=\"tt".$tipID.
      "\"><div class=\"holder\"><b>".chentities($tip["title"]).
      "</b><br />".$tip["desc"]."</div></div>\n";
  }

  // Print out the alpha link index div
  mpPrintExtraBoxAlphaList("ch", $alphaTable);
}
else
{
  echo
    "<p><b>No locations known!</b></p>\n".
    "</div>\n"; // end of contents div

  mpError("No locations known!");
}

mpPrintPageFooter(FALSE);
?>