User:Diploid/ATS (Article Tagging System)/ATS Body.php

From MediaWiki.org
Jump to: navigation, search
<?php
 /* Copyright (c) 2007 MediaWiki.org User: Diploid
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal 
 * in the Software without restriction, including without limitation the rights to 
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 
 * the Software, and to permit persons to whom the Software is furnished to do 
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all 
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
 * OTHER DEALINGS IN THE SOFTWARE. 
 * -----------------------------------------------------------------------
 */
 
#
# The ATS ajax response (Article Tagging System) class
#

# used for producing tag clouds and all interactions with the ATS table
class ATSajaxresponse
{ 
        ##=========Configuration Variables=========

        #The Maximum Font Size of the Tag Cloud in the units selected bellow
 private $MaxFontSize = 21;
        private $MinFontSize = 12;
        #Units for the font size
 private $FontUnit = "px";
 
        #Definate the default number of tags per tag cloud
 private $DefaultNofTags = 9;
 
        ##Defines the CSS Classes of various html elements of the Tag Cloud
 #Wrapper div for the tag cloud section
 private $cssClass_TagCloud = "tagcloud";
        #Each individual tag's span element
 private $cssClass_Tag = "tag";
        #Wrapper div for the add a tag section
 private $cssClass_AddTag = "addtag";
        #The text input area for typing the name of your tag
 private $cssClass_Add_Text = "addtaginput";
        #The button for adding your tag
 private $cssClass_Add_Button = "addtagbutton";
 
        #The Add Tag and Tag Cloud titles
 private $HTMLtagCloudTitle = "<h2>Tags</h2>";
        private $HTMLaddTagTitle = "<h2>Add Tag</h2>";
 
 
        #Set the dbuser and dbpassword variables to give this script table create 
 #permision for the wiki's database so that it can create the ATSTags table.
 private $dbuser="";
        private $dbpassword="";
 
        #database server name
 private $dbserver = "localhost";
        #database name
 private $dbname = "wikidb";
        #database mediawiki table prefix
 private $dbprefix = ""; //(make it the same as $wgDBprefix in local settings)
 
 
 
        private $MediaWikiInstallDirectory = "";
 
        #Sets the default setting for tag clouds:
 # If true every page will have a tag cloud by default that can be removed
 #with {{#ATS: disable}}
 # If false pages will not have tag clouds by default but must be added
 #with {{#ATS: enable}}
 public $TagCloudEnable = true;
 
        #The Hash Key used for all ATS form data, set this to some random
 #characters for increased security
 public $FormHashData = '';
 
        ##=====End of Configuration Variables=====
 
        ##Everything beyond this point should probably not be touched unless you wish
 #to modify the extension
 private $TagTableName = "atstags";
        private $TagCountAlias = "NoOfTags";
        #Time out (in seconds) for Session Data Stored in the atssession Memory Table in mysql
 #Note that this data is not particlularly valuable as it is only used to store a user validation key
 #from the time the user loads a ATS tagcloud to the time they add a tag to that cloud.
 private $SessionDataTimeout = 300; //default is 5 minute timeout
 
####Session Database Related Functions
 private function SessionEntryExists($user)
        {
                        $query = "SELECT suser FROM ".$this->dbname.".".$this->dbprefix."atssessions "
                                        ."WHERE suser = '$user'";
                        if ($resultdata = $this->DBConnect($query)==false) return false;
                        return true;
        }
        public function PostSessionData($sessiondata, $user)
        {
                foreach($sessiondata as $seskey => $sesvalue)
                {
                        $query = "DELETE FROM $this->dbname.$this->dbprefix"."atssessions "
                                ."WHERE suser = '$user' and skey = '$seskey'";
                        if ($this->DBConnect($query) == false) echo("ATS Session Deletion Error");
 
                        $servertime = time();
                        $query = "INSERT INTO ".$this->dbname.".".$this->dbprefix."atssessions"
                        ." (suser, skey, svalue, timestamp)"
                        ." VALUES ('$user', '$seskey', '$sesvalue','$servertime');";
                        if ($this->DBConnect($query) == false) echo("ATS Session Error");
                }
        }
        public function GetSessionData($sessionkey, $user)
        {
                        $query = "SELECT suser, svalue, skey FROM ".$this->dbname.".".$this->dbprefix."atssessions "
                                        ."WHERE skey = '$sessionkey' AND suser = '$user'";
                        $resultdata = $this->DBConnect($query);
                        if ($resultdata==false) return false;
                        $resultarray = $this->getSQLarray($resultdata);
                        return $resultarray[(count($resultarray)-1)]['svalue'];
        }
        private function DeleteExpiredSessions()
        { #Deletes Entries older then the timeout period specified in the $SessionDataTimeout Variable
         $awhileback = time()-$this->SessionDataTimeout;
                $query = "DELETE FROM $this->dbname.$this->dbprefix"."atssessions "
                                ."WHERE timestamp < $awhileback";
                if ($this->DBConnect($query) == false) echo("ATS Session Deletion Error");
        }
        private function SetupSession()
        {
                $query = "SELECT * FROM ".$this->dbname.".".$this->dbprefix."atssessions";
                if ($this->DBConnect($query)==false)
                {
                $query = "CREATE TABLE ".$this->dbname.".".$this->dbprefix."atssessions"
                ."("
                ."suser VARCHAR(100) NOT NULL, "
                ."skey VARCHAR(100) NOT NULL, "
                ."svalue VARCHAR(100) NOT NULL, "
                ."timestamp INTEGER UNSIGNED NOT NULL"
                .") ENGINE = MEMORY;";
                if ($this->DBConnect($query)==false) echo ("ATS Fatal Error: Could Not Set Up Session Data");
                }
 
                #Removing Expired Session Entries
         $this->DeleteExpiredSessions();
 
        }
 
####Tag Creation Related Functions
 public function AddTag($pagename, $tag, $username, $hashtoken)
        {
                $tag = ucfirst($tag);
                $identicaltagcheck = $this->identicaltagcheck($pagename, $tag, $username);
                //Requires the user to be logged in and authorized (aka has a correct hash)
                if ($this->validateuser($pagename,$username,$hashtoken) == true
                and $identicaltagcheck==false
                and $pagename != null)
                {
                        $pagename = ucfirst($pagename);
                        ######  Adding to ATS Table ####
                 
                        //Updating the tag table
                        $query = "
INSERT INTO `".$this->dbname."`.`".$this->dbprefix.$this->TagTableName."` (Tag, Page, UserName)
VALUES (\"".$tag."\",\"".$pagename."\",\"".$username."\")";
 
                        if($this->DBConnect($query)==false)
                        {
                                echo("Unknown ATS Error Please Try Again");
                                exit();
                        }
 
                        #####  Adding to MediaWiki Tables #####
                 
                        //Getting the page's number
                        $_pagename =  str_replace(" ", "_", $pagename);
                        $query =
"SELECT page_id FROM `".$this->dbname."`.`".$this->dbprefix."page`
WHERE page_title = \"".$_pagename."\"";
 
                        $pageiddata = $this->DBConnect($query);
                        if ($pageiddata ==false)
                        {
                                echo("ATS Error While Getting Page ID Please Try Again");
                                exit();
                        }
                        $pageidarray = $this->getSQLarray($pageiddata);
                        $pageid = $pageidarray[count($pageidarray)-1]["page_id"];
 
                        //Updating the Media Wiki categorylinks table
                        //cl_from, cl_to, cl_sortkey, cl_timestamp
                        $timestamp = date("Y-m-d H:i:s");
                        $tag = str_replace(" ", "_", $tag);
                        $query = "
INSERT INTO `$this->dbname`.`$this->dbprefix"."categorylinks` (cl_from, cl_to, cl_sortkey, cl_timestamp)
VALUES (\"".$pageid."\",\"".$tag."\",\"".$pagename."\",\"".$timestamp."\")";
 
                        if($this->DBConnect($query)==false)
                        {
                                echo("ATS Error While Interacting with the MediaWiki Table CategoryLinks Please Try Again");
                                exit();
                        }
 
 
                        //Updating the Job List so that the category page is updated accordingly
                        $query = "
insert into ".$this->dbname.".".$this->dbprefix."job (job_cmd,job_namespace,job_title,job_params) 
VALUES ('refreshLinks',0,'".$_pagename."','');
";
 
                        if($this->DBConnect($query)==false)
                        {
                                echo("ATS Error While adding MediaWiki Job");
                                exit();
                        }
 
                }
                else
                {
                        if ($identicaltagcheck == true) {
                                echo("You can only tag this page once");
                        }
                        else {
                                echo("Your session has expired, please log in to add a tag");
                        }
                }
        }
 
 
        private function identicaltagcheck($page, $tag, $user)
        {
                $query = 
"
SELECT Tag, Page, UserName FROM `".$this->dbname."`.`".$this->dbprefix.$this->TagTableName."`
WHERE Tag = \"".$tag."\" and UserName = \"".$user."\" and Page = \"".$page."\"
";
                $result = $this->DBConnect($query);
                if ($result == false) return true;
                $resultarray = $this->getSQLarray($result);
                if (count($resultarray) == 1)
                {
                return false;
                }
                return true;
        }
 
####Tag Querying Functions
 private function QueryPageTags($page, $arg="orderbytagcount")
        {
                $orderby="";
                if ($arg == "textonly" || $arg="orderbytagcount")
                        $orderby = "ORDER BY Count(UserName) DESC";
 
                //Querying the Database
                $query = 
"
SELECT Tag, Count(UserName) AS ".$this->TagCountAlias." FROM `".$this->dbname."`.`".$this->dbprefix.$this->TagTableName."`
WHERE Page = \"".$page."\"
GROUP BY Tag
".$orderby;
                return $this->DBConnect($query);
        }
        public function GetTags_CommaSeperatedText($page)
        {
                $result = $this->QueryPageTags($page);
                if ($result == false) return false;
                return $this->getSQLcolumntext_CommaSeperated($result,"Tag");
        }
        public function GetTags($page)
        {
                $result = $this->QueryPageTags($page);
                if ($result == false) return false;
                $resultarray = $this->getSQLarray($result);
                #Deleting the first, and for some reason always empty first row
         array_splice($resultarray, 0, 1);
                return $resultarray;
        }
        public function GetTaggedPages($tag)
        {
                $query = 
"
SELECT Page, Count(UserName) AS tagcount FROM `".$this->dbname."`.`".$this->dbprefix.$this->TagTableName."`
WHERE Tag = \"".$tag."\"
GROUP BY Page
ORDER BY Count(UserName) DESC
"
;
                $result = $this->DBConnect($query);
                if ($result == false) return false;
                $resultarray = $this->getSQLarray($result);
                #Deleting the first, and for some reason always empty first row
         array_splice($resultarray, 0, 1);
                return $resultarray;
        }
 
        #This monster of a function generates Tag Clouds in both WikiText and HTML format
 public function MakeTagCloud($page,$NofTags = false, $user=false, $key)
        {
                if ($this->TagCloudEnable == true)
                {
                #Setting the defualt number of tags if it is not definaed here
         if ($NofTags==false) $NofTags = $this->DefaultNofTags;
                #Gets the tag data in array form
         $tagdata = $this->GetTags($page);
 
                $Path = $this->MediaWikiInstallDirectory;
 
                #Initializing the returned tag cloud HTML: $tagcloud var
         $tagcloud =$this->HTMLtagCloudTitle
                ."<div class=\"".$this->cssClass_TagCloud."\">";
 
                #Getting the Size of the tagdata array
         $size = count($tagdata);
 
                #Checking that there are actually any tags returned for the page
         #before creating the tag cloud
         if ($tagdata!=false && $size != 0)
                {
                #Initializing a variety of variables
         if ($size < $NofTags) $NofTags = $size;
 
                $mosttags = $tagdata[0][$this->TagCountAlias];
                $leasttags = $tagdata[$NofTags-1][$this->TagCountAlias];
 
                $fontmultiplier = 1;
                if ($mosttags != $leasttags)
                {
                #Creating the font multiplier used to create the varying font sizes used in
         #the tag cloud to represent tag popularity            
         $fontmultiplier = 1/($mosttags - $leasttags)*
                                                  ($this->MaxFontSize - $this->MinFontSize);      
                }
 
                #Get the first N Tags where N = $NofTags 
         if ($size != $NofTags) array_splice($tagdata,$NofTags);
                $size = count($tagdata);
                #Order the first N Tags Alphabetically where N = $NofTags
         $this->OrderRowArrayAlphabetically($tagdata, "Tag");
                #Creating each Tag's HTML
         for ($i=0; $i<$size; $i++)
                {
                        #Generating the tag's font size relative to it's popularity and the
                 #font multiplier
                 $fontsize = 
                                (($tagdata[$i][$this->TagCountAlias]-$leasttags)
                                *$fontmultiplier) + $this->MinFontSize;
 
                        #Sets the URL of the Tag's Link
                 $tagurl = $Path."/index.php?title=Category:".$tagdata[$i]["Tag"];
 
                        #Generating the Tag's HTML code and appending it to the output
                 $tagcloud .= "<a href=\"".$tagurl."\" class = \"".$this->cssClass_Tag."\""
                                           ." style=\"font-size:".$fontsize."".$this->FontUnit.";\">"
                                          .$tagdata[$i]["Tag"]
                                          ."</a>\n";
                        }
                }
 
                $tagcloud .= "</div>\n"; //End of the TagCloudSpan
 
                $tagcloud .= $this->HTMLaddTagTitle
                                  ."<div class = \"".$this->cssClass_AddTag."\">\n";
                if ($this->validateuser($page, $user, $key) ==false)
                {
                        $tagcloud .="Please Log in to add a tag";
                }
                else 
                {
                #Creating the Add Tag HTML
         $tagcloud .=""
                ."<input id=\"ATSaddtag-tagname\" type=\"text\" />\n"
                ."<input id=\"ATSaddtag-submit\" type=\"button\" value=\"Add\""
                ."onClick=\"AsyncLoadATS("
                ."document.getElementById('ATSaddtag-tagname').value)\"/>\n";
                }
                $tagcloud .= "</div>\n";
 
 
                return $tagcloud;
                }
                return "";
        }
 
 
        private function OrderRowArrayAlphabetically(&$rows, $col)
        {
                $size = count($rows);
 
                for ($i=0; $i<$size; $i++)
                {
 
                #Finding the next row in alphabetical order (temperarorly stored as $alpha)
         $alpha = $i;
                for ($j=$i; $j<$size; $j++)
                {
                        if ((strcasecmp($rows[$alpha][$col], $rows[$j][$col]))>0)
                        {$alpha =$j;
                        }
                }
 
                #Inserting the next row $alpha and moving the previous 
         #entry at that position back into the sorting que
         if ($alpha!= $i)
                {
                        $tmprow = $rows[$i];
                        $rows[$i] = $rows[$alpha];
                        $rows[$alpha] = $tmprow;
                }
                }
        }
 
 
        public function Setup()
        {
                #Checking for Script Specific DB Username and Password otherwise using the
         #mediawiki account
         /*if (!$this->dbuser || !$this->dbpassword)
                {
                        $this->dbuser = $wgDBuser;
                        $this->dbpassword = $wgDBpassword;
                }*/
                #Checking if MySQL is installed and working properly
         # Test for missing mysql.so
         # First try to load it
         if (!@extension_loaded('mysql')) {
                        @dl('mysql.so');
                }
                # Fail now
         # Otherwise we get a suppressed fatal error, which is very hard to track down
         if ( !function_exists( 'mysql_connect' ) )
                {
                        echo ("ATS Error: SQL Not properly Installed.");
                        exit;
                };
                #Checking if the Tags table has been setup
         $query = "SELECT 1 FROM `".$this->dbprefix.$this->TagTableName."` LIMIT 0";
                $result = $this->DBConnect($query);
                if ($result==false)
                {
                        //If the table has not been setup attempt to make it
 
                                $query="
CREATE TABLE `".$this->dbname."`.`".$this->dbprefix.$this->TagTableName."` (
  id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  Page VARCHAR(100) NOT NULL,
  UserName VARCHAR(50) NOT NULL,
  Tag VARCHAR(50) NOT NULL,
  PRIMARY KEY (`id`)
);";
 
 
                        //Returning an error if the table cannot be created
                        //Yes I realize this is a shoddy error message, but its 2am and i'm sick
                        //so bugger off. (please)
                        if (!$this->DBConnect($query))
                        {
                                echo("ATS Error: Tag Table cannot be created."
                                        ."Please Insert the Following in your Wiki's MySQL Database:"
                                        ."<pre>"
                                    .$query
                                        ."</pre>"
                                        ."<br/><b>or</b>"
                                        ."Uncomment \$dbuser and \$dbpassword and set them to those "
                                        ."corresponding to a MySQL account with CREATE privledges for "
                                        ."the media wiki database and reload this page.");
                                   //Initialization of the Extension is stopped due to an SQL error
                                   exit();
                        }
                }
                //Sets up the session table in the RAM to track tagcloud users
                $this->SetupSession();
 
                //All is well so we allow the Magic Word/Hook to be initialized
                return true;
        }
 
 
        //I Realize all functions beyond this point are sql related and techincally
        //should be in their own object but i'm being lazy on this one.
 
        #Private function used to connect to the Tag Table
 public function DBConnect($query)
        {
 
                $link = mysql_connect ($this->dbserver, $this->dbuser, $this->dbpassword);
                mysql_select_db ($this->dbname, $link);
                $result = mysql_query ($query, $link);
                $link = null;
                return $result;
        }
        private function getSQLarray($queryresults)
        {
                if ($queryresults == false) return false;
                $resultsarray[] = null;
                $num_results = mysql_num_rows($queryresults);
                for ($i=0; $i < $num_results; $i ++)
                {
                        $resultsarray[] = mysql_fetch_array($queryresults);
                }
                return $resultsarray;
        }
        private function getSQLcolumntext_CommaSeperated($queryresults, $column)
        {
                if ($queryresults == false) return false;
 
                $resultstext = "";
                $num_results = mysql_num_rows($queryresults);
                for ($i=0; $i < $num_results; $i ++)
                {
                        $resultstext .= mysql_result($queryresults,$i,$column) . ",";
                }
                return $resultstext;
        }
 
 
        private function validateuser($pagename, $user, $key)
        {
                #If User is logged in
         if ($user != "" and $this->SessionEntryExists($user)) {
                        #If user's credentials check out
                 if (
                        $this->GetSessionData('ATShash',$user) == sha1($key) and #Checking Encryption Key
                 $this->GetSessionData('ATSpage',$user) == $pagename #Checking Page Name
                 )
                        {
                                return true;
                        }
                }
                return false;
        }
}
Personal tools
Namespaces
Variants
Actions
Site
Support
Download
Development
Communication
Print/export
Toolbox