diff --git a/.gitignore b/.gitignore index 238f7992..bb7db37f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ config.php release/* static/similar +*.swp +*.project +*.php~ diff --git a/classes/class_cache.php b/classes/class_cache.php index aae3b8cb..cd5e8ed1 100644 --- a/classes/class_cache.php +++ b/classes/class_cache.php @@ -38,7 +38,9 @@ class CACHE extends Memcache { 'stats_*', 'percentiles_*', 'top10tor_*', - 'query_lock_*' + 'query_lock_*', + 'top10votes_*', + 'similar_albums_*' ); public $CanClear = false; diff --git a/classes/class_format.php b/classes/class_format.php index 6ce89cd4..db52778c 100644 --- a/classes/class_format.php +++ b/classes/class_format.php @@ -60,24 +60,39 @@ public static function get_ratio_color($Ratio) { * @param int $Dividend AKA numerator * @param int $Divisor * @param boolean $Color if true, ratio will be coloured. - * @return formatted ratio HTML + * @return string formatted ratio HTML */ - public static function get_ratio_html($Dividend, $Divisor, $Color = true) { - if ($Divisor == 0 && $Dividend == 0) { - return '--'; - } elseif ($Divisor == 0) { - return '∞'; - } - $Ratio = number_format(max($Dividend/$Divisor-0.005,0), 2); //Subtract .005 to floor to 2 decimals - if ($Color) { - $Class = Format::get_ratio_color($Ratio); - if ($Class) { - $Ratio = ''.$Ratio.''; - } - } + public static function get_ratio_html($Dividend, $Divisor, $Color = true) + { + $Ratio = self::get_ratio($Dividend, $Divisor); + + if ($Ratio === false) return '--'; + if ($Ratio === '∞') return '∞'; + + if ($Color) + $Ratio = sprintf('%s', + self::get_ratio_color($Ratio), + self::get_ratio($Dividend, $Divisor, 5), + $Ratio + ); + return $Ratio; } + /** + * Returns ratio + * @param int $Dividend + * @param int $Divisor + * @return boolean|string|float + */ + public function get_ratio ($Dividend, $Divisor, $Decimal = 2) + { + if ($Divisor == 0 && $Dividend == 0) return false; + if ($Divisor == 0) return '∞'; + +// Subtract .005 to floor to 2 decimals + return number_format(max($Dividend/$Divisor - 0.005, 0), $Decimal); + } /** * Gets the query string of the current page, minus the parameters in $Exclude @@ -192,7 +207,7 @@ public static function get_pages($StartPage,$TotalRecords,$ItemsPerPage,$ShowPag $StartPosition = max($StartPosition, 1); - $QueryString = Format::get_url(array('page','post')); + $QueryString = self::get_url(array('page','post')); if ($QueryString != '') { $QueryString = '&'.$QueryString; } @@ -254,7 +269,7 @@ public static function get_size($Size, $Levels = 2) { if (func_num_args() == 1 && $Steps >= 4) { $Levels++; } - return number_format($Size,$Levels) . $Units[$Steps]; + return number_format($Size, $Levels) . $Units[$Steps]; } @@ -364,7 +379,7 @@ public static function selected($Name, $Value, $Attribute='selected', $Array = a */ public static function make_utf8($Str) { if ($Str!="") { - if (Format::is_utf8($Str)) { $Encoding="UTF-8"; } + if (self::is_utf8($Str)) { $Encoding="UTF-8"; } if (empty($Encoding)) { $Encoding=mb_detect_encoding($Str,'UTF-8, ISO-8859-1'); } if (empty($Encoding)) { $Encoding="ISO-8859-1"; } if ($Encoding=="UTF-8") { return $Str; } @@ -392,5 +407,4 @@ public static function is_utf8($Str) { ); } -} -?> +} \ No newline at end of file diff --git a/classes/class_mass_user_bookmarks_editor.php b/classes/class_mass_user_bookmarks_editor.php new file mode 100644 index 00000000..4bc127af --- /dev/null +++ b/classes/class_mass_user_bookmarks_editor.php @@ -0,0 +1,74 @@ +set_table($Table); + } + + /** + * Runs a SQL query and clears the bookmarks_torrent_{$UserID}_full Cache key + * + * $Cache->delete_value didn't always work, but setting the key to null, did. (?) + * + * @param string $sql + */ + protected function query_and_clear_cache ($sql) + { + if (is_string($sql) && $this->DB->query($sql)) { + $this->Cache->cache_value('bookmarks_torrent_' . $this->UserID, null, 0); + $this->Cache->cache_value('bookmarks_torrent_' . $this->UserID . '_full', null, 0); + } + } + + /** + * Uses (checkboxes) $_POST['remove'] to delete entries. + * + * Uses an IN() to match multiple items in one query. + */ + public function mass_remove () { + $SQL = array(); + foreach ($_POST['remove'] as $GroupID => $K) { + if (is_number($GroupID)) + $SQL[] = sprintf('%d', $GroupID); + } + + if (!empty($SQL)) { + $SQL = sprintf('DELETE FROM %s WHERE UserID = %d AND GroupID IN (%s)', + $this->Table, + $this->UserID, + implode(', ', $SQL) + ); + $this->query_and_clear_cache($SQL); + } + } + + /** + * Uses $_POST['sort'] values to update the DB. + */ + public function mass_update () { + $SQL = array(); + foreach ($_POST['sort'] as $GroupID => $Sort) { + if (is_number($Sort) && is_number($GroupID)) + $SQL[] = sprintf('(%d, %d, %d)', $GroupID, $Sort, $this->UserID); + } + + if (!empty($SQL)) { + $SQL = sprintf('INSERT INTO %s (GroupID, Sort, UserID) VALUES %s + ON DUPLICATE KEY UPDATE Sort = VALUES (Sort)', + $this->Table, + implode(', ', $SQL)); + $this->query_and_clear_cache($SQL); + } + } +} \ No newline at end of file diff --git a/classes/class_mass_user_torrents_editor.php b/classes/class_mass_user_torrents_editor.php new file mode 100644 index 00000000..11da274b --- /dev/null +++ b/classes/class_mass_user_torrents_editor.php @@ -0,0 +1,99 @@ +Cache = $Cache; + $this->DB = $DB; + $this->UserID = (int) $UserID; + if ($this->UserID < 1) error(403); + } + + /** + * Set the Table + * @param string $Table + */ + final public function set_table ($Table) + { + $this->Table = db_string($Table); + } + + /** + * Get the Table + * @param sting $Table + * @return string $Table + */ + final public function get_table () + { + return $this->Table; + } + + /** + * The extending class must provide a method to send a query and clear the cache + */ + abstract protected function query_and_clear_cache ($sql); + + /** + * A method to insert many rows into a single table + * Not required in subsequent classes + */ + public function mass_add () {} + + /** + * A method to remove many rows from a table + * The extending class must have a mass_remove method + */ + abstract public function mass_remove (); + + /** + * A method to update many rows in a table + * The extending class must have a mass_update method + */ + abstract public function mass_update (); +} \ No newline at end of file diff --git a/classes/class_mass_user_torrents_table_view.php b/classes/class_mass_user_torrents_table_view.php new file mode 100644 index 00000000..1f9eaa16 --- /dev/null +++ b/classes/class_mass_user_torrents_table_view.php @@ -0,0 +1,296 @@ +set_heading($Heading); + $this->set_edit_type($EditType); + + $this->UserID = (int) $UserID; + $this->LoggedUser = &$LoggedUser; + + $this->TorrentList = $TorrentList; + $this->CollageDataList = $CollageDataList; + + $this->HasTorrents = !empty($TorrentList); + if(!$this->HasTorrents) $this->no_torrents(); + } + + private function no_torrents () + { +?> +
Add some torrents and come back later.
+Sorting |
+
|
+
'.$this->to_html($Block['Val']).''; $this->NoImg--; + $this->InQuotes--; break; case 'hide': $Str.=''.(($Block['Attr']) ? $Block['Attr'] : 'Hidden text').': Show'; @@ -570,7 +716,7 @@ function to_html($Array) { } } break; - + case 'aud': if($this->NoImg>0 && $this->valid_url($Block['Val'])) { $Str.=''.$Block['Val'].' (audio)'; @@ -583,7 +729,7 @@ function to_html($Array) { $Str.=''; } break; - + case 'url': // Make sure the URL has a label if(empty($Block['Val'])) { @@ -593,7 +739,7 @@ function to_html($Array) { $Block['Val'] = $this->to_html($Block['Val']); $NoName = false; } - + if(!$this->valid_url($Block['Attr'])) { $Str.='[url='.$Block['Attr'].']'.$Block['Val'].'[/url]'; } else { @@ -606,23 +752,23 @@ function to_html($Array) { } } break; - + case 'inlineurl': if(!$this->valid_url($Block['Attr'], '', true)) { $Array = $this->parse($Block['Attr']); $Block['Attr'] = $Array; $Str.=$this->to_html($Block['Attr']); } - + else { $LocalURL = $this->local_url($Block['Attr']); if($LocalURL) { $Str.=''.substr($LocalURL,1).''; } else { $Str.=''.$Block['Attr'].''; - } + } } - + break; } @@ -630,8 +776,8 @@ function to_html($Array) { $this->Levels--; return $Str; } - - function raw_text($Array) { + + private function raw_text ($Array) { $Str = ''; foreach($Array as $Block) { if(is_string($Block)) { @@ -639,7 +785,8 @@ function raw_text($Array) { continue; } switch($Block['Type']) { - + case 'headline': + break; case 'b': case 'u': case 'i': @@ -667,7 +814,7 @@ function raw_text($Array) { $Str.=$Block['Tag'].$this->raw_text($Line); } break; - + case 'url': // Make sure the URL has a label if(empty($Block['Val'])) { @@ -675,10 +822,10 @@ function raw_text($Array) { } else { $Block['Val'] = $this->raw_text($Block['Val']); } - + $Str.=$Block['Val']; break; - + case 'inlineurl': if(!$this->valid_url($Block['Attr'], '', true)) { $Array = $this->parse($Block['Attr']); @@ -688,14 +835,14 @@ function raw_text($Array) { else { $Str.=$Block['Attr']; } - + break; } } return $Str; } - - function smileys($Str) { + + private function smileys ($Str) { global $LoggedUser; if(!empty($LoggedUser['DisableSmileys'])) { return $Str; @@ -706,18 +853,17 @@ function smileys($Str) { } /* -//Uncomment this part to test the class via command line: +//Uncomment this part to test the class via command line: function display_str($Str) {return $Str;} function check_perms($Perm) {return true;} -$Str = "hello +$Str = "hello [pre]http://anonym.to/?http://whatshirts.portmerch.com/ ====hi==== ===hi=== ==hi==[/pre] ====hi==== hi"; -$Text = NEW TEXT; +$Text = new TEXT; echo $Text->full_format($Str); echo "\n" */ -?> diff --git a/classes/class_textarea_preview.php b/classes/class_textarea_preview.php new file mode 100644 index 00000000..63865d63 --- /dev/null +++ b/classes/class_textarea_preview.php @@ -0,0 +1,199 @@ + + * @return void + */ + static public function JavaScript ($all = true) + { + if (self::$Textareas === 0) return; + if (self::$Exectuted === false && $all) + View::parse('generic/textarea/script.phtml'); + + self::$Exectuted = true; + self::iterator(); + } + + /** + * This iterator generates JavaScript to initialize each JavaScript + * TextareaPreview object. + * + * It will generate a numeric or custom ID related to the textarea. + * @static + * @return void + */ + static private function iterator () + { + $script = array(); + for($i = 0; $i < self::$Textareas; $i++) { + if (isset(self::$_ID[$i]) && is_string(self::$_ID[$i])) { + $a = sprintf('%d, "%s"', $i, self::$_ID[$i]); + } else { + $a = $i; + } + $script[] = sprintf('[%s]', $a); + } + if (!empty($script)) + View::parse('generic/textarea/script_factory.phtml', + array('script' => join(', ', $script))); + } +} + +/** + * Textarea Preview Class + * + * This class generates a textarea that works with the JS preview script. + * + * Templates found in design/views/generic/textarea + * + * @example
buttons(); // output buttons + * + * $text->preview(); // output preview div + * + * // Create a textarea with custom preview wrapper around a table + * // the table will be (in)visible depending on the toggle + * $text = new TEXTAREA_PREVIEW('body', '', '', 30, 10, false, false); + * $id = $text->getID(); + * + * // some template + *+ */ +class TEXTAREA_PREVIEW extends TEXTAREA_PREVIEW_SUPER +{ + /** + * @var int Unique ID + */ + private $id; + + /** + * Flag for preview output + * @var bool $preview + */ + private $preview = false; + + /** + * This method creates a textarea + * + * @param string $Name name attribute + * @param string $ID id attribute + * @param string $Value default text attribute + * @param string $Cols cols attribute + * @param string $Rows rows attribute + * @param bool $Preview add the preview divs near the textarea + * @param bool $Buttons add the edit/preview buttons near the textarea + * + * If false for either, use the appropriate methods to add the those + * elements elsewhere. Alternatively, use getID to create your own. + * + * @param array $ExtraAttributes array of attribute="value" + */ + public function __construct ($Name, $ID = '', $Value='', $Cols=50, $Rows=10, + $Preview = true, $Buttons = true, array $ExtraAttributes = array() + ) { + $this->id = parent::$Textareas; + parent::$Textareas += 1; + array_push(parent::$_ID, $ID); + + if (empty($ID)) $ID = 'quickpost_' . $this->id; + + if (!empty($ExtraAttributes)) + $Attributes = ' ' . implode(' ', $ExtraAttributes); + else + $Attributes = ''; + + if ($Preview === true) $this->preview(); + + View::parse('generic/textarea/textarea.phtml', array( + 'ID' => $ID, + 'NID' => $this->id, + 'Name' => &$Name, + 'Value' => &$Value, + 'Cols' => &$Cols, + 'Rows' => &$Rows, + 'Attributes' => &$Attributes + )); + + if ($Buttons === true) $this->buttons(); + } + + /** + * Outputs the divs required for previewing the AJAX content + * Will only output once + */ + public function preview () + { + if (!$this->preview) + View::parse('generic/textarea/preview.phtml', array('ID' => $this->id)); + $this->preview = true; + } + + /** + * Outputs the preview and edit buttons + * Can be called many times to place buttons in different areas + */ + public function buttons () + { + View::parse('generic/textarea/buttons.phtml', array('ID' => $this->id)); + } + + /** + * Returns the textarea's numeric ID. + */ + public function getID () + { + return $this->id; + } +} \ No newline at end of file diff --git a/classes/class_torrent_form.php b/classes/class_torrent_form.php index 547a4213..2e5fbf51 100644 --- a/classes/class_torrent_form.php +++ b/classes/class_torrent_form.php @@ -11,7 +11,7 @@ ** When it is called from the edit page, the forms are shortened quite a bit. ** ** ** ********************************************************************************/ - + class TORRENT_FORM { var $Categories = array(); var $Formats = array(); @@ -23,21 +23,21 @@ class TORRENT_FORM { var $TorrentID = false; var $Disabled = ''; var $DisabledFlag = false; - + function TORRENT_FORM($Torrent = false, $Error = false, $NewTorrent = true) { - + $this->NewTorrent = $NewTorrent; $this->Torrent = $Torrent; $this->Error = $Error; - + global $Categories, $Formats, $Bitrates, $Media, $TorrentID; - + $this->Categories = $Categories; $this->Formats = $Formats; $this->Bitrates = $Bitrates; $this->Media = $Media; $this->TorrentID = $TorrentID; - + if($this->Torrent && $this->Torrent['GroupID']) { $this->Disabled = ' disabled="disabled"'; $this->DisabledFlag = true; @@ -71,7 +71,7 @@ function head() { if($this->Torrent && $this->Torrent['GroupID']) { ?> - } + } if($this->Torrent && $this->Torrent['RequestID']) { ?> } @@ -99,7 +99,7 @@ function head() { echo ">"; echo $Cat; echo "\n"; - } + } ?> @@ -109,12 +109,12 @@ function head() {+ *+ *+ *
+ *+ * + *+ * + * + *
- because
+ because
@@ -154,34 +154,34 @@ function foot() {
} //function foot
-
-
+
+
function music_form($GenreTags) {
$Torrent = $this->Torrent;
$IsRemaster = !empty($Torrent['Remastered']);
$UnknownRelease = !$this->NewTorrent && $IsRemaster && !$Torrent['RemasterYear'];
-
+
if($Torrent['GroupID']) {
global $DB;
$DB->query("SELECT ID,
RemasterYear,
- RemasterTitle,
- RemasterRecordLabel,
- RemasterCatalogueNumber
- FROM torrents
- WHERE GroupID = ".$Torrent['GroupID']."
- AND Remastered = '1'
+ RemasterTitle,
+ RemasterRecordLabel,
+ RemasterCatalogueNumber
+ FROM torrents
+ WHERE GroupID = ".$Torrent['GroupID']."
+ AND Remastered = '1'
AND RemasterYear != 0
- ORDER BY RemasterYear DESC,
- RemasterTitle DESC,
- RemasterRecordLabel DESC,
+ ORDER BY RemasterYear DESC,
+ RemasterTitle DESC,
+ RemasterRecordLabel DESC,
RemasterCatalogueNumber DESC");
-
+
if($DB->record_count() > 0) {
$GroupRemasters = $DB->to_array(false, MYSQLI_BOTH, false);
}
}
-
+
global $DB;
$HasLog = $Torrent['HasLog'];
$HasCue = $Torrent['HasCue'];
@@ -196,7 +196,7 @@ function music_form($GenreTags) {
+
+
diff --git a/gazelle.sql b/gazelle.sql
index 8f9673a1..fe7feed5 100644
--- a/gazelle.sql
+++ b/gazelle.sql
@@ -23,6 +23,19 @@ CREATE TABLE `api_users` (
KEY `UserID` (`UserID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+CREATE TABLE `artist_comments` (
+ `ID` int(10) NOT NULL AUTO_INCREMENT,
+ `ArtistID` int(10) NOT NULL,
+ `AuthorID` int(10) NOT NULL,
+ `AddedTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `Body` mediumtext COLLATE utf8_bin,
+ `EditedUserID` int(10) DEFAULT NULL,
+ `EditedTime` datetime DEFAULT NULL,
+ PRIMARY KEY (`ID`),
+ KEY `TopicID` (`ArtistID`),
+ KEY `AuthorID` (`AuthorID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
CREATE TABLE `artists_alias` (
`AliasID` int(10) NOT NULL AUTO_INCREMENT,
`ArtistID` int(10) NOT NULL,
@@ -39,11 +52,20 @@ CREATE TABLE `artists_group` (
`Name` varchar(200) CHARACTER SET utf8 COLLATE utf8_swedish_ci DEFAULT NULL,
`RevisionID` int(12) DEFAULT NULL,
`VanityHouse` tinyint(1) DEFAULT '0',
+ `LastCommentID` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`ArtistID`),
KEY `Name` (`Name`),
KEY `RevisionID` (`RevisionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE `artists_last_read_comments` (
+ `UserID` int(10) NOT NULL,
+ `ArtistID` int(10) NOT NULL,
+ `CommentID` int(10) NOT NULL,
+ PRIMARY KEY (`UserID`,`ArtistID`),
+ KEY `ArtistID` (`ArtistID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
CREATE TABLE `artists_similar` (
`ArtistID` int(10) NOT NULL DEFAULT '0',
`SimilarID` int(12) NOT NULL DEFAULT '0',
@@ -490,6 +512,12 @@ CREATE TABLE `pm_messages` (
KEY `ConvID` (`ConvID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE `push_notifications_usage` (
+ `PushService` varchar(10) NOT NULL,
+ `TimesUsed` int(10) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`PushService`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
CREATE TABLE `reports` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`UserID` int(10) unsigned NOT NULL DEFAULT '0',
@@ -1017,6 +1045,7 @@ CREATE TABLE `torrents_group` (
`WikiImage` varchar(255) COLLATE utf8_bin NOT NULL,
`SearchText` varchar(500) COLLATE utf8_bin NOT NULL,
`VanityHouse` tinyint(1) DEFAULT '0',
+ `LastCommentID` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `ArtistID` (`ArtistID`),
KEY `CategoryID` (`CategoryID`),
@@ -1026,6 +1055,14 @@ CREATE TABLE `torrents_group` (
KEY `RevisionID` (`RevisionID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE `torrents_last_read_comments` (
+ `UserID` int(10) NOT NULL,
+ `GroupID` int(10) NOT NULL,
+ `CommentID` int(10) NOT NULL,
+ PRIMARY KEY (`UserID`,`GroupID`),
+ KEY `GroupID` (`GroupID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
CREATE TABLE `torrents_logs_new` (
`LogID` int(10) NOT NULL AUTO_INCREMENT,
`TorrentID` int(10) NOT NULL DEFAULT '0',
@@ -1117,6 +1154,13 @@ CREATE TABLE `torrents_votes` (
CONSTRAINT `torrents_votes_ibfk_1` FOREIGN KEY (`GroupID`) REFERENCES `torrents_group` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE `users_artists_comments_subscriptions` (
+ `UserID` int(10) NOT NULL,
+ `ArtistID` int(10) NOT NULL,
+ PRIMARY KEY (`UserID`,`ArtistID`),
+ KEY `ArtistID` (`ArtistID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
CREATE TABLE `users_collage_subs` (
`UserID` int(10) NOT NULL,
`CollageID` int(10) NOT NULL,
@@ -1125,6 +1169,13 @@ CREATE TABLE `users_collage_subs` (
KEY `CollageID` (`CollageID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE `users_comments_subscriptions` (
+ `UserID` int(10) NOT NULL,
+ `GroupID` int(10) NOT NULL,
+ PRIMARY KEY (`UserID`,`GroupID`),
+ KEY `GroupID` (`GroupID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
CREATE TABLE `users_downloads` (
`UserID` int(10) NOT NULL,
`TorrentID` int(1) NOT NULL,
@@ -1214,6 +1265,7 @@ CREATE TABLE `users_info` (
`SupportFor` varchar(255) NOT NULL,
`TorrentGrouping` enum('0','1','2') NOT NULL COMMENT '0=Open,1=Closed,2=Off',
`ShowTags` enum('0','1') NOT NULL DEFAULT '1',
+ `NotifyOnQuote` enum('0','1','2') NOT NULL DEFAULT '0',
`AuthKey` varchar(32) NOT NULL,
`ResetKey` varchar(32) NOT NULL,
`ResetExpires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -1243,6 +1295,8 @@ CREATE TABLE `users_info` (
`PermittedForums` varchar(150) NOT NULL DEFAULT '',
`UnseededAlerts` enum('0','1') NOT NULL DEFAULT '0',
`LastReadBlog` int(10) NOT NULL DEFAULT '0',
+ `TorrentsCommentsCatchupTime` datetime DEFAULT NULL,
+ `ArtistsCommentsCatchupTime` datetime DEFAULT NULL,
UNIQUE KEY `UserID` (`UserID`),
KEY `SupportFor` (`SupportFor`),
KEY `DisableInvites` (`DisableInvites`),
@@ -1344,6 +1398,17 @@ CREATE TABLE `users_notify_filters` (
KEY `ToYear` (`ToYear`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE `users_notify_quoted` (
+ `UserID` int(10) NOT NULL,
+ `QuoterID` int(10) NOT NULL,
+ `ForumID` int(6) unsigned DEFAULT NULL,
+ `TopicID` int(10) NOT NULL,
+ `PostID` int(10) NOT NULL,
+ `UnRead` enum('0','1') NOT NULL DEFAULT '1',
+ `Date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (`UserID`,`PostID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
CREATE TABLE `users_notify_torrents` (
`UserID` int(10) NOT NULL,
`FilterID` int(10) NOT NULL,
@@ -1373,6 +1438,13 @@ CREATE TABLE `users_points_requests` (
KEY `RequestID` (`RequestID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+CREATE TABLE `users_push_notifications` (
+ `UserID` int(10) NOT NULL,
+ `PushService` tinyint(1) NOT NULL DEFAULT '0',
+ `PushOptions` text NOT NULL,
+ PRIMARY KEY (`UserID`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
CREATE TABLE `users_sessions` (
`UserID` int(10) NOT NULL,
`SessionID` char(32) NOT NULL,
@@ -1544,7 +1616,7 @@ CREATE TABLE `xbt_snatched` (
SET FOREIGN_KEY_CHECKS = 1;
-INSERT INTO permissions (ID, Level, Name, `Values`, DisplayStaff) VALUES (15, 1000, 'Sysop', 'a:98:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:21:\"site_see_old_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:19:\"site_advanced_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:20:\"site_collages_delete\";i:1;s:23:\"site_collages_subscribe\";i:1;s:22:\"site_collages_personal\";i:1;s:28:\"site_collages_renamepersonal\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:22:\"site_can_invite_always\";i:1;s:27:\"site_send_unlimited_invites\";i:1;s:22:\"site_moderate_requests\";i:1;s:18:\"site_delete_artist\";i:1;s:20:\"site_moderate_forums\";i:1;s:17:\"site_admin_forums\";i:1;s:23:\"site_forums_double_post\";i:1;s:14:\"site_view_flow\";i:1;s:18:\"site_view_full_log\";i:1;s:28:\"site_view_torrent_snatchlist\";i:1;s:18:\"site_recommend_own\";i:1;s:27:\"site_manage_recommendations\";i:1;s:15:\"site_delete_tag\";i:1;s:23:\"site_disable_ip_history\";i:1;s:14:\"zip_downloader\";i:1;s:10:\"site_debug\";i:1;s:17:\"site_proxy_images\";i:1;s:16:\"site_search_many\";i:1;s:20:\"users_edit_usernames\";i:1;s:16:\"users_edit_ratio\";i:1;s:20:\"users_edit_own_ratio\";i:1;s:17:\"users_edit_titles\";i:1;s:18:\"users_edit_avatars\";i:1;s:18:\"users_edit_invites\";i:1;s:22:\"users_edit_watch_hours\";i:1;s:21:\"users_edit_reset_keys\";i:1;s:19:\"users_edit_profiles\";i:1;s:18:\"users_view_friends\";i:1;s:20:\"users_reset_own_keys\";i:1;s:19:\"users_edit_password\";i:1;s:19:\"users_promote_below\";i:1;s:16:\"users_promote_to\";i:1;s:16:\"users_give_donor\";i:1;s:10:\"users_warn\";i:1;s:19:\"users_disable_users\";i:1;s:19:\"users_disable_posts\";i:1;s:17:\"users_disable_any\";i:1;s:18:\"users_delete_users\";i:1;s:18:\"users_view_invites\";i:1;s:20:\"users_view_seedleech\";i:1;s:19:\"users_view_uploaded\";i:1;s:15:\"users_view_keys\";i:1;s:14:\"users_view_ips\";i:1;s:16:\"users_view_email\";i:1;s:23:\"users_override_paranoia\";i:1;s:12:\"users_logout\";i:1;s:20:\"users_make_invisible\";i:1;s:9:\"users_mod\";i:1;s:13:\"torrents_edit\";i:1;s:15:\"torrents_delete\";i:1;s:20:\"torrents_delete_fast\";i:1;s:18:\"torrents_freeleech\";i:1;s:20:\"torrents_search_fast\";i:1;s:17:\"torrents_hide_dnu\";i:1;s:19:\"torrents_fix_ghosts\";i:1;s:17:\"admin_manage_news\";i:1;s:17:\"admin_manage_blog\";i:1;s:18:\"admin_manage_polls\";i:1;s:19:\"admin_manage_forums\";i:1;s:16:\"admin_manage_fls\";i:1;s:13:\"admin_reports\";i:1;s:26:\"admin_advanced_user_search\";i:1;s:18:\"admin_create_users\";i:1;s:15:\"admin_donor_log\";i:1;s:19:\"admin_manage_ipbans\";i:1;s:9:\"admin_dnu\";i:1;s:17:\"admin_clear_cache\";i:1;s:15:\"admin_whitelist\";i:1;s:24:\"admin_manage_permissions\";i:1;s:14:\"admin_schedule\";i:1;s:17:\"admin_login_watch\";i:1;s:17:\"admin_manage_wiki\";i:1;s:18:\"admin_update_geoip\";i:1;s:21:\"site_collages_recover\";i:1;s:19:\"torrents_add_artist\";i:1;s:13:\"edit_unknowns\";i:1;s:19:\"forums_polls_create\";i:1;s:21:\"forums_polls_moderate\";i:1;s:12:\"project_team\";i:1;s:25:\"torrents_edit_vanityhouse\";i:1;s:23:\"artist_edit_vanityhouse\";i:1;}', '1'), (2, 100, 'User', 'a:7:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:14:\"site_edit_wiki\";i:1;s:19:\"torrents_add_artist\";i:1;}', '0'), (3, 150, 'Member', 'a:10:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_collages_manage\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:19:\"torrents_add_artist\";i:1;}', '0'), (4, 200, 'Power User', 'a:14:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:14:\"zip_downloader\";i:1;s:19:\"forums_polls_create\";i:1;s:19:\"torrents_add_artist\";i:1;} ', '0'), (5, 250, 'Elite', 'a:18:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:19:\"site_advanced_top10\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:15:\"site_delete_tag\";i:1;s:14:\"zip_downloader\";i:1;s:19:\"forums_polls_create\";i:1;s:13:\"torrents_edit\";i:1;s:19:\"torrents_add_artist\";i:1;s:17:\"admin_clear_cache\";i:1;}', '0'), (20, 202, 'Donor', 'a:9:{s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:14:\"zip_downloader\";i:1;s:19:\"forums_polls_create\";i:1;}', '0'), (19, 201, 'Artist', 'a:9:{s:10:\"site_leech\";s:1:\"1\";s:11:\"site_upload\";s:1:\"1\";s:9:\"site_vote\";s:1:\"1\";s:20:\"site_submit_requests\";s:1:\"1\";s:20:\"site_advanced_search\";s:1:\"1\";s:10:\"site_top10\";s:1:\"1\";s:19:\"site_make_bookmarks\";s:1:\"1\";s:14:\"site_edit_wiki\";s:1:\"1\";s:18:\"site_recommend_own\";s:1:\"1\";}', '0');
+INSERT INTO permissions (ID, Level, Name, `Values`, DisplayStaff) VALUES (15, 1000, 'Sysop', 'a:99:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:21:\"site_see_old_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:19:\"site_advanced_top10\";i:1;s:16:\"site_album_votes\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:20:\"site_collages_delete\";i:1;s:23:\"site_collages_subscribe\";i:1;s:22:\"site_collages_personal\";i:1;s:28:\"site_collages_renamepersonal\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:22:\"site_can_invite_always\";i:1;s:27:\"site_send_unlimited_invites\";i:1;s:22:\"site_moderate_requests\";i:1;s:18:\"site_delete_artist\";i:1;s:20:\"site_moderate_forums\";i:1;s:17:\"site_admin_forums\";i:1;s:23:\"site_forums_double_post\";i:1;s:14:\"site_view_flow\";i:1;s:18:\"site_view_full_log\";i:1;s:28:\"site_view_torrent_snatchlist\";i:1;s:18:\"site_recommend_own\";i:1;s:27:\"site_manage_recommendations\";i:1;s:15:\"site_delete_tag\";i:1;s:23:\"site_disable_ip_history\";i:1;s:14:\"zip_downloader\";i:1;s:10:\"site_debug\";i:1;s:17:\"site_proxy_images\";i:1;s:16:\"site_search_many\";i:1;s:20:\"users_edit_usernames\";i:1;s:16:\"users_edit_ratio\";i:1;s:20:\"users_edit_own_ratio\";i:1;s:17:\"users_edit_titles\";i:1;s:18:\"users_edit_avatars\";i:1;s:18:\"users_edit_invites\";i:1;s:22:\"users_edit_watch_hours\";i:1;s:21:\"users_edit_reset_keys\";i:1;s:19:\"users_edit_profiles\";i:1;s:18:\"users_view_friends\";i:1;s:20:\"users_reset_own_keys\";i:1;s:19:\"users_edit_password\";i:1;s:19:\"users_promote_below\";i:1;s:16:\"users_promote_to\";i:1;s:16:\"users_give_donor\";i:1;s:10:\"users_warn\";i:1;s:19:\"users_disable_users\";i:1;s:19:\"users_disable_posts\";i:1;s:17:\"users_disable_any\";i:1;s:18:\"users_delete_users\";i:1;s:18:\"users_view_invites\";i:1;s:20:\"users_view_seedleech\";i:1;s:19:\"users_view_uploaded\";i:1;s:15:\"users_view_keys\";i:1;s:14:\"users_view_ips\";i:1;s:16:\"users_view_email\";i:1;s:23:\"users_override_paranoia\";i:1;s:12:\"users_logout\";i:1;s:20:\"users_make_invisible\";i:1;s:9:\"users_mod\";i:1;s:13:\"torrents_edit\";i:1;s:15:\"torrents_delete\";i:1;s:20:\"torrents_delete_fast\";i:1;s:18:\"torrents_freeleech\";i:1;s:20:\"torrents_search_fast\";i:1;s:17:\"torrents_hide_dnu\";i:1;s:19:\"torrents_fix_ghosts\";i:1;s:17:\"admin_manage_news\";i:1;s:17:\"admin_manage_blog\";i:1;s:18:\"admin_manage_polls\";i:1;s:19:\"admin_manage_forums\";i:1;s:16:\"admin_manage_fls\";i:1;s:13:\"admin_reports\";i:1;s:26:\"admin_advanced_user_search\";i:1;s:18:\"admin_create_users\";i:1;s:15:\"admin_donor_log\";i:1;s:19:\"admin_manage_ipbans\";i:1;s:9:\"admin_dnu\";i:1;s:17:\"admin_clear_cache\";i:1;s:15:\"admin_whitelist\";i:1;s:24:\"admin_manage_permissions\";i:1;s:14:\"admin_schedule\";i:1;s:17:\"admin_login_watch\";i:1;s:17:\"admin_manage_wiki\";i:1;s:18:\"admin_update_geoip\";i:1;s:21:\"site_collages_recover\";i:1;s:19:\"torrents_add_artist\";i:1;s:13:\"edit_unknowns\";i:1;s:19:\"forums_polls_create\";i:1;s:21:\"forums_polls_moderate\";i:1;s:12:\"project_team\";i:1;s:25:\"torrents_edit_vanityhouse\";i:1;s:23:\"artist_edit_vanityhouse\";i:1;}', '1'), (2, 100, 'User', 'a:7:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:14:\"site_edit_wiki\";i:1;s:19:\"torrents_add_artist\";i:1;}', '0'), (3, 150, 'Member', 'a:10:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_collages_manage\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:19:\"torrents_add_artist\";i:1;}', '0'), (4, 200, 'Power User', 'a:14:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:14:\"zip_downloader\";i:1;s:19:\"forums_polls_create\";i:1;s:19:\"torrents_add_artist\";i:1;} ', '0'), (5, 250, 'Elite', 'a:18:{s:10:\"site_leech\";i:1;s:11:\"site_upload\";i:1;s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:19:\"site_advanced_top10\";i:1;s:19:\"site_make_bookmarks\";i:1;s:14:\"site_edit_wiki\";i:1;s:15:\"site_delete_tag\";i:1;s:14:\"zip_downloader\";i:1;s:19:\"forums_polls_create\";i:1;s:13:\"torrents_edit\";i:1;s:19:\"torrents_add_artist\";i:1;s:17:\"admin_clear_cache\";i:1;}', '0'), (20, 202, 'Donor', 'a:9:{s:9:\"site_vote\";i:1;s:20:\"site_submit_requests\";i:1;s:20:\"site_advanced_search\";i:1;s:10:\"site_top10\";i:1;s:20:\"site_torrents_notify\";i:1;s:20:\"site_collages_create\";i:1;s:20:\"site_collages_manage\";i:1;s:14:\"zip_downloader\";i:1;s:19:\"forums_polls_create\";i:1;}', '0'), (19, 201, 'Artist', 'a:9:{s:10:\"site_leech\";s:1:\"1\";s:11:\"site_upload\";s:1:\"1\";s:9:\"site_vote\";s:1:\"1\";s:20:\"site_submit_requests\";s:1:\"1\";s:20:\"site_advanced_search\";s:1:\"1\";s:10:\"site_top10\";s:1:\"1\";s:19:\"site_make_bookmarks\";s:1:\"1\";s:14:\"site_edit_wiki\";s:1:\"1\";s:18:\"site_recommend_own\";s:1:\"1\";}', '0');
INSERT INTO stylesheets (ID, Name, Description, `Default`) VALUES (9, 'Proton', 'Proton by Protiek', '0'), (2, 'Layer cake', 'Grey stylesheet by Emm', '0'), (21, 'postmod', 'Upgrade on anorex', '1');
diff --git a/sections/ajax/index.php b/sections/ajax/index.php
index dff1ea20..aa382968 100644
--- a/sections/ajax/index.php
+++ b/sections/ajax/index.php
@@ -101,6 +101,9 @@
case 'userhistory':
require(SERVER_ROOT.'/sections/ajax/userhistory/index.php');
break;
+ case 'votefavorite':
+ require(SERVER_ROOT.'/sections/ajax/takevote.php');
+ break;
default:
// If they're screwing around with the query string
print json_encode(array('status' => 'failure'));
diff --git a/sections/ajax/preview.php b/sections/ajax/preview.php
index 085a1e98..2ec6b0ab 100644
--- a/sections/ajax/preview.php
+++ b/sections/ajax/preview.php
@@ -2,7 +2,7 @@
/* AJAX Previews, simple stuff. */
include(SERVER_ROOT.'/classes/class_text.php'); // Text formatting class
-$Text = new TEXT;
+$Text = new TEXT(true);
if(!empty($_POST['AdminComment'])) {
echo $Text->full_format($_POST['AdminComment']);
@@ -10,4 +10,4 @@
$Content = $_REQUEST['body']; // Don't use URL decode.
echo $Text->full_format($Content);
}
-?>
+
diff --git a/sections/ajax/takevote.php b/sections/ajax/takevote.php
new file mode 100644
index 00000000..3ceff73d
--- /dev/null
+++ b/sections/ajax/takevote.php
@@ -0,0 +1,204 @@
+
+authorize();
+
+$GroupID = $_REQUEST['groupid'];
+if (!is_number($GroupID)) {
+ echo 'Invalid Group';
+ die();
+}
+
+// What groups has this guy voted?
+$UserVotes = $Cache->get_value('voted_albums_'.$LoggedUser['ID']);
+if ($UserVotes === FALSE) {
+ $DB->query('SELECT GroupID, Type FROM users_votes WHERE UserID='.$LoggedUser['ID']);
+ $UserVotes = $DB->to_array('GroupID', MYSQL_ASSOC, false);
+ $Cache->cache_value('voted_albums_'.$LoggedUser['ID'], $UserVotes);
+}
+
+// What are the votes for this group?
+$GroupVotes = $Cache->get_value('votes_'.$GroupID);
+if ($GroupVotes === FALSE) {
+ $DB->query("SELECT Ups AS Ups, Total AS Total FROM torrents_votes WHERE GroupID=$GroupID");
+ if ($DB->record_count() == 0) {
+ $GroupVotes = array('Ups'=>0, 'Total'=>0);
+ } else {
+ $GroupVotes = $DB->next_record(MYSQLI_ASSOC, false);
+ }
+ $Cache->cache_value('votes_'.$GroupID, $GroupVotes);
+}
+
+$UserID = $LoggedUser['ID'];
+if ($_REQUEST['do'] == 'vote') {
+ if (isset($UserVotes[$GroupID]) || !check_perms('site_album_votes')) {
+ echo 'noaction';
+ die();
+ }
+ if ($_REQUEST['vote'] != 'up' && $_REQUEST['vote'] != 'down') {
+ echo 'badvote';
+ die();
+ }
+ $Type = ($_REQUEST['vote'] == 'up')?"Up":"Down";
+
+ // Update the group's cache key
+ $GroupVotes['Total'] += 1;
+ if ($Type == "Up") {
+ $GroupVotes['Ups'] += 1;
+ }
+ $Cache->cache_value('votes_'.$GroupID, $GroupVotes);
+
+ // Update the two votes tables
+ $DB->query("INSERT INTO users_votes (UserID, GroupID, Type) VALUES ($UserID, $GroupID, '$Type') ON DUPLICATE KEY UPDATE Type = '$Type'");
+ // If the group has no votes yet, we need an insert, otherwise an update
+ // so we can cut corners and use the magic of INSERT...ON DUPLICATE KEY UPDATE...
+ // to accomplish both in one query
+ $DB->query("INSERT INTO torrents_votes (GroupID, Total, Ups, Score)
+ VALUES ($GroupID, 1, ".($Type=='Up'?1:0).", 0)
+ ON DUPLICATE KEY UPDATE Total = Total + 1,
+ Score = binomial_ci(".$GroupVotes['Ups'].",". $GroupVotes['Total'].")".
+ ($Type=='Up'?', Ups = Ups+1':''));
+
+ $UserVotes[$GroupID] = array('GroupID' => $GroupID, 'Type' => $Type);
+
+ // Update this guy's cache key
+ $Cache->cache_value('voted_albums_'.$LoggedUser['ID'], $UserVotes);
+
+ // Update the paired cache keys for "people who liked"
+ // First update this album's paired votes. If this keys is magically not set,
+ // our life just got a bit easier. We're only tracking paired votes on upvotes.
+ if ($Type == 'Up') {
+ $VotePairs = $Cache->get_value('vote_pairs_'.$GroupID);
+ if ($VotePairs !== FALSE) {
+ foreach ($UserVotes as $Vote) {
+ if ($Vote['GroupID'] == $GroupID) {
+ continue;
+ }
+ // Go through each of his other votes, incrementing the
+ // corresponding keys in this groups vote_pairs array
+ if (isset($VotePairs[$Vote['GroupID']])) {
+ $VotePairs[$Vote['GroupID']]['Total'] += 1;
+ if ($Vote['Type'] == 'Up') {
+ $VotePairs[$Vote['GroupID']]['Ups'] += 1;
+ }
+ } else {
+ $VotePairs[$Vote['GroupID']] = array('GroupID'=>$Vote['GroupID'],
+ 'Total' => 1,
+ 'Ups'=>($Type == 'Up')?1:0);
+ }
+ }
+ }
+ $Cache->cache_value('vote_pairs_'.$GroupID, $VotePairs);
+ }
+
+ // Now do the paired votes keys for all of this guy's other votes
+ foreach ($UserVotes as $VGID => $Vote) {
+ if ($Vote['Type'] != 'Up') {
+ // We're only track paired votes on upvotes
+ continue;
+ }
+ // Again, if the cache key is not set, move along
+ $VotePairs = $Cache->get_value('vote_pairs_'.$VGID);
+ if ($VotePairs !== FALSE) {
+ // Go through all of the other albums paired to this one, and update
+ // this group's entry in their vote_pairs keys
+ if (isset($VotePairs[$GroupID])) {
+ $VotePairs[$GroupID]['Total']++;
+ if ($Type == 'Up') {
+ $VotePairs[$GroupID]['Ups']++;
+ }
+ } else {
+ $VotePairs[$GroupID] = array('GroupID' => $GroupID,
+ 'Total' => 1,
+ 'Ups'=>($Type == 'Up')?1:0);
+ }
+ $Cache->cache_value('vote_pairs_'.$VGID, $VotePairs);
+ }
+ }
+
+
+ echo 'success';
+} elseif ($_REQUEST['do'] == 'unvote') {
+ if (!isset($UserVotes[$GroupID])) {
+ echo 'noaction';
+ die();
+ }
+ $Type = $UserVotes[$GroupID]['Type'];
+
+ $DB->query("DELETE FROM users_votes WHERE UserID=$UserID AND GroupID=$GroupID");
+
+ // Update personal cache key
+ unset($UserVotes[$GroupID]);
+ $Cache->cache_value('voted_albums_'.$LoggedUser['ID'], $UserVotes);
+
+ // Update the group's cache key
+ $GroupVotes['Total'] -= 1;
+ if ($Type == "Up") {
+ $GroupVotes['Ups'] -= 1;
+ }
+ $Cache->cache_value('votes_'.$GroupID, $GroupVotes);
+
+ $DB->query("UPDATE torrents_votes SET Total = GREATEST(0, Total - 1),
+ Score = binomial_ci(".$GroupVotes['Ups'].",".$GroupVotes['Total'].")".
+ ($Type=='Up'?', Ups = GREATEST(0, Ups - 1)':'')."
+ WHERE GroupID=$GroupID");
+ // Update paired cache keys
+ // First update this album's paired votes. If this keys is magically not set,
+ // our life just got a bit easier. We're only tracking paired votes on upvotes.
+ if ($Type == 'Up') {
+ $VotePairs = $Cache->get_value('vote_pairs_'.$GroupID);
+ if ($VotePairs !== FALSE) {
+ foreach ($UserVotes as $Vote) {
+ if (isset($VotePairs[$Vote['GroupID']])) {
+ if ($VotePairs[$Vote['GroupID']]['Total'] == 0) {
+ // Something is screwy
+ $Cache->delete_value('vote_pairs_'.$GroupID);
+ continue;
+ }
+ $VotePairs[$Vote['GroupID']]['Total'] -= 1;
+ if ($Vote['Type'] == 'Up') {
+ $VotePairs[$Vote['GroupID']]['Ups'] -= 1;
+ }
+ } else {
+ // Something is screwy, kill the key and move on
+ $Cache->delete_value('vote_pairs_'.$GroupID);
+ break;
+ }
+ }
+ }
+ $Cache->cache_value('vote_pairs_'.$GroupID, $VotePairs);
+ }
+
+ // Now do the paired votes keys for all of this guy's other votes
+ foreach ($UserVotes as $VGID => $Vote) {
+ if ($Vote['Type'] != 'Up') {
+ // We're only track paired votes on upvotes
+ continue;
+ }
+ // Again, if the cache key is not set, move along
+ $VotePairs = $Cache->get_value('vote_pairs_'.$VGID);
+ if ($VotePairs !== FALSE) {
+ if (isset($VotePairs[$GroupID])) {
+ if ($VotePairs[$GroupID]['Total'] == 0) {
+ // Something is screwy
+ $Cache->delete_value('vote_pairs_'.$VGID);
+ continue;
+ }
+ $VotePairs[$GroupID]['Total'] -= 1;
+ if ($Type == 'Up') {
+ $VotePairs[$GroupID]['Ups'] -= 1;
+ }
+ $Cache->cache_value('vote_pairs_'.$VGID, $VotePairs);
+ } else {
+ // Something is screwy, kill the key and move on
+ $Cache->delete_value('vote_pairs_'.$VGID);
+ }
+ }
+ }
+
+ // Let the script know what happened
+ if ($Type == 'Up') {
+ echo 'success-up';
+ } else {
+ echo 'success-down';
+ }
+}
+?>
\ No newline at end of file
diff --git a/sections/artist/artist.php b/sections/artist/artist.php
index 528fdd29..236e61b0 100644
--- a/sections/artist/artist.php
+++ b/sections/artist/artist.php
@@ -61,6 +61,15 @@ function compare($X, $Y){
list($Name, $Image, $Body, $VanityHouseArtist) = $DB->next_record(MYSQLI_NUM, array(0));
}
+$TokenTorrents = $Cache->get_value('users_tokens_'.$UserID);
+if (empty($TokenTorrents)) {
+ $DB->query("SELECT TorrentID FROM users_freeleeches WHERE UserID=$UserID AND Expired=FALSE");
+ $TokenTorrents = $DB->collect('TorrentID');
+ $Cache->cache_value('users_tokens_'.$UserID, $TokenTorrents);
+}
+
+$SnatchedTorrents = Torrents::get_snatched_torrents();
+
//----------------- Build list and get stats
ob_start();
@@ -96,16 +105,14 @@ function compare($X, $Y){
$LastReleaseType = 0;
if(empty($Importances) || empty($TorrentList)) {
$DB->query("SELECT
- DISTINCTROW ta.GroupID, ta.Importance, tg.VanityHouse
+ DISTINCTROW ta.GroupID, ta.Importance, tg.VanityHouse, tg.ReleaseType
FROM torrents_artists AS ta
JOIN torrents_group AS tg ON tg.ID=ta.GroupID
WHERE ta.ArtistID='$ArtistID'
ORDER BY IF(ta.Importance IN ('2', '3', '4', '7'),1000 + ta.Importance, tg.ReleaseType) ASC,
tg.Year DESC, tg.Name DESC");
-
$GroupIDs = $DB->collect('GroupID');
$Importances = $DB->to_array(false, MYSQLI_BOTH, false);
-
if(count($GroupIDs)>0) {
$TorrentList = Torrents::get_groups($GroupIDs, true,true);
$TorrentList = $TorrentList['matches'];
@@ -170,8 +177,19 @@ function compare($X, $Y){
if(!empty($ProducerAlbums)) {
$ReleaseTypes[1021] = "Produced By";
}
-
-
+//Custom sorting for releases
+if(!empty($LoggedUser['SortHide'])) {
+ $SortOrder = array_keys($LoggedUser['SortHide']);
+ uasort($Importances, function ($a, $b) {
+ global $SortOrder;
+ $c = array_search($a['ReleaseType'], $SortOrder);
+ $d = array_search($b['ReleaseType'], $SortOrder);
+ if ($c == $d) {
+ return 0;
+ }
+ return $c < $d ? -1 : 1;
+ });
+}
reset($TorrentList);
if(!empty($UsedReleases)) { ?>
@@ -191,8 +209,8 @@ function compare($X, $Y){
$DisplayName = $ReleaseTypes[$ReleaseID]."s";
break;
}
-
- if (!empty($LoggedUser['DiscogView']) || (isset($LoggedUser['HideTypes']) && in_array($ReleaseID, $LoggedUser['HideTypes']))) {
+
+ if (!empty($LoggedUser['DiscogView']) || (isset($LoggedUser['SortHide']) && array_key_exists($ReleaseType, $LoggedUser['SortHide']) && $LoggedUser['SortHide'][$ReleaseType] == 1)) {
$ToggleStr = " onclick=\"$('.releases_$ReleaseID').show(); return true;\"";
} else {
$ToggleStr = '';
@@ -264,7 +282,12 @@ function compare($X, $Y){
$OldReleaseType = $ReleaseType;
}
- if (!empty($LoggedUser['DiscogView']) || (isset($LoggedUser['HideTypes']) && in_array($ReleaseType, $LoggedUser['HideTypes']))) {
+/* if (!empty($LoggedUser['DiscogView']) || (isset($LoggedUser['HideTypes']) && in_array($ReleaseType, $LoggedUser['HideTypes']))) {
+ $HideDiscog = ' hidden';
+ } else {
+ $HideDiscog = '';
+ } */
+ if (!empty($LoggedUser['DiscogView']) || (isset($LoggedUser['SortHide']) && array_key_exists($ReleaseType, $LoggedUser['SortHide']) && $LoggedUser['SortHide'][$ReleaseType] == 1)) {
$HideDiscog = ' hidden';
} else {
$HideDiscog = '';
@@ -430,8 +453,12 @@ function compare($X, $Y){
&& !$Torrent['PersonalFL'] && empty($Torrent['FreeTorrent']) && ($LoggedUser['CanLeech'] == '1')) { ?>
| FL
} ?> ]
-
- » =Torrents::torrent_info($Torrent)?>
+
+ if(array_key_exists($TorrentID, $SnatchedTorrents)) {
+ $Torrent['SnatchedTorrent'] = '1';
+ }
+?>
+ » =Torrents::torrent_info($Torrent)?>
|
=Format::get_size($Torrent['Size'])?> | =number_format($Torrent['Snatched'])?> | @@ -450,7 +477,7 @@ function compare($X, $Y){ //----------------- End building list and getting stats -View::show_header($Name, 'browse,requests,bbcode'); +View::show_header($Name, 'browse,requests,bbcode,comments'); ?>
+ #=$PostID?> + =Users::format_username($AuthorID, true, true, true, true)?> =time_diff($AddedTime)?> [Report] + if(check_perms('users_warn') && $AuthorID != $LoggedUser['ID']) { + $AuthorInfo = Users::user_info($AuthorID); + if($LoggedUser['Class'] >= $AuthorInfo['Class']) { ?> + + - [Warn] + + } + } ?> + - [Quote] + - [Edit] } +if (check_perms('site_moderate_forums')){ ?> - [Delete] } ?> + + + ↑ + + | +|
+ if ($Avatar) { ?> + + } else { ?> + + + } + ?> + | + +} +?> +
+
+=$Text->full_format($Body)?>
+ if($EditedUserID){ ?>
+
+ + + if(Paranoia::check_perms('site_admin_forums')) { ?> + « + } ?> + Last edited by + =Users::format_username($EditedUserID, false, false, false) ?> =time_diff($EditedTime,2,true,true)?> + } ?> + |
+