function tagExists($tag)
{
    assert(isValidTag($tag));
    global $database;
    $sql = $database->prepare("SELECT COUNT(*) FROM tags WHERE tag = :tag");
    $sql->bindParam(":tag", $tag);
    if ($sql->execute()) {
        return intval($sql->fetchColumn()) > 0;
    }
    return false;
}
function validateValues(array &$values, &$errors)
{
    // Check type between 0 and 8
    if ($values['type'] < 0 || $values['type'] > 8) {
        $errors->add('type', 'Invalid type');
    }
    // Lowercase tag. Check that it is 'a-z0-9_-'
    if (!isValidTag($values['tag'])) {
        $errors->add('tag', 'Tag may only contain characters: a-z0-9_-');
    }
    // A lot of things involve content
    if (isset($values['content'])) {
        // Content can only be used for unparsed_content, closed, unparsed_commas_content, and unparsed_equals_content
        if (!in_array($values['type'], array(Codes::TYPE_UNPARSED_CONTENT, Codes::TYPE_CLOSED, Codes::TYPE_UNPARSED_COMMAS_CONTENT, Codes::TYPE_UNPARSED_EQUALS_CONTENT))) {
            $errors->add('content', 'Content may only be used for unparsed_content, closed, unparsed_commas_content, and unparsed_equals_content types');
        }
        // Before/after can only be used when content is not used
        if (isset($values['before'])) {
            $errors->add('before', 'Before and content cannot be used together.');
        }
        if (isset($values['after'])) {
            $errors->add('after', 'After and content cannot be used together.');
        }
    }
    // Same goes for disabled_content/before/after
    if (isset($values['disabled_content'])) {
        // Content can only be used for unparsed_content, closed, unparsed_commas_content, and unparsed_equals_content
        if (!in_array($values['type'], array(Codes::TYPE_UNPARSED_CONTENT, Codes::TYPE_CLOSED, Codes::TYPE_UNPARSED_COMMAS_CONTENT, Codes::TYPE_UNPARSED_EQUALS_CONTENT))) {
            $errors->add('disabled_content', 'Disabled content may only be used for unparsed_content, closed, unparsed_commas_content, and unparsed_equals_content types');
        }
        if (isset($values['disabled_before'])) {
            $errors->add('disabled_before', 'Disabled Before and disabled content cannot be used together.');
        }
        if (isset($values['disabled_after'])) {
            $errors->add('disabled_after', 'Disabled After and disabled content cannot be used together.');
        }
    }
    // Only parsed content (0) and unparsed content (3) can have parameters
    // Block level is bool
    // trim is empty, inside, outside, or both
    // quoted is empty, optional, or required
    // require_parents and children is a comma delimited list of tag names. Lowercase the tag names and check that they are valid tag names
    // Same goes for ATTR_DISALLOW_PARENTS, ATTR_DISALLOW_CHILDREN, ATTR_DISALLOW_BEFORE, ATTR_DISALLOW_AFTER, ATTR_PARSED_TAGS_ALLOWED
    // check to make sure require_parents doesn't contain anything in disallow_parents. Same for children
    // autolink is bool
    // disabled is bool
    // no_cache is bool
    // test is only for *equals
}
function tagForGraphCheck($tag, $type)
{
    if (!isValidTag(strtoupper($_GET["tag"]))) {
        printInvalidTag($_GET["tag"]);
        exit;
    }
    if (!tagExists(strtoupper($_GET["tag"]))) {
        printInexistingTag($_GET["tag"]);
        exit;
    }
    if (!graphExists(strtoupper($_GET["tag"]), $type)) {
        printInexistingGraph();
        exit;
    }
}
    });
  </script>
  <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=default"></script>
  <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
</head>

<body>

<h1><a href="<?php 
print href("");
?>
">The Stacks project sloganerator</a></h1>

<?php 
$tag = isset($_GET["tag"]) ? $_GET["tag"] : '';
if (!isValidTag($tag)) {
    $message = "The tag that was requested (<code>" . htmlentities($tag) . "</code>) is not a valid tag. You can request a new tag.";
    printError($message);
} elseif (!tagExists($tag)) {
    $message = "The tag that was requested (<code>" . $tag . "</code>) does not exist in the Stacks project. You can request a new tag.";
    printError($message);
} else {
    $meta = json_decode(file_get_contents("http://" . $_SERVER["HTTP_HOST"] . href("data/tag/" . $tag . "/meta")));
    if (in_array($meta->type, array("lemma", "proposition", "remark", "remarks", "theorem"))) {
        print "<p>You can suggest a slogan for <a href='" . href("tag/" . $tag) . "'>tag <code>" . $tag . "</code></a> (label: <code style='font-size: .9em'>" . $meta->label . "</code>), located in<br>";
        $id = explode(".", $meta->book_id);
        print "&nbsp&nbsp;Chapter " . $id[0] . ": " . parseAccents($meta->chapter_name) . "<br>";
        print "&nbsp&nbsp;Section " . $id[1] . ": " . parseAccents($meta->section_name);
        printStatement($tag);
        printForm($tag);
        $slogans = getSlogans($tag);
<?php

require_once "../tags.php";
ini_set('display_errors', 1);
error_reporting(E_ALL);
// read configuration file
$config = parse_ini_file("../../config.ini");
// initialize the global database object
try {
    $database = new PDO("sqlite:" . "../../" . $config["database"]);
} catch (PDOException $e) {
    echo $e->getMessage();
}
if (!isValidTag($_GET["tag"])) {
    print "This tag is not valid.";
    exit;
}
if (!tagExists($_GET["tag"])) {
    print "This tag does not exist.";
    exit;
}
$tag = getTag($_GET["tag"]);
$chapter = getEnclosingChapter($tag["position"]);
$section = getEnclosingSection($tag["position"]);
$result = array();
$result["type"] = $tag["type"];
$result["label"] = $tag["label"];
$result["chapter_page"] = $tag["chapter_page"];
$result["book_page"] = $tag["book_page"];
$result["book_id"] = $tag["book_id"];
$result["value"] = $tag["value"];
function tagIsActive($tag)
{
    assert(isValidTag($tag));
    global $database;
    $sql = $database->prepare("SELECT active FROM tags WHERE tag = :tag");
    $sql->bindParam(":tag", $tag);
    if ($sql->execute()) {
        return $sql->fetchColumn() == "TRUE";
    }
    return false;
}
include "general.php";
include 'tags.php';
// read configuration file
$config = parse_ini_file("../config.ini");
// initialize the global database object
try {
    $database = new PDO("sqlite:../" . $config["database"]);
} catch (PDOException $e) {
    echo $e->getMessage();
}
function printBackLink()
{
    print "<br><a href='#' onclick='history.go(-2);'>go back</a>";
}
// if this triggers the user is messing with the POST request
if (!isset($_POST['tag']) or !isValidTag($_POST['tag'])) {
    print 'The tag your browser supplied in the request is not in a valid format.';
    printBackLink();
    exit;
}
if ($_POST['tag'] !== $_POST['check']) {
    print 'You did not pass the captcha. Please go back and fill in the correct tag to prove you are not a computer.';
    printBackLink();
    exit;
}
// the tag is not present in the database, when we start handling removed tags this will have to change
if (!tagExists($_POST['tag'])) {
    print 'The tag you are trying to post a comment on does not exist.';
    printBackLink();
    exit;
}
function parseReferences($string)
{
    // look for \ref before MathJax can and see if they point to existing tags
    $references = array();
    preg_match_all('/\\\\ref{[\\w-]*}/', $string, $references);
    foreach ($references[0] as $reference) {
        // get the label or tag we're referring to, nothing more
        $target = substr($reference, 5, -1);
        // we're referring to a tag
        if (isValidTag($target)) {
            // regardless of whether the tag exists we insert the link, the user is responsible for meaningful content
            $string = str_replace($reference, '[`' . $target . '`](' . href('tag/' . $target) . ')', $string);
        } else {
            // might it be that he is referring to a "local" label, i.e. in the same chapter as the tag?
            // TODO: Is it worth it to do this?
            if (!labelExists($target)) {
                $tag = getTag(strtoupper($_GET['tag']));
                // let's try it with the current chapter in front of the label
                $target = $tag["file"] . '-' . $target;
            }
            // the label (potentially modified) exists in the database (and it is active), so the user is probably referring to it
            // if he declared a \label{} in his string with this particular label value he's out of luck
            if (labelExists($target)) {
                $tag = getTagWithLabel($target);
                $string = str_replace($reference, '[`' . $tag . '`](' . href('tag/' . $tag) . ')', $string);
            }
        }
    }
    return $string;
}