· 10 years ago · Sep 11, 2016, 09:50 AM
1<?php
2function getSettings() {
3 $querySettings = "SELECT * from `settings`";
4 return $querySettings;
5}
6function menu($user) {
7 global $TMPL, $LNG, $CONF, $db, $settings;
8
9 $admin_url = ((isset($_SESSION['usernameAdmin']) && isset($_SESSION['passwordAdmin'])) ? '<a href="'.$CONF['url'].'/index.php?a=admin" rel="loadpage"><div class="menu_btn" id="admin_btn" title="'.$LNG['admin_panel'].'"><img src="'.$CONF['url'].'/'.$CONF['theme_url'].'/images/icons/admin.png"></div></a>' : '');
10
11 if($user !== false) {
12 $skin = new skin('shared/menu'); $menu = '';
13
14 $TMPL_old = $TMPL; $TMPL = array();
15
16 $TMPL['realname'] = realName($user['username'], $user['first_name'], $user['last_name']);
17 $TMPL['avatar'] = $user['image'];
18 $TMPL['username'] = $user['username'];
19 $TMPL['url'] = $CONF['url'];
20 $TMPL['theme_url'] = $CONF['theme_url'];
21 $TMPL['intervaln'] = $settings['intervaln'];
22
23 /**
24 * Array Map
25 * array => { url, name, dynamic load, class type}
26 */
27 $links = array( array('profile&u='.$user['username'], realName($user['username'], $user['first_name'], $user['last_name']), 1, 0),
28 array('upload', $LNG['upload'], 1, 1),
29 (proStatus($db, $settings, $user['idu']) ? array('pro', $LNG['go_pro'], 1, 0) : ''),
30 array('stream', $LNG['stream'], 1, 2),
31 array('explore', $LNG['explore'], 1, 2),
32 array('profile&u='.$user['username'].'&r=likes', $LNG['likes'], 1, 0),
33 array('profile&u='.$user['username'].'&r=playlists', $LNG['playlists'], 1, 0),
34 array('stats', $LNG['statistics'], 1, 0),
35 array('settings', $LNG['user_ttl_sidebar'], 1, 0),
36 array('stream&logout=1&token_id='.$_SESSION['token_id'], $LNG['admin_menu_logout'], 0, 0));
37
38 foreach($links as $element => $value) {
39 if($value) {
40 $TMPL['links'] .= $divider.'<a href="'.$CONF['url'].'/index.php?a='.$value[0].'" '.($value[2] ? ' rel="loadpage"' : '').'><div class="menu-dd-row'.(($value[3] == 1) ? ' menu-dd-extra' : '').(($value[3] == 2) ? ' menu-dd-mobile' : '').'">'.$value[1].'</div></a>';
41 $divider = '<div class="menu-divider '.(($value[3] == 2) ? ' menu-dd-mobile' : '').'"></div>';
42 }
43 }
44
45 $TMPL['admin_url'] = $admin_url;
46
47 $menu = $skin->make();
48
49 $TMPL = $TMPL_old; unset($TMPL_old);
50 return $menu;
51 } else {
52 // Else show the LogIn Register button
53 return '<a onclick="connect_modal()" class="menu-btn" title="'.$LNG['connect'].'">'.$LNG['connect'].'</a>'.$admin_url;
54 }
55}
56function menuButtons($user) {
57 global $LNG, $CONF;
58
59 // Buttons list
60 if($user) {
61 $links = array('stream', 'explore');
62 } else {
63 $links = array('explore');
64 }
65
66 foreach($links as $url) {
67 $menu .= '<a href="'.$CONF['url'].'/index.php?a='.$url.'" class="menu-button" rel="loadpage" id="'.$url.'-button">'.$LNG[$url].'</a>';
68 }
69 return $menu;
70}
71function notificationBox($type, $message, $extra = null) {
72 // Extra 1: Add the -modal class name
73 if($extra == 1) {
74 $extra = ' notification-box-modal';
75 }
76 return '<div class="notification-box'.$extra.' notification-box-'.$type.'">
77 <p>'.$message.'</p>
78 <div class="notification-close notification-close-'.$type.'"></div>
79 </div>';
80}
81class register {
82 public $db; // Database Property
83 public $url; // Installation URL Property
84 public $username; // The inserted username
85 public $password; // The inserted password
86 public $first_name; // First name (used for social logins)
87 public $last_name; // Last name (used for social logins)
88 public $email; // The inserted email
89 public $captcha; // The inserted captcha
90 public $captcha_on; // Store the Admin Captcha settings
91 public $email_register; // Store the Admin Email on Register settings
92 public $accounts_per_ip; // Store the Admin settings for Accounts Per IP
93 public $email_like; // The general e-mail like setting [if allowed, it will turn on emails on likes]
94 public $email_comment; // The general e-mail like setting [if allowed, it will turn on emails on comments]
95 public $email_new_friend; // The general e-mail new friend setting [if allowed, it will turn on emails on new friendships]
96 public $fbapp; // Facebook App (0 disabled, 1 enabled)
97 public $fbappid; // Facebook App ID
98 public $fbappsecret; // Facebook App Secret
99
100 function facebook() {
101 if($this->fbapp) {
102 $getToken = $this->getFbToken($this->fbappid, $this->fbappsecret, $this->url.'/requests/connect.php?facebook=true', $this->fbcode);
103 $user = $this->parseFbInfo($getToken['access_token']);
104
105 if($getToken == null || $_SESSION['state'] == null || ($_SESSION['state'] != $this->fbstate) || empty($user->email)) {
106 header("Location: ".$this->url);
107 }
108 if(!empty($user->email)) {
109 $this->email = $user->email;
110
111 $this->first_name = $user->first_name;
112 $this->last_name = $user->last_name;
113 $checkEmail = $this->verify_if_email_exists(1);
114
115 // If user already exist
116 if($checkEmail) {
117 // Set sessions and log-in
118 $_SESSION['username'] = $checkEmail['username'];
119 $_SESSION['password'] = $checkEmail['password'];
120
121 // Redirect user
122 header("Location: ".$this->url);
123 } else {
124 $this->profile_image = $this->parseFbPicture($getToken['access_token']);
125 $this->generateUsername();
126 $this->password = $this->generatePassword(8);
127 $this->query();
128
129 $_SESSION['username'] = $this->username;
130 $_SESSION['password'] = md5($this->password);
131
132 return 1;
133 }
134 }
135 }
136 }
137
138 function generateUsername($type = null) {
139 // If type is set, generate a random username
140 if($type) {
141 $this->username = $this->parseUsername().rand(0, 999);
142 } else {
143 $this->username = $this->parseUsername();
144 }
145
146 // Replace the '.' sign with '_' (allows @user_mention)
147 $this->username = str_replace('.', '_', $this->username);
148
149 // Check if the username exists
150 $checkUser = $this->verify_if_user_exist();
151
152 if($checkUser) {
153 $this->generateUsername(1);
154 }
155 }
156
157 function parseUsername() {
158 if(ctype_alnum($this->first_name) && ctype_alnum($this->last_name)) {
159 return $this->username = $this->first_name.'.'.$this->last_name;
160 } elseif(ctype_alnum($this->first_name)) {
161 return $this->first_name;
162 } elseif(ctype_alnum($this->last_name)) {
163 return $this->last_name;
164 } else {
165 // Parse email address
166 $email = explode('@', $this->email);
167 $email = preg_replace("/[^a-z0-9]+/i", "", $email[0]);
168 if(ctype_alnum($email)) {
169 return $email;
170 } else {
171 return rand(0, 9999);
172 }
173 }
174 }
175
176 function generatePassword($length) {
177 // Allowed characters
178 $chars = str_split("abcdefghijklmnopqrstuvwxyz0123456789");
179
180 // Generate password
181 for($i = 1; $i <= $length; $i++) {
182 // Get a random character
183 $n = array_rand($chars, 1);
184
185 // Store random char
186 $password .= $chars[$n];
187 }
188 return $password;
189 }
190
191 function getFbToken($app_id, $app_secret, $redirect_url, $code) {
192 // Build the token URL
193 $url = 'https://graph.facebook.com/oauth/access_token?client_id='.$app_id.'&redirect_uri='.urlencode($redirect_url).'&client_secret='.$app_secret.'&code='.$code;
194
195 // Get the file
196 $response = fetch($url);
197
198 // Parse the response
199 parse_str($response, $params);
200
201 // Return parameters
202 return $params;
203 }
204
205 function parseFbInfo($access_token) {
206 // Build the Graph URL
207 $url = "https://graph.facebook.com/me?fields=id,email,first_name,gender,last_name,link,locale,name,timezone,updated_time,verified&access_token=".$access_token;
208
209 // Get the file
210 $user = json_decode(fetch($url));
211
212 // Return user
213 if($user != null && isset($user->name)) {
214 return $user;
215 }
216 return null;
217 }
218
219 function parseFbPicture($access_token) {
220 // Build the Graph URL
221 $url = "https://graph.facebook.com/me/picture?width=500&height=500&access_token=".$access_token;
222
223 // Get the image
224 $image = fetch($url);
225
226 // Generate the file name
227 $file_name = mt_rand().'_'.mt_rand().'_'.mt_rand().'.jpg';
228 $file_path = __DIR__ .'/../uploads/avatars/';
229
230 // Create the file
231 $fp = fopen($file_path.$file_name, 'wb');
232
233 // If the file can't be written
234 if(!file_exists($file_path.$file_name)) {
235 // Return the file name
236 return false;
237 }
238
239 // Write the image
240 fwrite($fp, $image);
241
242 // Close
243 fclose($fp);
244
245 // Return the filename
246 return $file_name;
247 }
248
249 function process() {
250 global $LNG;
251
252 $arr = $this->validate_values(); // Must be stored in a variable before executing an empty condition
253 if(empty($arr)) { // If there is no error message then execute the query;
254 $this->query();
255
256 // Set a session and log-in the user
257 $_SESSION['username'] = $this->username;
258 $_SESSION['password'] = md5($this->password);
259
260 // Return (int) 1 if everything was validated
261 return 1;
262
263 // return $LNG['user_success'];
264 } else { // If there is an error message
265 foreach($arr as $err) {
266 return notificationBox('error', $LNG["$err"], 1); // Return the error value for translation file
267 }
268 }
269 }
270
271 function verify_if_user_exist() {
272 $query = sprintf("SELECT `username` FROM `users` WHERE `username` = '%s'", $this->db->real_escape_string(strtolower($this->username)));
273 $result = $this->db->query($query);
274
275 return ($result->num_rows == 0) ? 0 : 1;
276 }
277
278 function verify_accounts_per_ip() {
279 if($this->accounts_per_ip) {
280 $query = $this->db->query(sprintf("SELECT COUNT(`ip`) FROM `users` WHERE `ip` = '%s'", $this->db->real_escape_string(getUserIP())));
281
282 $result = $query->fetch_row();
283 if($result[0] < $this->accounts_per_ip) {
284 return true;
285 } else {
286 return false;
287 }
288 } else {
289 return true;
290 }
291 }
292
293 function verify_if_email_exists($type = null) {
294 // Type 0: Normal check
295 // Type 1: Facebook check & return type
296 if($type) {
297 $query = sprintf("SELECT `username`, `password` FROM `users` WHERE `email` = '%s'", $this->db->real_escape_string(strtolower($this->email)));
298 } else {
299 $query = sprintf("SELECT `email` FROM `users` WHERE `email` = '%s'", $this->db->real_escape_string(strtolower($this->email)));
300 }
301 $result = $this->db->query($query);
302
303 if($type) {
304 return ($result->num_rows == 0) ? 0 : $result->fetch_assoc();
305 } else {
306 return ($result->num_rows == 0) ? 0 : 1;
307 }
308 }
309
310 function verify_captcha() {
311 if($this->captcha_on) {
312 if($this->captcha == "{$_SESSION['captcha']}" && !empty($this->captcha)) {
313 return true;
314 } else {
315 return false;
316 }
317 } else {
318 return true;
319 }
320 }
321
322 function validate_values() {
323 // Create the array which contains the Language variable
324 $error = array();
325
326 // Define the Language variable for each type of error
327 if($this->verify_accounts_per_ip() == false) {
328 $error[] = 'user_limit';
329 }
330 if($this->verify_if_user_exist() !== 0) {
331 $error[] = 'user_exists';
332 }
333 if($this->verify_if_email_exists() !== 0) {
334 $error[] = 'email_exists';
335 }
336 if(empty($this->username) && empty($this->password) && empty($email)) {
337 $error[] = 'all_fields';
338 }
339 if(strlen($this->password) < 6) {
340 $error[] = 'password_too_short';
341 }
342 if(!ctype_alnum($this->username)) {
343 $error[] = 'user_alnum';
344 }
345 if(strlen($this->username) <= 2 || strlen($this->username) >= 33) {
346 $error[] = 'user_too_short';
347 }
348 if(!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
349 $error[] = 'invalid_email';
350 }
351 if($this->verify_captcha() == false) {
352 $error[] = 'invalid_captcha';
353 }
354
355 return $error;
356 }
357
358 function query() {
359 $query = sprintf("INSERT into `users` (`username`, `password`, `first_name`, `last_name`, `email`, `date`, `image`, `cover`, `online`, `ip`, `notificationl`, `notificationc`, `notificationd`, `notificationf`, `email_comment`, `email_like`, `email_new_friend`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', 'default.png', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s');", $this->db->real_escape_string(strtolower($this->username)), md5($this->db->real_escape_string($this->password)), $this->db->real_escape_string($this->first_name), $this->db->real_escape_string($this->last_name), $this->db->real_escape_string($this->email), date("Y-m-d H:i:s"), ($this->profile_image ? $this->profile_image : 'default.png'), time(), $this->db->real_escape_string(getUserIp()), 1, 1, 1, 1, $this->email_comment, $this->email_like, $this->email_new_friend);
360 $this->db->query($query);
361 }
362}
363
364class logIn {
365 public $db; // Database Property
366 public $url; // Installation URL Property
367 public $username; // Username Property
368 public $password; // Password Property
369 public $remember; // Option to remember the usr / pwd (_COOKIE) Property
370
371 function in() {
372 global $LNG;
373
374 // If an user is found
375 if($this->queryLogIn() == 1) {
376 // Regenerate the SID
377 session_regenerate_id();
378
379 if($this->remember == 1) { // If checkbox, then set cookie
380 setcookie("username", $this->username, time() + 30 * 24 * 60 * 60, '/'); // Expire in one month
381 setcookie("password", md5($this->password), time() + 30 * 24 * 60 * 60, '/'); // Expire in one month
382 } else { // Else set session
383 $_SESSION['username'] = $this->username;
384 $_SESSION['password'] = md5($this->password);
385 }
386
387 // Return logged in state
388 return 1;
389 } else {
390 // If wrong credentials are entered, unset everything
391 $this->logOut();
392
393 return notificationBox('error', $LNG['invalid_user_pw'], 1);
394 }
395 }
396
397 function queryLogIn() {
398 // If the username input string is an e-mail, switch the query
399 if(filter_var($this->db->real_escape_string($this->username), FILTER_VALIDATE_EMAIL)) {
400 $query = sprintf("SELECT * FROM `users` WHERE `email` = '%s' AND `password` = '%s' AND `suspended` = 0", $this->db->real_escape_string($this->username), md5($this->db->real_escape_string($this->password)));
401 } else {
402 $query = sprintf("SELECT * FROM `users` WHERE `username` = '%s' AND `password` = '%s' AND `suspended` = 0", $this->db->real_escape_string($this->username), md5($this->db->real_escape_string($this->password)));
403 }
404 $result = $this->db->query($query);
405
406 return ($result->num_rows == 0) ? 0 : 1;
407 }
408
409 function logOut() {
410 unset($_SESSION['username']);
411 unset($_SESSION['password']);
412 setcookie("username", '', 1, '/');
413 setcookie("password", '', 1, '/');
414 }
415}
416
417class loggedIn {
418 public $db; // Database Property
419 public $url; // Installation URL Property
420 public $username; // Username Property
421 public $password; // Password Property
422
423 function verify() {
424 // Set the query result into $query variable;
425 $query = $this->query();
426
427 if(!is_int($query)) {
428 // If the $query variable is not 0 (int)
429 // Fetch associative array into $result variable
430 $result = $query->fetch_assoc();
431 return $result;
432 }
433 }
434
435 function query() {
436 // If the username input string is an e-mail, switch the query
437 if(filter_var($this->db->real_escape_string($this->username), FILTER_VALIDATE_EMAIL)) {
438 $query = sprintf("SELECT * FROM `users` WHERE `email` = '%s' AND `password` = '%s' AND `suspended` = 0", $this->db->real_escape_string($this->username), $this->db->real_escape_string($this->password));
439 } else {
440 $query = sprintf("SELECT * FROM `users` WHERE `username` = '%s' AND `password` = '%s' AND `suspended` = 0", $this->db->real_escape_string($this->username), $this->db->real_escape_string($this->password));
441 }
442 $result = $this->db->query($query);
443 return ($result->num_rows == 0) ? 0 : $result;
444 }
445
446 function logOut() {
447 unset($_SESSION['username']);
448 unset($_SESSION['password']);
449 setcookie("username", '', 1, '/');
450 setcookie("password", '', 1, '/');
451 }
452}
453
454class logInAdmin {
455 public $db; // Database Property
456 public $url; // Installation URL Property
457 public $username; // Username Property
458 public $password; // Password Property
459
460 function in() {
461 global $LNG;
462
463 // If an user is found
464 if($this->queryLogIn() == 1) {
465 // Regenerate the SID
466 session_regenerate_id();
467
468 // Set session
469 $_SESSION['usernameAdmin'] = $this->username;
470 $_SESSION['passwordAdmin'] = md5($this->password);
471
472 // Redirect the user to his personal profile
473 // header("Location: ".$this->url."/index.php?a=feed");
474 } else {
475 // If wrong credentials are entered, unset everything
476 $this->logOut();
477
478 return notificationBox('error', $LNG['invalid_user_pw']);
479 }
480 }
481
482 function queryLogIn() {
483 $query = sprintf("SELECT * FROM `admin` WHERE `username` = '%s' AND `password` = '%s'", $this->db->real_escape_string($this->username), md5($this->db->real_escape_string($this->password)));
484 $result = $this->db->query($query);
485
486 return ($result->num_rows == 0) ? 0 : 1;
487 }
488
489 function logOut() {
490 unset($_SESSION['usernameAdmin']);
491 unset($_SESSION['passwordAdmin']);
492 }
493}
494
495class loggedInAdmin {
496 public $db; // Database Property
497 public $url; // Installation URL Property
498 public $username; // Username Property
499 public $password; // Password Property
500
501 function verify() {
502 // Set the query result into $query variable;
503 $query = $this->query();
504 if(!is_int($query)) {
505 // If the $query variable is not 0 (int)
506 // Fetch associative array into $result variable
507 $result = $query->fetch_assoc();
508 return $result;
509 }
510 }
511
512 function query() {
513 $query = sprintf("SELECT * FROM `admin` WHERE `username` = '%s' AND `password` = '%s'", $this->db->real_escape_string($this->username), $this->db->real_escape_string($this->password));
514
515 $result = $this->db->query($query);
516 return ($result->num_rows == 0) ? 0 : $result;
517 }
518
519 function logOut() {
520 unset($_SESSION['usernameAdmin']);
521 unset($_SESSION['passwordAdmin']);
522 }
523}
524
525class updateSettings {
526 public $db; // Database Property
527 public $url; // Installation URL Property
528
529 function validate_password($password) {
530 $query = $this->db->query(sprintf("SELECT `password` FROM `admin` WHERE `username` = '%s' AND `password` = '%s'", $this->db->real_escape_string($_SESSION['usernameAdmin']), $this->db->real_escape_string(md5($password))));
531 return $query->num_rows ? 1 : 0;
532 }
533
534 function query_array($table, $data) {
535 // Verify if the user has a valid token
536 if($data['token_id'] == $_SESSION['token_id']) {
537 unset($data['token_id']);
538 // Get the columns of the query-ed table
539 $available = $this->getColumns($table);
540
541 if($table == 'admin') {
542 if(isset($data['password']) && !isset($data['current_password']) || isset($data['current_password']) && !$this->validate_password($data['current_password'])) {
543 return 2;
544 }
545
546 if(isset($data['password']) && strlen($data['password']) < 6) {
547 return 4;
548 }
549
550 if(isset($data['password']) && $data['password'] !== $data['repeat_password']) {
551 return 3;
552 }
553
554 unset($data['repeat_password'], $data['current_password']);
555 }
556
557 foreach ($data as $key => $value) {
558 // Check if all arrays introduced are available table fields
559 if(!array_key_exists($key, $available)) {
560 $x = 1;
561 return 0;
562 }
563 }
564
565 // If all array keys are valid database columns
566 if($x !== 1) {
567 foreach ($data as $column => $value) {
568 $columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value));
569 }
570 $column_list = implode(',', $columns);
571
572 // Prepare the database for specific page
573 if($table == 'admin') {
574 // Prepare the statement
575 $stmt = $this->db->prepare("UPDATE `$table` SET `password` = md5('{$data['password']}') WHERE `username` = '{$_SESSION['usernameAdmin']}'");
576 $_SESSION['passwordAdmin'] = md5($data['password']);
577 } else {
578 // Prepare the statement
579 $stmt = $this->db->prepare("UPDATE `$table` SET $column_list");
580 }
581 // Execute the statement
582 $stmt->execute();
583
584 // Save the affected rows
585 $affected = $stmt->affected_rows;
586
587 // Close the statement
588 $stmt->close();
589
590 // If there was anything affected return 1
591 return ($affected) ? 1 : 0;
592 }
593 } else {
594 return 0;
595 }
596 }
597
598 function getColumns($table) {
599 if($table == 'admin') {
600 $query = $this->db->query("SHOW columns FROM `$table` WHERE Field NOT IN ('id', 'username')");
601 } else {
602 $query = $this->db->query("SHOW columns FROM `$table`");
603 }
604 // Define an array to store the results
605 $columns = array();
606
607 // Fetch the results set
608 while ($row = $query->fetch_array()) {
609 // Store the result into array
610 $columns[] = $row[0];
611 }
612
613 // Return the array;
614 return array_flip($columns);
615 }
616
617 function getThemes() {
618 global $CONF, $LNG;
619 if($handle = opendir('./'.$CONF['theme_path'].'/')) {
620
621 $allowedThemes = array();
622 // This is the correct way to loop over the directory.
623 while(false !== ($theme = readdir($handle))) {
624 // Exclude ., .., and check whether the info.php file of the theme exist
625 if($theme != '.' && $theme != '..' && file_exists('./'.$CONF['theme_path'].'/'.$theme.'/info.php')) {
626 $allowedThemes[] = $theme;
627 include('./'.$CONF['theme_path'].'/'.$theme.'/info.php');
628
629 if($CONF['theme_name'] == $theme) {
630 $state = '<div class="modal-btn modal-btn-active list-button"><a>'.$LNG['theme_active'].'</a></div>';
631 } else {
632 $state = '<div class="modal-btn list-button"><a href="'.$CONF['url'].'/index.php?a=admin&b=themes&theme='.$theme.'&token_id='.$_SESSION['token_id'].'">'.$LNG['theme_activate'].'</a></div>';
633 }
634
635 if(file_exists('./'.$CONF['theme_path'].'/'.$theme.'/icon.png')) {
636 $image = '<img src="'.$CONF['url'].'/'.$CONF['theme_path'].'/'.$theme.'/icon.png" />';
637 } else {
638 $image = '';
639 }
640
641 $output .= '
642 <div class="manage-users-container">
643 <div class="manage-users-image"><a href="'.$url.'" target="_blank" title="'.$LNG['theme_author_homepage'].'">'.$image.'</a></div>
644 <div class="manage-users-content"><strong><a href="'.$url.'" target="_blank" title="'.$LNG['theme_author_homepage'].'">'.$name.'</a></strong> '.$version.'<br />'.$LNG['by'].': <a href="'.$url.'" target="_blank" title="'.$LNG['theme_author_homepage'].'">'.$author.'</a></div>
645 <div class="manage-users-buttons">
646 '.$state.'
647 </div>
648 </div>';
649 }
650 }
651
652 closedir($handle);
653 return array($output, $allowedThemes);
654 }
655 }
656}
657
658class updateUserSettings {
659 public $db; // Database Property
660 public $url; // Installation URL Property
661 public $id; // Logged in user id
662
663 function validate_password($password) {
664 $query = $this->db->query(sprintf("SELECT `password` FROM `users` WHERE `idu` = '%s' AND `password` = '%s'", $this->id, $this->db->real_escape_string(md5($password))));
665 return $query->num_rows ? 1 : 0;
666 }
667
668 function validate_inputs($data) {
669 if(isset($data['password']) && !isset($data['current_password']) || isset($data['current_password']) && !$this->validate_password($data['current_password'])) {
670 return array('wrong_current_password');
671 }
672
673 if(isset($data['email']) && !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
674 return array('valid_email');
675 }
676
677 if(!countries(0, $data['country'])) {
678 return array('valid_country');
679 }
680
681 if(!filter_var($data['website'], FILTER_VALIDATE_URL) && !empty($data['website'])) {
682 return array('valid_url');
683 }
684
685 if(isset($data['email']) && $this->verify_if_email_exists($this->id, $data['email'])) {
686 return array('email_exists');
687 }
688
689 if(strlen($data['description']) > 160) {
690 return array('profile_description', 160);
691 }
692
693 if(isset($data['password']) && strlen($data['password']) < 6) {
694 return array('password_too_short');
695 }
696
697 if(isset($data['password']) && $data['password'] !== $data['repeat_password']) {
698 return array('password_not_match');
699 }
700 }
701
702 function query_array($table, $data) {
703 global $LNG;
704 // Verify if the user has a valid token
705 if($data['token_id'] == $_SESSION['token_id']) {
706 // Validate the inputs
707 $validate = $this->validate_inputs($data);
708
709 if($validate) {
710 return notificationBox('error', sprintf($LNG["{$validate[0]}"], $validate[1]));
711 }
712
713 // Unset unused values
714 unset($data['repeat_password'], $data['current_password'], $data['token_id']);
715
716 // Clean the description
717 if(isset($data['description'])) {
718 $data['description'] = htmlspecialchars(trim(nl2clean($data['description'])));
719 }
720
721 // Get the columns of the query-ed table
722 $available = $this->getColumns($table);
723
724 foreach ($data as $key => $value) {
725 // Check if password array key exist and set a variable if so
726 if($key == 'password') {
727 $password = true;
728 }
729
730 // Check if all arrays introduced are available table fields
731 if(!array_key_exists($key, $available)) {
732 $x = 1;
733 break;
734 }
735 }
736
737 // If the password array key exists, encrypt the password
738 if($password) {
739 $data['password'] = md5($data['password']);
740 }
741
742 // If all array keys are valid database columns
743 if($x !== 1) {
744 foreach ($data as $column => $value) {
745 $columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value));
746 }
747 $column_list = implode(',', $columns);
748
749 // Prepare the statement
750 $stmt = $this->db->prepare("UPDATE `$table` SET $column_list WHERE `idu` = '{$this->id}'");
751
752 // Execute the statement
753 $stmt->execute();
754
755 // Save the affected rows
756 $affected = $stmt->affected_rows;
757
758 // Close the statement
759 $stmt->close();
760
761 // If the SQL was executed, and the password field was set, save the new password
762 if($affected && $password) {
763 if(isset($_COOKIE['password'])) {
764 setcookie("password", $data['password'], time() + 30 * 24 * 60 * 60); // Expire in one month
765 } else {
766 $_SESSION['password'] = $data['password'];
767 }
768 }
769
770 // If there was anything affected return 1
771 if($affected) {
772 return notificationBox('success', $LNG['settings_saved']);
773 } else {
774 return notificationBox('info', $LNG['nothing_changed']);
775 }
776 }
777 } else {
778 return notificationBox('info', $LNG['nothing_changed']);
779 }
780 }
781
782 function getColumns($table) {
783
784 $query = $this->db->query("SHOW columns FROM `$table` WHERE Field NOT IN ('idu', 'username', 'date', 'salted')");
785
786 // Define an array to store the results
787 $columns = array();
788
789 // Fetch the results set
790 while ($row = $query->fetch_array()) {
791 // Store the result into array
792 $columns[] = $row[0];
793 }
794
795 // Return the array;
796 return array_flip($columns);
797 }
798
799 function deleteAvatar($image) {
800 // Prepare the statement
801 $stmt = $this->db->prepare("UPDATE `users` SET `image` = 'default.png' WHERE `idu` = '{$this->id}'");
802
803 // Execute the statement
804 $stmt->execute();
805
806 // Save the affected rows
807 $affected = $stmt->affected_rows;
808
809 // Close the statement
810 $stmt->close();
811
812 // If the change was made, then unlink the old image
813 if($affected) {
814 unlink('uploads/avatars/'.$image);
815 }
816
817 // If there was anything affected return 1
818 return ($affected) ? 1 : 0;
819 }
820
821 function verify_if_email_exists($id, $email) {
822 $query = sprintf("SELECT `idu`, `email` FROM `users` WHERE `idu` != '%s' AND `email` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string(strtolower($email)));
823 $result = $this->db->query($query);
824
825 return ($result->num_rows == 0) ? 0 : 1;
826 }
827
828 function getSettings() {
829 $result = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` = '%s'", $this->db->real_escape_string($this->id)));
830
831 return $result->fetch_assoc();
832 }
833
834 function getBlockedUsers() {
835 global $LNG;
836 $result = $this->db->query(sprintf("SELECT * FROM `blocked`, `users` WHERE `blocked`.`by` = '%s' AND `blocked`.`uid` = `users`.`idu` ORDER BY `id` DESC", $this->db->real_escape_string($this->id)));
837
838 while($row = $result->fetch_assoc()) {
839 $output .= '
840 <div class="manage-users-container" id="blocked'.$row['idu'].'">
841 <div class="manage-users-image">
842 <a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50"></a>
843 </div>
844 <div class="manage-users-content"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">'.$row['username'].'</a><br>'.realName(null, $row['first_name'], $row['last_name']).''.((location($row['country'], $row['city']) && $row['private'] == 0) ? ' ('.location($row['country'], $row['city']).')' : ' ').'</div>
845 <div class="manage-users-buttons">
846 <div class="modal-btn list-button"><a onclick="doBlock('.$row['idu'].', 1)">'.$LNG['unblock'].'</a></div>
847 </div>
848 </div>';
849 }
850 return $output;
851 }
852}
853class recover {
854 public $db; // Database Property
855 public $url; // Installation URL Property
856 public $username; // The username to recover
857
858 function checkUser() {
859 // Query the database and check if the username exists
860 if(filter_var($this->db->real_escape_string($this->username), FILTER_VALIDATE_EMAIL)) {
861 $query = sprintf("SELECT `username`,`email` FROM `users` WHERE `email` = '%s'", $this->db->real_escape_string(strtolower($this->username)));
862 } else {
863 $query = sprintf("SELECT `username`,`email` FROM `users` WHERE `username` = '%s'", $this->db->real_escape_string(strtolower($this->username)));
864 }
865
866 $result = $this->db->query($query);
867
868 // If a valid username is found
869 if ($result->num_rows > 0) {
870 // Fetch Associative values
871 $assoc = $result->fetch_assoc();
872
873 // Generate the salt for that username
874 $generateSalt = $this->generateSalt($assoc['username']);
875
876 // If the salt was generated
877 if($generateSalt) {
878
879 // Return the username, email and salted code
880 return array($assoc['username'], $assoc['email'], $generateSalt);
881 }
882 }
883 }
884
885 function generateSalt($username) {
886 // Generate the salted code
887 $salt = md5(mt_rand());
888
889 // Prepare to update the database with the salted code
890 $stmt = $this->db->prepare("UPDATE `users` SET `salted` = '{$this->db->real_escape_string($salt)}' WHERE `username` = '{$this->db->real_escape_string(strtolower($username))}'");
891
892 // Execute the statement
893 $stmt->execute();
894
895 // Save the affected rows
896 $affected = $stmt->affected_rows;
897
898 // Close the query
899 $stmt->close();
900
901 // If there was anything affected return 1
902 if($affected)
903 return $salt;
904 else
905 return false;
906 }
907
908 function changePassword($username, $password, $salt) {
909 // Query the database and check if the username and the salted code exists
910 $query = sprintf("SELECT `username` FROM `users` WHERE `username` = '%s' AND `salted` = '%s'", $this->db->real_escape_string(strtolower($username)), $this->db->real_escape_string($salt));
911 $result = $this->db->query($query);
912
913 // If a valid match was found
914 if ($result->num_rows > 0) {
915
916 // Change the password
917 $stmt = $this->db->prepare("UPDATE `users` SET `password` = md5('{$password}'), `salted` = '' WHERE `username` = '{$this->db->real_escape_string(strtolower($username))}'");
918
919 // Execute the statement
920 $stmt->execute();
921
922 // Save the affected rows
923 $affected = $stmt->affected_rows;
924
925 // Close the query
926 $stmt->close();
927 if($affected) {
928 return true;
929 } else {
930 return false;
931 }
932 }
933 }
934}
935class manageUsers {
936 public $db; // Database Property
937 public $url; // Installation URL Property
938 public $title; // Installation WebSite Title
939 public $per_page; // Limit per page
940
941 function getUsers($start) {
942 global $LNG;
943 // If the $start value is 0, empty the query;
944 if($start == 0) {
945 $start = '';
946 } else {
947 // Else, build up the query
948 $start = 'WHERE `idu` < \''.$this->db->real_escape_string($start).'\'';
949 }
950 // Query the database and get the latest 20 users
951 // If load more is true, switch the query for the live query
952
953 $query = sprintf("SELECT * FROM `users` %s ORDER BY `idu` DESC LIMIT %s", $start, $this->db->real_escape_string($this->per_page + 1));
954
955 $result = $this->db->query($query);
956 while($row = $result->fetch_assoc()) {
957 $rows[] = $row;
958 }
959
960 if(array_key_exists($this->per_page, $rows)) {
961 $loadmore = 1;
962
963 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
964 array_pop($rows);
965 }
966
967 $output = ''; // Define the rows variable
968
969 foreach($rows as $row) {
970 $output .= '
971 <div class="manage-users-container" id="user'.$row['idu'].'">
972 <div class="manage-users-image"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50" /></a></div>
973 <div class="manage-users-content"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank">'.$row['username'].'</a><br />'.$row['email'].'</div>
974 <div class="manage-users-buttons">
975 <div class="modal-btn list-button"><a href="'.$this->url.'/index.php?a=admin&b=users&id='.$row['idu'].'" rel="loadpage">'.$LNG['edit'].'</a></div>
976 </div>
977 </div>';
978 $last = $row['idu'];
979 }
980 if($loadmore) {
981 $output .= '<div class="admin-load-more"><div id="more_users">
982 <div class="load_more"><a onclick="manage_the('.$last.', 0)" id="infinite-load">'.$LNG['load_more'].'</a></div>
983 </div></div>';
984 }
985
986 // Return the array set
987 return $output;
988 }
989
990 function getUser($id, $profile = null) {
991 if($profile) {
992 $query = sprintf("SELECT `idu`, `username`, `email`, `first_name`, `last_name`, `image`, `country`, `city`, `website`, `description`, `facebook`, `twitter`, `gplus`, `youtube`, `vimeo`, `tumblr`, `soundcloud`, `myspace`, `lastfm`, `suspended`, `ip` FROM `users` WHERE `username` = '%s'", $this->db->real_escape_string($profile));
993 } else {
994 $query = sprintf("SELECT `idu`, `username`, `email`, `first_name`, `last_name`, `image`, `country`, `city`, `website`, `description`, `facebook`, `twitter`, `gplus`, `youtube`, `vimeo`, `tumblr`, `soundcloud`, `myspace`, `lastfm`, `suspended`, `ip` FROM `users` WHERE `idu` = '%s'", $this->db->real_escape_string($id));
995 }
996 $result = $this->db->query($query);
997
998 // If the user exists
999 if($result->num_rows > 0) {
1000
1001 $row = $result->fetch_assoc();
1002
1003 return $row;
1004 } else {
1005 return false;
1006 }
1007 }
1008
1009 function suspendUser($id, $type) {
1010 // Type 0: Restore
1011 // Type 1: Suspend
1012 $user = $this->getUser($id);
1013
1014 if($type && $user['suspended'] == 0) {
1015 $stmt = $this->db->prepare(sprintf("UPDATE `users` SET `suspended` = 1, `private` = 1 WHERE `idu` = '%s'", $this->db->real_escape_string($id)));
1016 } else {
1017 $stmt = $this->db->prepare(sprintf("UPDATE `users` SET `suspended` = 0, `private` = 1 WHERE `idu` = '%s'", $this->db->real_escape_string($id)));
1018 }
1019 $stmt->execute();
1020
1021 $affected = $stmt->affected_rows;
1022
1023 $stmt->close();
1024
1025 if($affected) {
1026 if($type) {
1027 global $LNG;
1028 // Send suspended account email
1029 sendMail($user['email'], sprintf($LNG['ttl_suspended_account_mail']), sprintf($LNG['suspended_account_mail'], realName($user['username'], $user['first_name'], $user['last_name']), $this->url, $this->title), $this->email);
1030 }
1031 }
1032 }
1033
1034 function deleteUser($id) {
1035 // Prepare the statement to delete the user from the database
1036 $stmt = $this->db->prepare("DELETE FROM `users` WHERE `idu` = '{$this->db->real_escape_string($id)}'");
1037
1038 // Execute the statement
1039 $stmt->execute();
1040
1041 // Save the affected rows
1042 $affected = $stmt->affected_rows;
1043
1044 // Close the statement
1045 $stmt->close();
1046
1047 // If the user was returned
1048 if($affected) {
1049 $this->db->query(sprintf("UPDATE `tracks` SET `likes` = `likes`-1, `time` = `time` WHERE `id` IN (SELECT `track` FROM `likes` WHERE `by` = '%s' ORDER BY `track` ASC)", $this->db->real_escape_string($id)));
1050 $this->db->query("DELETE FROM `playlistentries` WHERE `track` IN (SELECT `id` FROM `tracks` WHERE `uid` = '{$this->db->real_escape_string($id)}')");
1051 $this->db->query("DELETE FROM `playlistentries` WHERE `playlist` IN (SELECT `id` FROM `playlists` WHERE `by` = '{$this->db->real_escape_string($id)}')");
1052 $this->db->query("DELETE FROM `tracks` WHERE `uid` = '{$this->db->real_escape_string($id)}'");
1053 $this->db->query("DELETE FROM `comments` WHERE `uid` = '{$this->db->real_escape_string($id)}'");
1054 $this->db->query("DELETE FROM `likes` WHERE `by` = '{$this->db->real_escape_string($id)}'");
1055 $this->db->query("DELETE FROM `views` WHERE `by` = '{$this->db->real_escape_string($id)}'");
1056 $this->db->query("DELETE FROM `reports` WHERE `by` = '{$this->db->real_escape_string($id)}'");
1057 $this->db->query("DELETE FROM `relations` WHERE `subscriber` = '{$this->db->real_escape_string($id)}'");
1058 $this->db->query("DELETE FROM `relations` WHERE `leader` = '{$this->db->real_escape_string($id)}'");
1059 $this->db->query("DELETE FROM `chat` WHERE `from` = '{$this->db->real_escape_string($id)}'");
1060 $this->db->query("DELETE FROM `chat` WHERE `to` = '{$this->db->real_escape_string($id)}'");
1061 $this->db->query("DELETE FROM `blocked` WHERE `uid` = '{$this->db->real_escape_string($id)}'");
1062 $this->db->query("DELETE FROM `blocked` WHERE `by` = '{$this->db->real_escape_string($id)}'");
1063 $this->db->query("DELETE FROM `notifications` WHERE `to` = '{$this->db->real_escape_string($id)}'");
1064 $this->db->query("DELETE FROM `notifications` WHERE `from` = '{$this->db->real_escape_string($id)}'");
1065 $this->db->query("DELETE FROM `playlists` WHERE `by` = '{$this->db->real_escape_string($id)}'");
1066 return 1;
1067 } else {
1068 return 0;
1069 }
1070 }
1071
1072}
1073class manageCategories {
1074 public $db; // Database Property
1075 public $url; // Installation URL Property
1076
1077 function getCategories($type = null) {
1078 global $LNG;
1079 // Type 0: Return all categories
1080 // Type 1: Return the last category added
1081 if($type) {
1082 $query = sprintf("SELECT * FROM `categories` ORDER BY `id` DESC LIMIT 0, 1");
1083 } else {
1084 $query = sprintf("SELECT * FROM `categories` ORDER BY `name` ASC");
1085 }
1086 $result = $this->db->query($query);
1087
1088 while($row = $result->fetch_assoc()) {
1089 $rows[] = $row;
1090 }
1091
1092 foreach($rows as $row) {
1093 $output .= '
1094 <div class="manage-users-container" id="category'.$row['id'].'">
1095 <div class="manage-list-name"><a href="'.$this->url.'/index.php?a=explore&filter='.$row['name'].'" target="_blank">'.$row['name'].'</a></div>
1096 <div class="manage-users-buttons manage-list-buttons">
1097 <div class="modal-btn list-button"><a onclick="manage_categories('.$row['id'].', 0)" title="'.$LNG['delete'].'">'.$LNG['delete'].'</a></div>
1098 </div>
1099 </div>';
1100 }
1101
1102 return $output;
1103 }
1104
1105 function addCategory($value) {
1106 $value = preg_replace(array('/[^[:alnum:]-]/u', '/--+/'), array('', '-'), $value);
1107
1108 $stmt = $this->db->prepare(sprintf("INSERT INTO `categories` (`name`) VALUES ('%s')", $this->db->real_escape_string($value)));
1109
1110 // Execute the statement
1111 $stmt->execute();
1112
1113 // Save the affected rows
1114 $affected = $stmt->affected_rows;
1115
1116 // Close the statement
1117 $stmt->close();
1118
1119 // If category was added return the latest category
1120 if($affected) {
1121 return $this->getCategories(1);
1122 }
1123 }
1124
1125 function deleteCategory($id) {
1126 $stmt = $this->db->prepare(sprintf("DELETE FROM `categories` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
1127
1128 // Execute the statement
1129 $stmt->execute();
1130
1131 // Save the affected rows
1132 $affected = $stmt->affected_rows;
1133
1134 // Close the statement
1135 $stmt->close();
1136
1137 // If category was deleted
1138 return ($affected) ? 1 : 0;
1139 }
1140}
1141class managePayments {
1142 public $db; // Database Property
1143 public $url; // Installation URL Property
1144 public $title; // Installation WebSite Title
1145 public $per_page; // Limit per page
1146
1147 function validatePayment($id) {
1148 // If the ID is the txn_id
1149 if(!ctype_digit($id)) {
1150 $field = 'txn_id';
1151 } else {
1152 $field = 'id';
1153 }
1154
1155 // Select the report
1156 $query = $this->db->query(sprintf("SELECT * FROM `payments`, `users` WHERE `payments`.`by` = `users`.`idu` AND `payments`.`%s` = '%s'", $field, $this->db->real_escape_string($id)));
1157
1158 // Fetch the result
1159 $row = $query->fetch_assoc();
1160
1161 return $row;
1162 }
1163
1164 function updatePayment($id, $type) {
1165 /*
1166 @function updatePayment
1167 Type 0: Suspended
1168 Type 1: Completed
1169 Type 2: Reversed
1170 Type 3: Refunded
1171 Type 4: Pending
1172 Type 5: Failed
1173 Type 6: Denied
1174 */
1175
1176 $row = $this->validatePayment($id);
1177 $types = array(0, 1, 2, 3, 4, 5, 6);
1178
1179 if($row && in_array($type, $types)) {
1180 // Update the payment
1181 $stmt = $this->db->prepare("UPDATE `payments` SET `status` = ?, `time` = `time`, `valid` = `valid` WHERE `id` = ?");
1182
1183 $stmt->bind_param("ii", $type, $row['id']);
1184
1185 // Execute the statement
1186 $stmt->execute();
1187
1188 // Save the affected rows
1189 $affected = $stmt->affected_rows;
1190
1191 // Close the statement
1192 $stmt->close();
1193
1194 // If the row has been affected
1195 return ($affected) ? 1 : 0;
1196 }
1197 }
1198
1199 function getPayments($start, $id = null) {
1200 // ID: Set to retrieve the payments history from a specific user
1201 global $LNG;
1202
1203 // If the $start value is 0, empty the query;
1204 if($start == 0) {
1205 $start = '';
1206 } else {
1207 // Else, build up the query
1208 $start = 'AND `id` < \''.$this->db->real_escape_string($start).'\'';
1209 }
1210
1211 if($id) {
1212 $query = sprintf("SELECT * FROM `payments`,`users` WHERE `payments`.`by` = '%s' AND `payments`.`by` = `users`.`idu` ORDER BY `payments`.`id` DESC", $this->db->real_escape_string($id));
1213 } else {
1214 $query = sprintf("SELECT * FROM `payments`,`users` WHERE `payments`.`by` = `users`.`idu` %s ORDER BY `payments`.`id` DESC LIMIT %s", $start, $this->db->real_escape_string($this->per_page + 1));
1215 }
1216
1217 $result = $this->db->query($query);
1218
1219 while($row = $result->fetch_assoc()) {
1220 $rows[] = $row;
1221 }
1222
1223 if(array_key_exists($this->per_page, $rows) && !$id) {
1224 $loadmore = 1;
1225
1226 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
1227 array_pop($rows);
1228 }
1229
1230 $output = ''; // Define the rows variable
1231
1232 foreach($rows as $row) {
1233 if($row['type'] == 0) {
1234 $type = $LNG['monthly'];
1235 } else {
1236 $type = $LNG['yearly'];
1237 }
1238 // If the transaction is not completed, set a class to display the button in another color (red)
1239 if($row['status'] !== '1') {
1240 $class = ' modal-btn-active';
1241 } else {
1242 $class = '';
1243 }
1244
1245 $date = explode('-', $row['time']);
1246
1247 // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language)
1248 $month = intval($date[1]);
1249
1250 $date = substr($LNG["month_$month"], 0, 3).' '.substr($date[2], 0, 2).', '.$date[0];
1251
1252 $output .= '
1253 <div class="manage-users-container" id="payment'.$row['id'].'">
1254 <div class="manage-users-image"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50" /></a></div>
1255 <div class="manage-users-content"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank">'.$row['username'].'</a><br />'.$date.' - '.$row['amount'].' '.$row['currency'].'</div>
1256 <div class="manage-users-buttons">
1257 <div class="modal-btn'.$class.' list-button"><a href="'.$this->url.'/index.php?a=admin&b=payments&id='.$row['id'].'" rel="loadpage">'.$LNG['view'].'</a></div>
1258 </div>
1259 '.$content.'</div>';
1260
1261 $last = $row['id'];
1262 }
1263 if($loadmore) {
1264 $output .= '<div class="admin-load-more"><div id="more_payments">
1265 <div class="load_more"><a onclick="manage_the('.$last.', 2)" id="infinite-load">'.$LNG['load_more'].'</a></div>
1266 </div></div>';
1267 }
1268
1269 // Return the array set
1270 return $output;
1271 }
1272
1273 function getPayment($id) {
1274 global $LNG;
1275
1276 $row = $this->validatePayment($id);
1277
1278 if($row) {
1279 $content = '<div class="report-content"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=112&h=112" height="15" width="15"> <span class="manage-report-author"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank">'.realName($row['username']).'</a></div>';
1280
1281 $date = explode('-', $row['time']);
1282 // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language)
1283 $month = intval($date[1]);
1284 $date = substr($LNG["month_$month"], 0, 3).' '.substr($date[2], 0, 2).', '.$date[0];
1285
1286 $valid = explode('-', $row['valid']);
1287 // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language)
1288 $month = intval($valid[1]);
1289 $valid = substr($LNG["month_$month"], 0, 3).' '.substr($valid[2], 0, 2).', '.$valid[0];
1290
1291 $status = paymentStatus($row['status']);
1292
1293 $output = ' <div class="page-inner">
1294 <div class="report-title">'.$LNG['transaction_details'].'</div>
1295 <div class="payment-content">
1296 <div class="payment-row"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50" height="15" width="15" /></a> <a href="'.$this->url.'/index.php?a=admin&b=users&id='.$row['idu'].'" target="_blank">'.realName($row['username']).'</a></div>
1297 <div class="payment-row">'.$LNG['status'].': <strong>'.$status.'</strong></div>
1298 <div class="payment-row">'.$LNG['ttl_last_name'].': <strong>'.$row['payer_last_name'].'</strong></div>
1299 <div class="payment-row">'.$LNG['ttl_first_name'].': <strong>'.$row['payer_first_name'].'</strong></div>
1300 <div class="payment-row">'.$LNG['ttl_email'].': <strong>'.$row['payer_email'].'</strong></div>
1301 <div class="payment-row">'.$LNG['ttl_country'].': <strong>'.$row['payer_country'].'</strong></div>
1302 <div class="payment-row">'.$LNG['transaction_id'].': <strong>#'.$row['txn_id'].'</strong></div>
1303 <div class="payment-row">'.$LNG['amount'].': <strong>'.$row['amount'].' '.$row['currency'].' </strong></div>
1304 <div class="payment-row">'.$LNG['date'].': <strong>'.$date.'</strong></div>
1305 <div class="payment-row">'.$LNG['plan'].': <strong>'.($row['type'] ? $LNG['yearly'].' '.$LNG['pro_plan'] : $LNG['monthly'].' '.$LNG['pro_plan']).'</strong></div>
1306 <div class="payment-row">'.$LNG['valid'].': <strong>'.$valid.'</strong></div>
1307 </div>
1308 </div>
1309 <div class="divider"></div>
1310 '.$this->paymentButtons($row);
1311
1312 return $output;
1313 }
1314 }
1315
1316 function paymentButtons($payment) {
1317 global $LNG;
1318
1319 // If the report is not reviewed
1320
1321 if($payment['status'] == 0) {
1322 $output .= '<div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=payments&id='.$payment['id'].'&type=1&token_id='.$_SESSION['token_id'].'">'.$LNG['enable'].'</a></div>';
1323 } else {
1324 $output .= '<div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=payments&id='.$payment['id'].'&type=0&token_id='.$_SESSION['token_id'].'">'.$LNG['suspend'].'</a></div>';
1325 }
1326
1327 return '<div class="page-inner">'.$output.'</div>';
1328 }
1329}
1330class manageReports {
1331 public $db; // Database Property
1332 public $url; // Installation URL Property
1333 public $title; // Installation WebSite Title
1334 public $per_page; // Limit per page
1335
1336 function getReports($start, $tracks) {
1337 // Tracks: Array of tracks id to retrieve reports for
1338 global $LNG;
1339 if($tracks) {
1340 // If tracks is set but the value is not array, return false
1341 if(!is_array($tracks)) {
1342 return false;
1343 }
1344 $query = sprintf("SELECT * FROM `reports`,`users` WHERE `reports`.`by` = `users`.`idu` AND `reports`.`track` IN (%s) AND `type` = 1 AND (`state` = 2 OR `state` = 3) ORDER BY `reports`.`id` DESC", $this->db->real_escape_string(implode(',', $tracks)));
1345 } else {
1346 // If the $start value is 0, empty the query;
1347 if($start == 0) {
1348 $start = '';
1349 } else {
1350 // Else, build up the query
1351 $start = 'AND `id` < \''.$this->db->real_escape_string($start).'\'';
1352 }
1353 $query = sprintf("SELECT * FROM `reports`,`users` WHERE `reports`.`by` = `users`.`idu` AND `state` = 0 %s ORDER BY `reports`.`id` DESC LIMIT %s", $start, $this->db->real_escape_string($this->per_page + 1));
1354 }
1355 $result = $this->db->query($query);
1356
1357 while($row = $result->fetch_assoc()) {
1358 $rows[] = $row;
1359 }
1360
1361 if(array_key_exists($this->per_page, $rows) && !$tracks) {
1362 $loadmore = 1;
1363
1364 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
1365 array_pop($rows);
1366 }
1367
1368 $output = ''; // Define the rows variable
1369
1370 foreach($rows as $row) {
1371 if($row['type'] == 0) {
1372 $type = $LNG['abusive_comment'];
1373 } else {
1374 $type = $LNG['copyright_infringement'];
1375 }
1376
1377 $output .= '
1378 <div class="manage-users-container" id="report'.$row['id'].'">
1379 <div class="manage-users-image"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50" /></a></div>
1380 <div class="manage-users-content"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank">'.$row['username'].'</a><br />'.$type.'</div>
1381 <div class="manage-users-buttons">
1382 <div class="modal-btn list-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$row['id'].'" rel="loadpage">'.$LNG['view'].'</a></div>
1383 </div>
1384 '.$content.'</div>';
1385
1386 $last = $row['id'];
1387 }
1388 if($loadmore) {
1389 $output .= '<div class="admin-load-more"><div id="more_reports">
1390 <div class="load_more"><a onclick="manage_the('.$last.', 1)" id="infinite-load">'.$LNG['load_more'].'</a></div>
1391 </div></div>';
1392 }
1393
1394 // Return the array set
1395 return $output;
1396 }
1397
1398 function getReport($id) {
1399 global $LNG;
1400
1401 // Select the report
1402 $query = $this->db->query(sprintf("SELECT * FROM `reports`, `users` WHERE `reports`.`by` = `users`.`idu` AND `reports`.`id` = '%s'", $this->db->real_escape_string($id)));
1403
1404 // Fetch the result
1405 $row = $query->fetch_assoc();
1406
1407 if($row) {
1408 // Output report comment
1409 if($row['type'] == 0) {
1410 $x = $LNG['reported_by'];
1411 $y = $LNG['author'];
1412 $title = $LNG['abusive_comment'];
1413 $query = $this->db->query(sprintf("SELECT * FROM `comments`,`users` WHERE `comments`.`id` = '%s' AND `users`.`idu` = `comments`.`uid`", $this->db->real_escape_string($row['track'])));
1414 $result = $query->fetch_assoc();
1415
1416 $content = '<div class="report-content"><img src="'.$this->url.'/thumb.php?src='.$result['image'].'&t=a&w=112&h=112" height="15" width="15"> <span class="manage-report-author"><a href="'.$this->url.'/index.php?a=admin&b=users&id='.$result['idu'].'" target="_blank">'.realName($result['username']).'</a></div>';
1417 } else {
1418 $x = $LNG['claimant'];
1419 $y = $LNG['infringing_material'];
1420 $title = $LNG['copyright_infringement'];
1421 $query = $this->db->query(sprintf("SELECT * FROM `tracks`,`users` WHERE `tracks`.`id` = '%s' AND `users`.`idu` = `tracks`.`uid`", $this->db->real_escape_string($row['track'])));
1422 $result = $query->fetch_assoc();
1423
1424 $content = '<div class="report-content"><img src="'.$this->url.'/thumb.php?src='.$result['art'].'&t=m&w=112&h=112" height="15" width="15"> <a href="'.$this->url.'/index.php?a=track&id='.$result['id'].'" target="_blank">'.$result['title'].'</a> '.strtolower($LNG['by']).' <img src="'.$this->url.'/thumb.php?src='.$result['image'].'&t=a&w=50&h=50" height="15" width="15" /> <a href="'.$this->url.'/index.php?a=admin&b=users&id='.$result['idu'].'" target="_blank">'.realName($result['username']).'</a></div>';
1425 }
1426
1427 $output = ' <div class="page-inner">
1428 <div class="report-title">'.$x.'</div>
1429 <div class="report-content"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50" height="15" width="15" /></a> <a href="'.$this->url.'/index.php?a=admin&b=users&id='.$row['idu'].'" target="_blank">'.realName($row['username']).'</a></div>
1430 </div>
1431 <div class="divider"></div>
1432 <div class="page-inner">
1433 <div class="report-title">'.$title.'</div>
1434 <div class="report-content">'.$row['content'].'</div>
1435 </div>
1436 <div class="divider"></div>
1437 '.(($result['username']) ? '<div class="page-inner">
1438 <div class="report-title">'.$y.'</div>
1439 '.$content.'
1440 </div>
1441 <div class="divider"></div>' : '').'
1442 '.$this->reportButtons($row);
1443
1444 return $output;
1445 }
1446 }
1447
1448 function reportButtons($report) {
1449 global $LNG;
1450 // If the report is not reviewed
1451 if($report['state'] == 0) {
1452 $output .= '<div class="page-inner">';
1453 if($report['type'] == 0) {
1454 $output .= '<div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=2&token_id='.$_SESSION['token_id'].'">'.$LNG['delete_comment'].'</a></div>
1455 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=1&token_id='.$_SESSION['token_id'].'">'.$LNG['delete_report'].'</a></div>
1456 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=track&id='.$report['parent'].'#comment'.$report['track'].'" target="_blank">'.$LNG['view_comment'].'</a></div>';
1457 } else {
1458 $output .= '<div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=3&token_id='.$_SESSION['token_id'].'">'.$LNG['suspend_track'].'</a></div>
1459 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=2&token_id='.$_SESSION['token_id'].'">'.$LNG['delete_track'].'</a></div>
1460 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=1&token_id='.$_SESSION['token_id'].'">'.$LNG['delete_report'].'</a></div>';
1461 }
1462 $output .= '</div>';
1463
1464 // If the report is safe
1465 } elseif($report['state'] == 1) {
1466 $output = notificationBox('info', $LNG['safe_report']);
1467
1468 // If the reported material has been deleted
1469 } elseif($report['state'] == 2) {
1470 if($report['type'] == 0) {
1471 $output = notificationBox('error', $LNG['deleted_comment']);
1472 } else {
1473 $output = notificationBox('error', $LNG['deleted_track']);
1474 }
1475 } elseif($report['state'] == 3) {
1476 $output = notificationBox('error', $LNG['suspended_track']).'<div class="page-inner"><div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=4&token_id='.$_SESSION['token_id'].'">'.$LNG['restore_track'].'</a></div></div>';
1477 } elseif($report['state'] == 4) {
1478 $output = notificationBox('info', $LNG['restored_track']).'<div class="page-inner">
1479 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=3&token_id='.$_SESSION['token_id'].'">'.$LNG['suspend_track'].'</a></div>
1480 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=2&token_id='.$_SESSION['token_id'].'">'.$LNG['delete_track'].'</a></div>
1481 <div class="modal-btn page-button"><a href="'.$this->url.'/index.php?a=admin&b=reports&id='.$_GET['id'].'&type=1&token_id='.$_SESSION['token_id'].'">'.$LNG['delete_report'].'</a></div></div>';
1482 }
1483
1484 return $output;
1485 }
1486
1487 function manageReport($id, $type) {
1488 // Type 0: Delete comment
1489 // Type 1: Delete report
1490 // Type 2: Delete track
1491 // Type 3: Suspend track
1492 // Type 4: Restore track
1493
1494 // Select the report
1495 $query = $this->db->query(sprintf("SELECT * FROM `reports`, `users` WHERE `reports`.`by` = `users`.`idu` AND `reports`.`id` = '%s'", $this->db->real_escape_string($id)));
1496
1497 // Fetch the result
1498 $report = $query->fetch_assoc();
1499
1500 // Store the track ID
1501 $track = $report['track'];
1502
1503 if($type == 1) {
1504 // Make the report safe
1505 $stmt = $this->db->prepare("UPDATE `reports` SET `state` = '1' WHERE `track` = ? AND `type` = ? AND `id` = ?");
1506
1507 $stmt->bind_param("iii", $report['track'], $report['type'], $id);
1508
1509 // Execute the statement
1510 $stmt->execute();
1511
1512 // Save the affected rows
1513 $affected = $stmt->affected_rows;
1514
1515 // Close the statement
1516 $stmt->close();
1517
1518 // If the row has been affected
1519 return ($affected) ? 1 : 0;
1520 } else {
1521 // Prepare the statement to delete the message from the database
1522 if($report['type'] == 1) {
1523 // If the track has been suspended, send an email
1524 $query = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($track)));
1525 $result = $query->fetch_assoc();
1526
1527 if($type == 2) {
1528 // Execute the deleteMedia function
1529 deleteMedia($result['art'], $result['name'], 1);
1530
1531 $stmt = $this->db->prepare("DELETE FROM `tracks` WHERE `id` = '{$this->db->real_escape_string($track)}'");
1532 } elseif($type == 3) {
1533 $stmt = $this->db->prepare("UPDATE `tracks` SET `public` = '2', `time` = `time` WHERE `id` = '{$this->db->real_escape_string($track)}'");
1534 } elseif($type == 4) {
1535 $stmt = $this->db->prepare("UPDATE `tracks` SET `public` = '1', `time` = `time` WHERE `id` = '{$this->db->real_escape_string($track)}'");
1536 }
1537 } else {
1538 $stmt = $this->db->prepare("DELETE FROM `comments` WHERE `id` = '{$this->db->real_escape_string($track)}'");
1539 }
1540 // Execute the statement
1541 $stmt->execute();
1542
1543 // Save the affected rows
1544 $affected = $stmt->affected_rows;
1545
1546 // Close the statement
1547 $stmt->close();
1548
1549 if($affected) {
1550 if($type == 3) {
1551 // Suspend the track for the selected report, and dimiss the rest of the reports
1552 $this->db->query(sprintf("UPDATE `reports` SET `state` = '1' WHERE `track` = '%s' AND `type` = '%s' AND `id` != '%s'", $this->db->real_escape_string($track), (($report['type']) ? 1 : 0), $id));
1553 $this->db->query(sprintf("UPDATE `reports` SET `state` = '3' WHERE `track` = '%s' AND `type` = '%s' AND `id` = '%s'", $this->db->real_escape_string($track), (($report['type']) ? 1 : 0), $id));
1554 } elseif($type == 4) {
1555 // Restore the track
1556 $this->db->query(sprintf("UPDATE `reports` SET `state` = '4' WHERE `track` = '%s' AND `type` = '%s'", $this->db->real_escape_string($track), (($report['type']) ? 1 : 0)));
1557 } else {
1558 $this->db->query(sprintf("UPDATE `reports` SET `state` = '2' WHERE `track` = '%s' AND `type` = '%s'", $this->db->real_escape_string($track), (($report['type']) ? 1 : 0)));
1559 }
1560
1561 if($report['type'] == 1) {
1562 global $LNG;
1563 // Send mail to the copyright claimer
1564 sendMail($report['email'], sprintf($LNG['ttl_copyright_notification'], $result['title']), sprintf($LNG['copyright_mail_1'], realName($report['username'], $report['first_name'], $report['last_name']), $this->url.'/index.php?a=track&id='.$result['id'], $result['title'], $id, $this->url, $this->title), $this->email);
1565
1566 // Send mail to the abuser
1567 sendMail($result['email'], sprintf($LNG['ttl_copyright_notification'], $result['title']), sprintf($LNG['copyright_mail_0'], realName($result['username'], $result['first_name'], $result['last_name']), $this->url.'/index.php?a=track&id='.$result['id'], $result['title'], $this->url.'/index.php?a=profile&u='.$report['username'], realName($report['username'], $report['first_name'], $report['last_name']), $id, $this->url, $this->title), $this->email);
1568
1569 // If the track is suspended or restored
1570 if($type == 3 || $type == 4) {
1571 return 1;
1572 }
1573
1574 $this->db->query("DELETE FROM `comments` WHERE `tid` = '{$this->db->real_escape_string($track)}'");
1575 $this->db->query("DELETE FROM `likes` WHERE `track` = '{$this->db->real_escape_string($track)}'");
1576 $this->db->query("DELETE FROM `notifications` WHERE `parent` = '{$this->db->real_escape_string($track)}'");
1577 $this->db->query("DELETE FROM `playlistentries` WHERE `track` = '{$this->db->real_escape_string($track)}'");
1578 } else {
1579 $this->db->query("DELETE FROM `notifications` WHERE `child` = '{$this->db->real_escape_string($track)}' AND `type` = '1'");
1580 }
1581
1582 return 1;
1583 }
1584 }
1585 }
1586}
1587
1588class feed {
1589 public $db; // Database Property
1590 public $url; // Installation URL Property
1591 public $title; // Installation WebSite Title
1592 public $email; // Installation Default E-mail
1593 public $id; // The ID of the user
1594 public $username; // The username
1595 public $user_email; // The email of the current username
1596 public $per_page; // The per_page limit for feed
1597 public $c_start; // The row where to start the nex
1598 public $c_per_page; // Comments per_page limit
1599 public $s_per_page; // Subscribers per page (dedicated profile page)
1600 public $m_per_page; // Conversation Messages (Chat) per page
1601 public $time; // The time option from the admin panel
1602 public $art_size; // Image size allowed for upload (art cover)
1603 public $art_format; // Image formats allowed for upload (art cover)
1604 public $track_size; // Track size allowed for upload
1605 public $track_format; // Track formats allowed for upload
1606 public $track_size_total; // Total track size allowed for upload
1607 public $subscriptions; // The public variable to be accessed outside of the class to pass variable to sidebar functions
1608 public $message_length; // The maximum message length allowed for messages/comments
1609 public $max_images; // The maxium images allowed to be uploaded per message
1610 public $is_admin; // The option for is_admin to show the post no matter what
1611 public $profile; // The current viewed user profile
1612 public $profile_id; // The profile id of the current viewed user profile
1613 public $profile_data; // The public variable which holds all the data for queried user
1614 public $subscriptionsList; // The subscriptions users list Array([value],[count])
1615 public $subscribersList; // The subscribers users list Array([value],[count])
1616 public $subsList; // The subs list for dedicated subs page
1617 public $trackList; // A list of tracks separated by "," (comma)
1618 public $l_per_post; // Likes per post (small thumbs)
1619 public $online_time; // The amount of time an user is being kept as online
1620 public $friends_online; // The amount of online friends to be displayed on the Feed/Subscriptions page
1621 public $chat_length; // The maximum chat length allowed for conversations
1622 public $email_comment; // The admin settings for allowing e-mails on comments to be sent
1623 public $email_like; // The admin settings for allowing e-mails on likes to be sent
1624 public $email_new_friend; // The admin settings for allowing e-mails on new friendship to be sent
1625 public $categories; // The category list
1626
1627 function getTracks($query, $type, $typeVal) {
1628 // QUERY: Holds the query string
1629 // TYPE: [exploreTracks, loadProfile]
1630 // TYPEVAL: Values for the JS functions
1631 // EXTRA: Is defined when two ID values are set, and need the extra one as the latest ID
1632 global $LNG;
1633
1634 // Run the query
1635 $result = $this->db->query($query);
1636
1637 // Set the result into an array
1638 $rows = array();
1639 while($row = $result->fetch_assoc()) {
1640 $rows[] = $row;
1641 }
1642
1643 // If the Stream is empty, display a welcome message
1644 if(empty($rows) && $type == 'exploreTracks') {
1645 return $this->showError('no_results', 1);
1646 } elseif(empty($rows) && $type == 'searchTracks') {
1647 return $this->showError('no_results', 1);
1648 }
1649
1650 // Define the $loadmore variable
1651 $loadmore = '';
1652
1653 // If there are more results available than the limit, then show the Load More Comments
1654 if(array_key_exists($this->per_page, $rows)) {
1655 $loadmore = 1;
1656
1657 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
1658 array_pop($rows);
1659 }
1660
1661 // Define the $messages variable
1662 $sound = '';
1663
1664 // If it's set profile, then set $profile
1665 if($this->profile) {
1666 $profile = ', \''.$this->profile.'\'';
1667 }
1668
1669 // Start outputting the content
1670 foreach($rows as $row) {
1671 $time = $row['time']; $b = '';
1672 if($this->time == '0') {
1673 $time = date("c", strtotime($row['time']));
1674 } elseif($this->time == '2') {
1675 $time = $this->ago(strtotime($row['time']));
1676 } elseif($this->time == '3') {
1677 $date = strtotime($row['time']);
1678 $time = date('Y-m-d', $date);
1679 $b = '-standard';
1680 }
1681
1682 // Define the style variable (reset the last value)
1683 $style = '';
1684
1685 // If the track is private
1686 if($this->username !== $row['username'] && $row['public'] == 0) {
1687 $hide = 1;
1688 } else {
1689 $hide = 0;
1690 }
1691
1692
1693 // If the user is a visitor
1694 if(empty($this->username)) {
1695 $style = ' style="display: none;"';
1696 }
1697
1698 if($hide == 1 && !$this->is_admin) {
1699 $error = $this->showError('track_hidden_1');
1700 $sound .= $error[0];
1701 } elseif($hide == 2) {
1702 $error = $this->showError('track_suspended_1');
1703 $sound .= $error[0];
1704 } else {
1705 $tag = $this->fetchCategory($row['tag']);
1706 if($type == 'trackPage') {
1707 $comment = (($this->id) ? '<div class="message-comment-box-container" id="comment_box_'.$row['id'].'"'.$style.'>
1708 <div class="message-reply-avatar">
1709 <a href="'.$this->url.'/index.php?a=profile&u='.$this->user['username'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$this->user['image'].'&t=a&w=50&h=50" /></a>
1710 </div>
1711 <div class="message-comment-box-form">
1712 <textarea id="comment-form'.$row['id'].'" onclick="showButton('.$row['id'].')" placeholder="'.$LNG['leave_comment'].'" class="comment-reply-textarea"></textarea>
1713 </div>
1714 <div class="comment-btn" id="comment_btn_'.$row['id'].'">
1715 <a onclick="postComment('.$row['id'].')">'.$LNG['post'].'</a>
1716 </div>
1717 <div class="delete_preloader" id="post_comment_'.$row['id'].'"></div>
1718 </div>' : '').'
1719 <div class="comments-container" id="comments-list'.$row['id'].'">
1720 '.$this->getComments($row['id'], null, $this->c_start).'
1721 </div>';
1722 }
1723 $track .= '<div id="track'.$row['id'].'" class="song-container'.(($type == 'trackPage') ? ' song-container-page' : '').'">
1724 <div class="song-art"><a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&t=m&w=112&h=112" id="song-art'.$row['id'].'" alt="'.$row['title'].'"></a></div>
1725 <div class="song-top">
1726 <div class="song-timeago">
1727 <a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" rel="loadpage"><span id="time'.$row['id'].'">
1728 <div class="timeago'.$b.'" title="'.$time.'">
1729 '.$time.'
1730 </div>
1731 </span>
1732 </a>
1733 </div>
1734 <div data-track-name="'.$row['name'].'" data-track-id="'.$row['id'].'" id="play'.$row['id'].'" class="track song-play-btn">
1735 </div>
1736 <div class="song-titles">
1737 <div class="song-author"><a onmouseover="profileCard('.$row['idu'].', '.$row['id'].', 0, 0);" onmouseout="profileCard(0, 0, 0, 1);" onclick="profileCard(0, 0, 1, 1);" href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage" id="song-author'.$row['id'].'">'.realName($row['username'], $row['first_name'], $row['last_name']).'</a></div>
1738 <div class="song-tag">
1739 <a href="'.$this->url.'/index.php?a=explore&filter='.$tag.'" rel="loadpage">'.$tag.'</a>
1740 </div>
1741 <div class="song-title">
1742 <a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" id="song-url'.$row['id'].'" rel="loadpage"><div id="song-name'.$row['id'].'">'.$row['title'].'</div></a>
1743 </div>
1744 </div>
1745 </div>
1746 <div class="player-controls">
1747 <div id="song-controls'.$row['id'].'">
1748 <div id="jp_container_123" class="jp-audio">
1749 <div class="jp-type-single">
1750 <div class="jp-gui jp-interface">
1751 <div class="jp-progress">
1752 <div class="jp-seek-bar">
1753 <div class="jp-play-bar"></div>
1754 </div>
1755 </div>
1756 </div>
1757 </div>
1758 </div>
1759 </div>
1760 </div>
1761 <div class="track-actions-container">
1762 <div class="track-actions"><div class="track-actions-content" id="track-action'.$row['id'].'">'.$this->getActions($row['id'], null).'</div></div>
1763 </div>
1764 '.$comment.'
1765 </div>';
1766 $start = (isset($row['extra_id']) ? $row['extra_id'] : $row['id']);
1767 }
1768 }
1769 // If the $loadmore button is set, then show the Load More Messages button
1770 if($loadmore) {
1771 $track .= '
1772 <div id="load-more">
1773 <div class="load_more"><a onclick="'.$type.'('.$start.', '.$typeVal.''.$profile.')" id="infinite-load">'.$LNG['load_more'].'</a></div>
1774 </div>';
1775 }
1776 return array($track, 0);
1777 }
1778
1779 function explore($start, $value) {
1780 // If the $start value is 0, empty the query;
1781 if($value == 'popular music' || $value == 'liked music') {
1782 $limit = ", ".($this->db->real_escape_string($start) + ($this->per_page))." as `extra_id`";
1783 } else {
1784 if($start == 0) {
1785 $start = '';
1786 } else {
1787 // Else, build up the query
1788 $start = 'AND `tracks`.`id` < \''.$this->db->real_escape_string($start).'\'';
1789 }
1790 }
1791
1792 // Query for the Popular Music filter
1793 if($value == 'popular music') {
1794 $query = sprintf("SELECT `views`.`track`, `tracks`.*, `users`.*, COUNT(`track`) as `count`%s FROM `views`,`tracks`,`users` WHERE `views`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= date(`views`.`time`) AND `tracks`.`public` = '1' GROUP BY `track` ORDER BY `count` DESC LIMIT %s, %s", $limit, $this->db->real_escape_string($start), ($this->per_page + 1));
1795 $value = '\''.$value.'\'';
1796 } elseif($value == 'liked music') {
1797 $query = sprintf("SELECT `likes`.`track`, `tracks`.*, `users`.*, COUNT(`track`) as `count`%s FROM `likes`,`tracks`,`users` WHERE `likes`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL 7 DAY) <= date(`likes`.`time`) AND `tracks`.`public` = '1' GROUP BY `track` ORDER BY `count` DESC LIMIT %s, %s", $limit, $this->db->real_escape_string($start), ($this->per_page + 1));
1798 $value = '\''.$value.'\'';
1799 } elseif(!empty($value)) {
1800 $query = sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`tag` REGEXP '[[:<:]]%s[[:>:]]' AND `tracks`.`uid` = `users`.`idu` %s AND `tracks`.`public` = '1' AND `users`.`private` = 0 ORDER BY `tracks`.`id` DESC LIMIT %s", $this->db->real_escape_string($value), $start, ($this->per_page + 1));
1801 $value = '\''.$value.'\'';
1802 } else {
1803 $query = sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`uid` = `users`.`idu` %s AND `tracks`.`public` = 1 AND `users`.`private` = 0 ORDER BY `tracks`.`id` DESC LIMIT %s", $start, ($this->per_page + 1));
1804 $value = '\'\'';
1805 }
1806
1807 return $this->getTracks($query, 'exploreTracks', $value);
1808 }
1809
1810 function stream($start, $value) {
1811 $this->subscriptions = $this->getSubscriptionsList();
1812
1813 // If the $start value is 0, empty the query;
1814 if($start == 0) {
1815 $start = '';
1816 } else {
1817 // Else, build up the query
1818 $start = 'AND tracks.id < \''.$this->db->real_escape_string($start).'\'';
1819 }
1820
1821 if(!empty($this->subscriptions)) {
1822 $uid = $this->id.','.$this->subscriptions;
1823 } else {
1824 $uid = $this->id;
1825 }
1826
1827 // The query to select the subscribed users
1828 $query = sprintf("SELECT * FROM tracks, users WHERE tracks.uid IN (%s) AND tracks.public = '1' AND tracks.uid = users.idu %s ORDER BY tracks.id DESC LIMIT %s", $uid, $start, ($this->per_page + 1));
1829 $value = '\'\'';
1830
1831 // If the user subscribed to other users get the tracks (prevents fatal error because of empty IN () query)
1832 if(!empty($this->subscriptions)) {
1833 return $this->getTracks($query, 'loadStream', $value);
1834 } else {
1835 return $this->showError('welcome_stream');
1836 }
1837 }
1838
1839 function getProfile($start, $value) {
1840 $profile = $this->profile_data;
1841 $this->profile_id = $profile['idu'];
1842
1843 // If the username exist
1844 if(!empty($profile['idu'])) {
1845 $relationship = $this->verifyRelationship($this->id, $this->profile_id, 0);
1846
1847 // Check privacy
1848 switch($profile['private']) {
1849 case 0:
1850 break;
1851 case 1:
1852 // Check if the username is not same with the profile
1853 if($this->profile !== $this->username) {
1854 if($profile['suspended']) {
1855 return $this->showError('profile_suspended');
1856 }
1857 return $this->showError('profile_private');
1858 }
1859 break;
1860 case 2:
1861 // Check relationship
1862 if(!$relationship) {
1863 return $this->showError('profile_semi_private');
1864 }
1865 break;
1866 }
1867
1868 $allowedDates = $this->listDates('profile');
1869
1870 // If the $start value is 0, empty the query;
1871 if($start == 0) {
1872 $start = '';
1873 } else {
1874 // Else, build up the query
1875 $start = 'AND tracks.id < \''.$this->db->real_escape_string($start).'\'';
1876 }
1877
1878 // Decide if the query will include only public sounds or not
1879 $public = ($this->username == $this->profile) ? 'AND `tracks`.`public` != 2' : 'AND `tracks`.`public` = 1';
1880 if(in_array($value, $allowedType)) {
1881 $query = sprintf("SELECT * FROM `tracks`, users WHERE tracks.uid = '%s' AND tracks.type = '%s' AND tracks.uid = users.idu %s %s ORDER BY tracks.id DESC LIMIT %s", $this->db->real_escape_string($profile['idu']), $this->db->real_escape_string($value), $public, $start, ($this->per_page + 1));
1882 $value = '\''.$value.'\'';
1883 } elseif(in_array($value, $allowedDates)) {
1884 $query = sprintf("SELECT * FROM `tracks`, users WHERE tracks.uid = '%s' AND extract(YEAR_MONTH from `time`) = '%s' AND tracks.uid = users.idu %s %s ORDER BY tracks.id DESC LIMIT %s", $this->db->real_escape_string($profile['idu']), $this->db->real_escape_string($value), $public, $start, ($this->per_page + 1));
1885 $value = '\''.$value.'\'';
1886 } else {
1887 $query = sprintf("SELECT * FROM `tracks`, users WHERE tracks.uid = '%s' AND tracks.uid = users.idu %s %s ORDER BY tracks.id DESC LIMIT %s", $this->db->real_escape_string($profile['idu']), $public, $start, ($this->per_page + 1));
1888 $value = '\'\'';
1889 }
1890 return $this->getTracks($query, 'loadProfile', $value);
1891 } else {
1892 return $this->showError('profile_not_exist');
1893 }
1894 }
1895
1896 function getSubscriptionsList() {
1897 // The query to select the subscribed users
1898 $query = sprintf("SELECT `leader` FROM `relations` WHERE `subscriber` = '%s'", $this->db->real_escape_string($this->id));
1899
1900 // Run the query
1901 $result = $this->db->query($query);
1902
1903 // The array to store the subscribed users
1904 $subscriptions = array();
1905 while($row = $result->fetch_assoc()) {
1906 $subscriptions[] = $row['leader'];
1907 }
1908
1909 // Close the query
1910 $result->close();
1911
1912 // Return the subscriptions list (e.g: 13,22,19)
1913 return implode(',', $subscriptions);
1914 }
1915
1916 public function profileData($username = null, $id = null) {
1917 // The query to select the profile
1918 // If the $id is set (used in Subscribe function for profiels) then search for the ID
1919 if($id) {
1920 $query = sprintf("SELECT `idu`, `username`, `email`, `first_name`, `last_name`, `country`, `city`, `website`, `description`, `date`, `facebook`, `twitter`, `gplus`, `youtube`, `vimeo`, `tumblr`, `soundcloud`, `myspace`, `lastfm`, `image`, `private`, `suspended`, `cover`, `gender`, `email_new_friend` FROM `users` WHERE `idu` = '%s'", $this->db->real_escape_string($id));
1921 } else {
1922 $query = sprintf("SELECT `idu`, `username`, `email`, `first_name`, `last_name`, `country`, `city`, `website`, `description`, `date`, `facebook`, `twitter`, `gplus`, `youtube`, `vimeo`, `tumblr`, `soundcloud`, `myspace`, `lastfm`, `image`, `private`, `suspended`, `cover`, `gender`, `email_new_friend` FROM `users` WHERE `username` = '%s'", $this->db->real_escape_string($username));
1923 }
1924
1925 // Run the query
1926 $result = $this->db->query($query);
1927
1928 return $result->fetch_assoc();
1929 }
1930
1931 function fetchProfile($profile) {
1932 global $LNG, $CONF;
1933 $coverImage = ((!empty($profile['cover'])) ? $profile['cover'] : 'default.png');
1934 $coverAvatar = ((!empty($profile['image'])) ? $profile['image'] : 'default.png');
1935 $profileButtons = ((!empty($profile['idu'])) ? '<div id="subscribe'.$profile['idu'].'">'.$this->getSubscribe(null, null, null).'</div>'.$this->chatButton($profile['idu'], $profile['username'], 1) : '');
1936 $cover = '<div class="twelve columns">
1937 <div class="cover-container">
1938 <div class="cover-content">
1939 <div class="cover-image" style="background-position: center; background-image: url('.$this->url.'/thumb.php?src='.((!empty($profile['cover'])) ? $profile['cover'] : 'default.png').'&w=1100&h=200&t=c)">
1940 </div>
1941 <div class="cover-description">
1942 <div class="cover-avatar-content">
1943 <div class="cover-avatar">
1944 <span id="avatar'.$profile['idu'].$profile['username'].'"><img src="'.$this->url.'/thumb.php?src='.$coverAvatar.'&t=a&w=112&h=112" /></span>
1945 </div>
1946 </div>
1947 <div class="cover-description-content">
1948 <span id="author'.$profile['idu'].$profile['username'].'"></span><span id="time'.$profile['idu'].$profile['username'].'"></span><div class="cover-text-container">
1949 <div class="cover-username"><a href="'.$this->url.'/index.php?a=profile&u='.$profile['username'].'" rel="loadpage">'.realName($profile['username'], $profile['first_name'], $profile['last_name']).'</a>'.(($this->getProStatus($profile['idu'])) ? '<a href="'.$this->url.'/index.php?a=pro" rel="loadpage" title="'.$LNG['pro_user'].'"><span class="pro-icon pro-normal"></span></a>' : '').'</div>
1950 '.((location($profile['country'], $profile['city'])) ? '<div class="cover-location">'.location($profile['country'], $profile['city']).'</div>' : '').'</div>
1951 </div>
1952 <div class="cover-description-buttons">'.$profileButtons.'</div>
1953 <div class="cover-buttons">
1954 '.$this->coverButtons().'
1955 </div>
1956 </div>
1957 </div>
1958 </div>
1959 </div>';
1960 return $cover;
1961 }
1962
1963 function countSongs($id = null) {
1964 // If the logged in username is the same as the profile, count the private songs as well, otherwise only public ones
1965 $public = ($this->username == $this->profile) ? 'AND `tracks`.`public` != 2' : 'AND `tracks`.`public` = 1';
1966 $query = $this->db->query(sprintf("SELECT count(`uid`) FROM `tracks` WHERE `tracks`.`uid` = '%s' %s", (($id) ? $id : $this->db->real_escape_string($this->profile_id)), $public));
1967
1968 $result = $query->fetch_row();
1969 return $result[0];
1970 }
1971
1972 function getPlaylistTracks($id) {
1973 // Get the tracks for Playlist page
1974 $query = sprintf("SELECT * FROM `playlistentries`,`users`,`tracks` WHERE (`playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`public` = 1) OR (`playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`uid` = '%s') ORDER BY `playlistentries`.`id` DESC", $this->db->real_escape_string($id), $this->db->real_escape_string($id), $this->id);
1975
1976 return $this->getTracks($query, 'loadPlaylist', null);
1977 }
1978
1979 function getPlaylists($start = null, $type = null, $query = null) {
1980 global $LNG;
1981 // Type 0: Return the number of playlists from user
1982 // Type 1: Return the playlists for profiles
1983 // Type 2: Return the playlists for search
1984 // Type 3: Return the playlist for playlist page
1985
1986 if($type) {
1987 if($start == 0) {
1988 $start = '';
1989 } else {
1990 $start = 'AND `playlists`.`id` < \''.$this->db->real_escape_string($start).'\'';
1991 }
1992
1993 if($type == 1) {
1994 $public = ($this->username == $this->profile) ? '' : 'AND `playlists`.`public` = 1';
1995 $q = sprintf("SELECT * FROM `playlists`,`users` WHERE `playlists`.`by` = '%s' AND `users`.`idu` = `playlists`.`by` %s %s ORDER BY `id` DESC LIMIT %s", $this->profile_data['idu'], $public, $start, ($this->per_page + 1));
1996 } elseif($type == 2) {
1997 $q = sprintf("SELECT * FROM `playlists`,`users` WHERE `playlists`.`name` LIKE '%s' AND `users`.`idu` = `playlists`.`by` AND `playlists`.`public` = 1 %s ORDER BY `id` DESC LIMIT %s", '%'.$this->db->real_escape_string($query).'%', $start, ($this->per_page + 1));
1998 } elseif($type == 3) {
1999 $public = ($this->username == $this->profile) ? '' : 'AND `playlists`.`public` = 1';
2000 $q = sprintf("SELECT * FROM `playlists`,`users` WHERE `playlists`.`id` = '%s' AND `users`.`idu` = `playlists`.`by`", $this->db->real_escape_string($query));
2001 }
2002
2003 $getPlaylists = $this->db->query($q);
2004
2005 // Declare the rows array
2006 $rows = array();
2007 while($row = $getPlaylists->fetch_assoc()) {
2008 // Store the result into the array
2009 $rows[] = $row;
2010 }
2011
2012 if($type == 3) {
2013 // If the playlist doesn't exist
2014 if(!$rows) {
2015 return;
2016 }
2017 // If the playlist is private, and the logged-in user is not the author of the playlist
2018 elseif($rows[0]['public'] == 0 && $rows[0]['by'] !== $this->id) {
2019 return $this->showError('playlist_hidden');
2020 }
2021 } else {
2022 // Decide whether the load more will be shown or not
2023 if(array_key_exists($this->per_page, $rows)) {
2024 $loadmore = 1;
2025
2026 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
2027 array_pop($rows);
2028 }
2029 }
2030
2031 // Start the output
2032 foreach($rows as $value) {
2033 $time = $value['time']; $b = '';
2034 if($this->time == '0') {
2035 $time = date("c", strtotime($value['time']));
2036 } elseif($this->time == '2') {
2037 $time = $this->ago(strtotime($value['time']));
2038 } elseif($this->time == '3') {
2039 $date = strtotime($value['time']);
2040 $time = date('Y-m-d', $date);
2041 $b = '-standard';
2042 }
2043 $output .= '<div class="list-container" id="playlist'.$value['id'].'"><div class="list-inner"><div class="playlist-content">
2044
2045 <div class="playlist-artwork"><a href="'.$this->url.'/index.php?a=playlist&id='.$value['id'].'" rel="loadpage">'.$this->playlistArt($value['id'], 5).'</a></div>
2046 <div class="playlist-content-info">
2047 <div class="song-timeago"><span id="time'.$row['id'].'"><a href="'.$this->url.'/index.php?a=playlist&id='.$value['id'].'" rel="loadpage">
2048 <div class="timeago'.$b.'" title="'.$time.'">
2049 '.$time.'
2050 </div>
2051 </span></div>
2052 <a href="'.$this->url.'/index.php?a=playlist&id='.$value['id'].'" id="playlist-url'.$value['id'].'" rel="loadpage"><div class="playlist-title" id="playlist-name'.$value['id'].'">'.$value['name'].'</div></a>
2053 <div class="playlist-author">
2054 <a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'" rel="loadpage" onmouseover="profileCard('.$value['idu'].', '.$value['id'].', 2, 0);" onmouseout="profileCard(0, 0, 0, 1);" onclick="profileCard(0, 0, 1, 1);">'.realName($value['username'], $value['first_name'], $value['last_name']).'</a>
2055 </div>
2056 </div>
2057 '.$this->getPlaylistActions($value['id']).'
2058 </div></div></div>';
2059 }
2060
2061 if($loadmore) {
2062 $output .= '<div id="load-more">
2063 <div class="load_more"><a onclick="loadPlaylists('.$value['id'].', '.($type == 2 ? 2 : 1).', \''.($type == 2 ? $query : $value['username']).'\')" id="infinite-load">'.$LNG['load_more'].'</a></div>
2064 </div>';
2065 }
2066
2067 // If the query is for the playlist page, return array
2068 if($type == 3) {
2069 $tracks = $this->getPlaylistTracks($query);
2070 return array($output.$tracks[0], 0);
2071 }
2072 return $output;
2073 } else {
2074 $public = ($this->username == $this->profile) ? '' : 'AND `playlists`.`public` = 1';
2075 $query = $this->db->query(sprintf("SELECT count(`by`) FROM `playlists` WHERE `playlists`.`by` = '%s' %s", $this->db->real_escape_string($this->profile_id), $public));
2076
2077 $result = $query->fetch_row();
2078 return $result[0];
2079 }
2080 }
2081
2082 function getPlaylistActions($id, $type = null) {
2083 global $LNG;
2084
2085 // Get the likes, views, and other info
2086 $query = sprintf("SELECT * FROM `playlists` WHERE `id` = '%s'", $this->db->real_escape_string($id));
2087
2088 // Run the query
2089 $result = $this->db->query($query);
2090
2091 // Get the array element for the like
2092 $get = $result->fetch_assoc();
2093
2094 $count = $this->db->query(sprintf("SELECT COUNT(*) FROM `playlistentries`,`tracks` WHERE (`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`public` = 1) OR (`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`uid` = '%s' AND `tracks`.`public` != 2)", $this->db->real_escape_string($id), $this->db->real_escape_string($id), $this->id));
2095 $tracks = $count->fetch_row(); $count->close();
2096
2097 // Determine whether to show the delete/privacy buttons or not
2098 if($this->id == $get['by']) { // If it's current username is the same with the current author
2099 if($get['public'] == 1) {
2100 $privacy = '<div class="public-button" onclick="privacy('.$get['id'].', 0, 1)" title="'.$LNG['this_playlist_public'].'"></div>';
2101 $delete = '<div id="delete-button-'.$get['id'].'" class="delete-button" onclick="delete_modal('.$get['id'].', 3)" title="'.$LNG['delete'].'"></div>';
2102 } else {
2103 $privacy = '<div class="private-button" onclick="privacy('.$get['id'].', 1, 1)" title="'.$LNG['this_playlist_private'].'"></div>';
2104 $delete = '<div id="delete-button-'.$get['id'].'" class="delete-button" onclick="delete_modal('.$get['id'].', 3)" title="'.$LNG['delete'].'"></div>';
2105 }
2106 } else { // If the current username is not the same as the author
2107 $privacy = '';
2108 $delete = '';
2109 }
2110
2111 $output = '<div class="playlist-actions-container">
2112 <div class="playlist-actions">
2113 <div class="playlist-actions-content"><div class="share-button" onclick="share('.$get['id'].', 2)" title="'.$LNG['share'].'"><span class="action-text">'.$LNG['share'].'</span></div>'.$delete.'<span id="privacy-pl'.$get['id'].'">'.$privacy.'</span></div>
2114 <div class="playlist-stats">
2115 <div class="tracks-small-icon" style="float: right;">'.$tracks[0].' <span class="playlist-stats-text">'.$LNG['tracks'].'</span></div>
2116 </div>
2117 </div>
2118 </div>';
2119 return $output;
2120 }
2121
2122 function playlistArt($id, $limit) {
2123 $query = $this->db->query(sprintf("SELECT `tracks`.`art` FROM `playlistentries`,`tracks` WHERE (`playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`public` = 1) OR (`playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`uid` = '%s' AND `tracks`.`public` != 2) ORDER BY `playlistentries`.`id` DESC LIMIT %s", $this->db->real_escape_string($id), $this->db->real_escape_string($id), $this->id, $this->db->real_escape_string($limit)));
2124
2125 while($result = $query->fetch_assoc()) {
2126 $rows[] = $result;
2127 }
2128
2129 if(!empty($rows)) {
2130 // Display the album artwork
2131 $n = 0;
2132 foreach($rows as $row) {
2133 $output .= '<div style="transform:rotate('.(10*$n).'deg); -webkit-transform:rotate('.(10*$n).'deg); -ms-transform:rotate('.(10*$n).'deg); position: absolute; float: left; z-index: '.(99-$n).'"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&h=100&w=100&t=m" id="playlist-art'.$id.'"></div>';
2134 $n++;
2135 }
2136 } else {
2137 // Show the default artwork
2138 $output .= '<div style="transform:rotate('.(10*$n).'deg); -webkit-transform:rotate('.(10*$n).'deg); -ms-transform:rotate('.(10*$n).'deg); position: absolute; float: left; z-index: '.(99-$n).'"><img src="'.$this->url.'/thumb.php?src=default.png&h=100&w=100&t=m" id="playlist-art'.$id.'"></div>';
2139 }
2140 return $output;
2141 }
2142
2143 function coverButtons() {
2144 global $LNG;
2145
2146 $buttons = array( 't'.$this->countSongs() => array('', '', (($this->countSongs() == 1) ? 'track' : 'tracks')),
2147 ((!empty($this->subscriptionsList[1])) ? 'g'.$this->subscriptionsList[1] : '') => array('&r=', 'subscriptions'),
2148 ((!empty($this->subscribersList[1])) ? 's'.$this->subscribersList[1] : '') => array('&r=', 'subscribers'),
2149 (($this->getLikes()) ? 'l'.$this->getLikes() : '') => array('&r=', 'likes'),
2150 (($this->getPlaylists()) ? 'p'.$this->getPlaylists() : '') => array('&r=', 'playlists'));
2151 /*
2152 array map: value => parameter
2153 => parameter value
2154
2155 Special note: t, g, s, l, p characters are being inserted into the array in order to avoid duplicated array keys when the count is the same for both keys
2156 */
2157
2158 foreach($buttons as $value => $name) {
2159 // Check whether the value is empty or not in order to return the button
2160
2161 if($value) {
2162 $button .= '<a class="cover-button'.(($name[1] == $_GET['r']) ? ' cover-button-active' : '').'" rel="loadpage" href="'.$this->url.'/index.php?a=profile&u='.((!empty($this->profile)) ? $this->profile : $this->username).$name[0].$name[1].'">'.str_replace(array('t', 'g', 's', 'l', 'p'), '', $value).' '.$LNG[$name[1].$name[2]].'</a>';
2163 }
2164 }
2165
2166 return $button;
2167 }
2168
2169 function getProfileCard($profile) {
2170 global $LNG, $CONF;
2171 $coverImage = ((!empty($profile['cover'])) ? $profile['cover'] : 'default.png');
2172 $coverAvatar = ((!empty($profile['image'])) ? $profile['image'] : 'default.png');
2173 $subscribersList = $this->getSubs($profile['idu'], 1, null);
2174 $subscribe = $this->getSubscribe(null, null, 1);
2175 $count = $this->countSongs($profile['idu']);
2176 $card = '
2177 <div class="profile-card-cover"><img src="'.$this->url.'/thumb.php?src='.((!empty($profile['cover'])) ? $profile['cover'] : 'default.png').'&w=300&h=100&t=c"></div>
2178 <div class="profile-card-avatar">
2179 <a href="'.$this->url.'/index.php?a=profile&u='.$profile['username'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$coverAvatar.'&t=a&w=112&h=112" /></a>
2180 </div>
2181 <div class="profile-card-info">
2182 <div class="profile-card-username">
2183 <a href="'.$this->url.'/index.php?a=profile&u='.$profile['username'].'" rel="loadpage"><span id="author'.$profile['idu'].$profile['username'].'"></span><span id="time'.$profile['idu'].$profile['username'].'"></span><div class="cover-text-container">'.realName($profile['username'], $profile['first_name'], $profile['last_name']).''.(($this->getProStatus($profile['idu'])) ? '<img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/pro.png" title="'.$LNG['pro_user'].'" />' : '').'</div></a>
2184 </div>
2185 <div class="profile-card-location">
2186 '.((location($profile['country'], $profile['city'])) ? location($profile['country'], $profile['city']) : '').'
2187 </div>
2188 </div>
2189 <div class="profile-card-buttons">'.(($count) ? '<a href="'.$this->url.'/index.php?a=profile&u='.$profile['username'].'" rel="loadpage"><div class="profile-card-stats" title="'.$count.' '.$LNG['tracks'].'"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/tracks_small.png" />'.$count.'</div></a>' : '').(($subscribersList[1]) ? '<a href="'.$this->url.'/index.php?a=profile&u='.$profile['username'].'&r=subscribers" rel="loadpage"><div class="profile-card-stats" title="'.$subscribersList[1].' '.$LNG['subscribers'].'"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/followers.png" />'.$subscribersList[1].'</div></a>' : '').''.((!empty($subscribe)) ? '<div class="profile-card-buttons-container"><div id="subscribe'.$profile['idu'].'">'.$subscribe.'</div>'.$this->chatButton($profile['idu'], $profile['username'], 1).'</div>' : '').'</div>
2190 ';
2191 return $card;
2192 }
2193
2194 function fetchProfileInfo($profile) {
2195 global $LNG, $CONF;
2196
2197 // Array: database column name => url model
2198 $social = array(
2199 'website' => '%s',
2200 'facebook' => 'http://facebook.com/%s',
2201 'gplus' => 'http://plus.google.com/%s',
2202 'twitter' => 'http://twitter.com/%s',
2203 'youtube' => 'http://youtube.com/%s',
2204 'soundcloud' => 'https://soundcloud.com/%s',
2205 'myspace' => 'http://myspace.com/%s',
2206 'lastfm' => 'http://last.fm/user/%s',
2207 'vimeo' => 'https://vimeo.com/%s',
2208 'tumblr' => 'http://%s.tumblr.com'
2209 );
2210
2211 $info = '<div class="sidebar-container widget-about"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['profile_about'].(($this->username == $profile['username']) ? '<div class="sidebar-header-extra"><a href="'.$this->url.'/index.php?a=settings" rel="loadpage">'.$LNG['edit'].'</a></div>' : '').'</div> '.((!empty($profile['description'])) ? '<div class="sidebar-description">'.$profile['description'].'</div>' : '').'<div class="sidebar-social-container">';
2212
2213 foreach($social as $value => $url) {
2214 $info .= ((!empty($profile[$value])) ? '<div class="social-icon-container"><div class="social-icon-padding"><a href="'.sprintf($url, $profile[$value]).'" target="_blank" rel="nofllow" title="'.(($value == 'website') ? $LNG['profile_view_site'] : sprintf($LNG['profile_view_social'], ucfirst($value))).'"><div class="social-icon '.$value.'-icon"></div></a></div></div>' : '');
2215 }
2216
2217 $info .= '</div></div></div>';
2218
2219 return $info;
2220 }
2221
2222 function checkNewNotifications($limit, $type = null, $for = null, $ln = null, $cn = null, $fn = null, $dn = null) {
2223 global $LNG, $CONF;
2224 // $ln, $cn, $fn, $dn holds the filters for the notifications
2225 // Type 0: Just check for and show the new notification alert
2226 // Type 1: Return the last X notifications from each category. (Drop Down Notifications)
2227 // Type 2: Return the latest X notifications (read and unread) (Notifications Page)
2228
2229 // For 0: Returns the Global Notifications
2230 // For 1: Return results for the Chat Messages Notifications (Drop Down)
2231 // For 2: Return Chat Messages results for the Notifications Page
2232
2233 // Start checking for new notifications
2234 if(!$type) {
2235
2236 // Check for new likes events
2237 if($ln) {
2238 $checkLikes = $this->db->query(sprintf("SELECT `id` FROM `notifications` WHERE `to` = '%s' AND `from` <> '%s' AND `type` = '2' AND `read` = '0'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id)));
2239
2240 $lc = $checkLikes->num_rows;
2241 }
2242
2243 // Check for new comments events
2244 if($cn) {
2245 $checkComments = $this->db->query(sprintf("SELECT `id` FROM `notifications` WHERE `to` = '%s' AND `from` <> '%s' AND `type` = '1' AND `read` = '0'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id)));
2246
2247 // If any, return 1 (show notification)
2248 $cc = $checkComments->num_rows;
2249 }
2250
2251 // Check for new friend additions
2252 if($fn) {
2253 $checkFriends = $this->db->query(sprintf("SELECT `id` FROM `notifications` WHERE `to` = '%s' AND `from` <> '%s' AND `type` = '4' AND `read` = '0'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id)));
2254
2255 // If any, return 1 (show notification)
2256 $fc = $checkFriends->num_rows;
2257 }
2258
2259 if($for) {
2260 if($dn) {
2261 $checkChats = $this->db->query(sprintf("SELECT `id` FROM `chat` WHERE `to` = '%s' AND `read` = '0'", $this->db->real_escape_string($this->id)));
2262
2263 // If any, return 1 (show notification)
2264 $dc = $checkChats->num_rows;
2265 }
2266 }
2267
2268 $output = array('response' => array('global' => $lc + $cc + $fc, 'messages' => $dc));
2269 return json_encode($output);
2270 } else {
2271 // Define the arrays that holds the values (prevents the array_merge to fail, when one or more options are disabled)
2272 $likes = array();
2273 $comments = array();
2274 $friends = array();
2275 $chats = array();
2276
2277 if($type) {
2278 // Get the events and display all unread messages [applies only to the drop down widgets]
2279 if($for == 2 && $type !== 2 || !$for && $type !== 2) {
2280 if($ln) {
2281 // Check for new likes events
2282 $checkLikes = $this->db->query(sprintf("SELECT * FROM `notifications`,`users` WHERE `notifications`.`from` = `users`.`idu` AND `notifications`.`to` = '%s' and `notifications`.`from` <> '%s' AND `notifications`.`type` = '2' AND `notifications`.`read` = '0' ORDER BY `notifications`.`id` DESC", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id)));
2283 // Fetch the comments
2284 while($row = $checkLikes->fetch_assoc()) {
2285 $likes[] = $row;
2286 }
2287 }
2288
2289 if($cn) {
2290 // Check for new comments events
2291 $checkComments = $this->db->query(sprintf("SELECT * FROM `notifications`,`users` WHERE `notifications`.`from` = `users`.`idu` AND `notifications`.`to` = '%s' and `notifications`.`from` <> '%s' AND `notifications`.`type` = '1' AND `notifications`.`read` = '0' ORDER BY `notifications`.`id` DESC", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id)));
2292
2293 // Fetch the comments
2294 while($row = $checkComments->fetch_assoc()) {
2295 $comments[] = $row;
2296 }
2297 }
2298
2299 if($fn) {
2300 // Check for new messages events
2301 $checkFriends = $this->db->query(sprintf("SELECT * FROM `notifications`,`users` WHERE `notifications`.`from` = `users`.`idu` AND `notifications`.`to` = '%s' and `notifications`.`from` <> '%s' AND `notifications`.`type` = '4' AND `notifications`.`read` = '0' ORDER BY `notifications`.`id` DESC", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id)));
2302 // Fetch the messages
2303 while($row = $checkFriends->fetch_assoc()) {
2304 $friends[] = $row;
2305 }
2306 }
2307
2308 if($for == 2) {
2309 if($dn) {
2310 // Check for new messages events
2311 $checkChats = $this->db->query(sprintf("SELECT * FROM (SELECT * FROM `chat`,`users` WHERE `chat`.`to` = '%s' AND `chat`.`read` = '0' AND `chat`.`from` = `users`.`idu` ORDER BY `id` DESC) as x GROUP BY `from`", $this->db->real_escape_string($this->id)));
2312 // Fetch the chat
2313 while($row = $checkChats->fetch_assoc()) {
2314 $chats[] = $row;
2315 }
2316 }
2317 }
2318 }
2319 // Return the unread messages for drop-down messages notifications (excludes $for 2 and $type 2)
2320 elseif($type !== 2 && $for == 1) {
2321 if($dn) {
2322 // Check for new messages events
2323 $checkChats = $this->db->query(sprintf("SELECT * FROM (SELECT * FROM `chat`,`users` WHERE `chat`.`to` = '%s' AND `chat`.`read` = '0' AND `chat`.`from` = `users`.`idu` ORDER BY `id` DESC) as x GROUP BY `from`", $this->db->real_escape_string($this->id)));
2324 // Fetch the chat
2325 while($row = $checkChats->fetch_assoc()) {
2326 $chats[] = $row;
2327 }
2328 }
2329 }
2330
2331 // If there are no new (unread) notifications (for the drop-down wdigets), get the lastest notifications
2332 if(!$for) {
2333 // Verify for the drop-down notifications
2334 if(empty($likes) && empty($comments) && empty($friends) || $type == 2) {
2335 $all = 1;
2336 }
2337 }
2338 // For the Notifications Page
2339 elseif($for == 2 && $type == 2) {
2340 // Verify for the notifications page
2341 $all = 1;
2342 }
2343
2344 if($all) {
2345 // LR: Enable limit rows when there are unread messages
2346 $lr = 1;
2347 if($ln) {
2348 $checkLikes = $this->db->query(sprintf("SELECT * FROM `notifications`,`users` WHERE `notifications`.`from` = `users`.`idu` AND `notifications`.`to` = '%s' and `notifications`.`from` <> '%s' AND `notifications`.`type` = '2' ORDER BY `notifications`.`id` DESC LIMIT %s", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id), $limit));
2349
2350 while($row = $checkLikes->fetch_assoc()) {
2351 $likes[] = $row;
2352 }
2353 }
2354
2355 if($cn) {
2356 $checkComments = $this->db->query(sprintf("SELECT * FROM `notifications`,`users` WHERE `notifications`.`from` = `users`.`idu` AND `notifications`.`to` = '%s' and `notifications`.`from` <> '%s' AND `notifications`.`type` = '1' ORDER BY `notifications`.`id` DESC LIMIT %s", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id), $limit));
2357
2358 while($row = $checkComments->fetch_assoc()) {
2359 $comments[] = $row;
2360 }
2361 }
2362
2363 if($fn) {
2364 $checkFriends = $this->db->query(sprintf("SELECT * FROM `notifications`,`users` WHERE `notifications`.`from` = `users`.`idu` AND `notifications`.`to` = '%s' and `notifications`.`from` <> '%s' AND `notifications`.`type` = '4' ORDER BY `notifications`.`id` DESC LIMIT %s", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id), $limit));
2365
2366 while($row = $checkFriends->fetch_assoc()) {
2367 $friends[] = $row;
2368 }
2369 }
2370
2371 if($for == 2) {
2372 if($dn) {
2373 $checkChats = $this->db->query(sprintf("SELECT * FROM (SELECT * FROM `chat`,`users` WHERE `chat`.`to` = '%s' AND `chat`.`from` = `users`.`idu` ORDER BY `id` DESC) as x GROUP BY `from` LIMIT %s", $this->db->real_escape_string($this->id), $limit));
2374
2375 while($row = $checkChats->fetch_assoc()) {
2376 $chats[] = $row;
2377 }
2378 }
2379 }
2380
2381 // If there are no latest notifications
2382 if($for == 2) {
2383 // Verify for the notifications page
2384 if(empty($likes) && empty($comments) && empty($friends) && empty($chats)) {
2385 return '<div class="notification-row"><div class="notification-padding">'.$LNG['no_notifications'].'</a></div></div><div class="notification-row"><div class="notification-padding"><a href="'.$this->url.'/index.php?a=settings&b=notifications" rel="loadpage">'.$LNG['notifications_settings'].'</a></div></div>';
2386 }
2387 } else {
2388 // Verify for the drop-down notifications
2389 if(empty($likes) && empty($comments) && empty($friends)) {
2390 return '<div class="notification-row"><div class="notification-padding">'.$LNG['no_notifications'].'</a></div></div>';
2391 }
2392 }
2393 }
2394 }
2395
2396 // Add the types into the recursive array results
2397 $x = 0;
2398 foreach($likes as $like) {
2399 $likes[$x]['event'] = 'like';
2400 $x++;
2401 }
2402 $y = 0;
2403 foreach($comments as $comment) {
2404 $comments[$y]['event'] = 'comment';
2405 $y++;
2406 }
2407 $a = 0;
2408 foreach($friends as $friend) {
2409 $friends[$a]['event'] = 'friend';
2410 $a++;
2411 }
2412 $b = 0;
2413 foreach($chats as $chat) {
2414 $chats[$b]['event'] = 'chat';
2415 $b++;
2416 }
2417
2418 $array = array_merge($likes, $comments, $friends, $chats);
2419
2420 // Sort the array
2421 usort($array, 'sortDateAsc');
2422
2423 $i = 0;
2424 foreach($array as $value) {
2425 if($i == $limit && $lr == 1) break;
2426 $time = $value['time']; $b = '';
2427 if($this->time == '0') {
2428 $time = date("c", strtotime($value['time']));
2429 } elseif($this->time == '2') {
2430 $time = $this->ago(strtotime($value['time']));
2431 } elseif($this->time == '3') {
2432 $date = strtotime($value['time']);
2433 $time = date('Y-m-d', $date);
2434 $b = '-standard';
2435 }
2436 $events .= '<div class="notification-row'.(($value['read'] == 0 && $value['event'] == 'chat') ? ' notification-unread' : '').'"><div class="notification-padding">';
2437 if($value['event'] == 'like') {
2438 $events .= '<div class="notification-image"><a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'" rel="loadpage"><img class="notifications" src='.$this->url.'/thumb.php?src='.$value['image'].'&t=a&w=50&h=50" /></a></div><div class="notification-text"><a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'">'.sprintf($LNG['new_like_notification'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name']), $this->url.'/index.php?a=track&id='.$value['parent']).'.<br /><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/like_n.png" width="17" height="17" /> <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span></div>';
2439 } elseif($value['event'] == 'comment') {
2440 $events .= '<div class="notification-image"><a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'" rel="loadpage"><img class="notifications" src='.$this->url.'/thumb.php?src='.$value['image'].'&t=a&w=50&h=50" /></a></div><div class="notification-text">'.sprintf($LNG['new_comment_notification'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name']), $this->url.'/index.php?a=track&id='.$value['parent'].'#'.$value['child']).'.<br /><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/comment_n.png" width="17" height="17" /> <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span></div>';
2441 } elseif($value['event'] == 'friend') {
2442 $events .= '<div class="notification-image"><a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'" rel="loadpage"><img class="notifications" src='.$this->url.'/thumb.php?src='.$value['image'].'&t=a&w=50&h=50" /></a></div><div class="notification-text">'.sprintf($LNG['new_friend_notification'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name'])).'.<br /><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/friendships_n.png" width="17" height="17" /> <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span></div>';
2443 } elseif($value['event'] == 'chat') {
2444 $events .= '<div class="notification-image"><a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'" rel="loadpage"><img class="notifications" src='.$this->url.'/thumb.php?src='.$value['image'].'&t=a&w=50&h=50" /></a></div><div class="notification-text">'.sprintf($LNG['new_chat_notification'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name']), $this->url.'/index.php?a=messages&u='.$value['username'].'&id='.$value['idu']).'.<br /><span class="chat-snippet">'.$this->parseMessage(substr($value['message'], 0, 45)).'...</span><br /><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/chat_n.png" width="17" height="17" /> <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span></div>';
2445 }
2446 $events .= '</div></div>';
2447 $i++;
2448 }
2449
2450 if(!$for) {
2451 // Mark global notifications as read
2452 $this->db->query("UPDATE `notifications` SET `read` = '1', `time` = `time` WHERE `to` = '{$this->id}' AND `read` = '0'");
2453 }
2454 // Update when the for is set, and it's not viewed from the Notifications Page
2455 elseif($type !== 2) {
2456 // Mark chat messages notifications as read
2457 $this->db->query("UPDATE `chat` SET `read` = '1', `time` = `time` WHERE `to` = '{$this->id}' AND `read` = '0'");
2458 }
2459 // return the result
2460 return $events;
2461 }
2462
2463 // If no notification was returned, return 0
2464 }
2465
2466 function getCategories() {
2467 $query = $this->db->query("SELECT `name` FROM `categories`");
2468
2469 while($row = $query->fetch_assoc()) {
2470 $rows[] = $row;
2471 }
2472
2473 // Flat the array
2474 foreach($rows as $category) {
2475 $categories[] = $category['name'];
2476 }
2477
2478 return $categories;
2479 }
2480
2481 function fetchCategory($categories) {
2482 $categories = explode(',', $categories);
2483
2484 // If the tag is viewed from a filter page, set it to the filter's name
2485 if($_GET['a'] == 'explore' && !empty($_GET['filter']) && $_GET['filter'] !== 'popular music' && $_GET['filter'] !== 'liked music') {
2486 return strtolower($_GET['filter']);
2487 }
2488
2489 $list = array_map('strtolower', $this->categories);
2490
2491 // If a tag is matched with one of the categories
2492 foreach($categories as $category) {
2493 if(in_array(strtolower($category), $list)) {
2494 return $category;
2495 }
2496 }
2497
2498 // Return the first tag
2499 return $categories[0];
2500 }
2501
2502 function chatButton($id, $username, $z = null) {
2503 // Profile: Returns the current row username
2504 // Z: A switcher for the sublist CSS class
2505 global $LNG;
2506 if($z == 1) {
2507 $style = ' subslist_message';
2508 }
2509 if(!empty($this->username) && $this->username !== $username) {
2510 return '<a href="'.$this->url.'/index.php?a=messages&u='.$username.'&id='.$id.'" title="'.$LNG['send_message'].'" rel="loadpage"><div class="message_btn'.$style.'"></div></a>';
2511 }
2512 }
2513
2514 function getSubscribe($type = null, $list = null, $z = null) {
2515 global $LNG;
2516 // Type 0: Just show the button
2517 // Type 1: Go trough the add friend query
2518 // List: Array (for the dedicated profile page list)
2519 // Z: A switcher for the sublist CSS class
2520 if($list) {
2521 $profile = $list;
2522 } else {
2523 $profile = $this->profile_data;
2524 }
2525 if($z == 1) {
2526 $style = ' subslist';
2527 }
2528
2529 // Avoid queries search for abuse avoid, Repro: 5 users follows $X, then $X goes private, the button to unfollow remains active to offer the possibility to unfollow
2530
2531 // Verify if the profile is completely private
2532 if($profile['private'] == 1) {
2533 // Run the query only if the user is logged-in
2534 if($this->id) {
2535 $avoid = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `leader` = '%s' AND `subscriber` = '%s'", $this->db->real_escape_string($profile['idu']), $this->db->real_escape_string($this->id)));
2536 }
2537 if($avoid->num_rows == 0) {
2538 if($this->username == $profile['username']) {
2539 // Set a variable if the profile is private and the one who views the profile is the owner, then show settings button
2540 $a = 1;
2541 } else {
2542 return false;
2543 }
2544 }
2545 } elseif($profile['private'] == 2) {
2546 if($this->id) {
2547 $avoid = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `leader` = '%s' AND `subscriber` = '%s'", $this->db->real_escape_string($profile['idu']), $this->db->real_escape_string($this->id)));
2548
2549 // If the user have semi-private profile, hide the add button
2550 $result = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `subscriber` = '%s' AND `leader` = '%s'", $this->db->real_escape_string($profile['idu']), $this->db->real_escape_string($this->id)));
2551 }
2552 if($result->num_rows == 0 && $avoid->num_rows == 0) {
2553 if($this->username == $profile['username']) {
2554 // Set a variable if the profile is semi-private and the one who views the profile is the owner, then show settings button
2555 $a = 1;
2556 } else {
2557 return false;
2558 }
2559 }
2560 }
2561
2562 // Verify if the username is logged in, and it's not the same with the viewed profile
2563 if(!empty($this->username) && $this->username !== $profile['username']) {
2564 if($type) {
2565 $result = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `subscriber` = '%s' AND `leader` = '%s'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($profile['idu'])));
2566
2567 // If a relationship already exist, then remove
2568 if($result->num_rows) {
2569 $result = $this->db->query(sprintf("DELETE FROM `relations` WHERE `subscriber` = '%s' AND `leader` = '%s'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($profile['idu'])));
2570 $insertNotification = $this->db->query(sprintf("DELETE FROM `notifications` WHERE `from` = '%s' AND `to` = '%s' AND `type` = '4'", $this->db->real_escape_string($this->id), $profile['idu']));
2571 } else {
2572 $result = $this->db->query(sprintf("INSERT INTO `relations` (`subscriber`, `leader`, `time`) VALUES ('%s', '%s', CURRENT_TIMESTAMP)", $this->db->real_escape_string($this->id), $this->db->real_escape_string($profile['idu'])));
2573 $insertNotification = $this->db->query(sprintf("INSERT INTO `notifications` (`from`, `to`, `type`, `read`) VALUES ('%s', '%s', '4', '0')", $this->db->real_escape_string($this->id), $profile['idu']));
2574
2575 if($this->email_new_friend) {
2576 // If user has emails on new friendships enabled
2577 if($profile['email_new_friend']) {
2578 // Send e-mail
2579 sendMail($profile['email'], sprintf($LNG['ttl_new_friend_email'], $this->username), sprintf($LNG['new_friend_email'], realName($profile['username'], $profile['first_name'], $profile['last_name']), $this->url.'/index.php?a=profile&u='.$this->username, $this->username, $this->title, $this->url.'/index.php?a=settings&b=notifications'), $this->email);
2580 }
2581 }
2582 }
2583 }
2584 } elseif($this->username == $profile['username'] || $a == 1) {
2585 return '<a href="'.$this->url.'/index.php?a=settings&b=avatar" rel="loadpage" title="'.$LNG['edit_profile_cover'].'"><div class="edit_profile_btn'.$style.'"></div></a>';
2586 } else {
2587 return false;
2588 }
2589
2590 $result = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `subscriber` = '%s' AND `leader` = '%s'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($profile['idu'])));
2591 if($result->num_rows) {
2592 return '<div class="subscribe_btn unsubscribe'.$style.'" title="'.$LNG['remove_friend'].'" onclick="subscribe('.$profile['idu'].', 1'.(($z == 1) ? ', 1' : '').')"></div>';
2593 } else {
2594 return '<div class="subscribe_btn'.$style.'" title="'.$LNG['add_friend'].'" onclick="subscribe('.$profile['idu'].', 1'.(($z == 1) ? ', 1' : '').')"></div>';
2595 }
2596 }
2597
2598 function showError($error, $type = null) {
2599 global $LNG;
2600 // Type 1: return only the description
2601 // Type 0: return title and description
2602
2603 if($type) {
2604 $message = '<div class="message-inner">'.$LNG["$error"].'</div>';
2605 } else {
2606 $message = '<div class="private-profile-content"><div class="page-header">'.$LNG[$error.'_ttl'].'</div><div class="message-inner">'.$LNG["$error"].'</div></div>';
2607 }
2608 return array($message, 1);
2609 }
2610
2611 function verifyRelationship($user_id, $profile_id, $type) {
2612 // Type 0: The viewed profile subscribed to the logged in username
2613 // Type 1: The logged in username is a subscriber of the viewed profile
2614 if($type == 0) {
2615 $result = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `subscriber` = '%s' AND `leader` = '%s'", $this->db->real_escape_string($profile_id), $this->db->real_escape_string($user_id)));
2616 } elseif($type == 1) {
2617 $result = $this->db->query(sprintf("SELECT * FROM `relations` WHERE `leader` = '%s' AND `subscriber` = '%s'", $this->db->real_escape_string($profile_id), $this->db->real_escape_string($user_id)));
2618 }
2619
2620 // If the logged in username is the same with the viewed profile
2621 if($user_id == $profile_id) {
2622 return 2;
2623 }
2624
2625 // If a relationship exist
2626 elseif($result->num_rows) {
2627 return 1;
2628 } else {
2629 return 0;
2630 }
2631 }
2632
2633 function validateTrack($values, $type, $num) {
2634 // Type 0: For Edit Page
2635 // Type 1: For Upload Page
2636
2637 // Validate Release date
2638 if(!empty($values['day']) && !empty($values['month']) && !empty($values['year'])) {
2639 $values['release'] = date("Y-m-d", mktime(0, 0, 0, $values['month'], $values['day'], $values['year']));
2640 } else {
2641 $values['release'] = 0;
2642 }
2643
2644 // Validate License
2645 if($values['license']) {
2646 if($values['license-nc'] != 0) {
2647 $values['license-nc'] = 1;
2648 }
2649
2650 // License Types
2651 $licenseTypes = array(0, 1, 2);
2652
2653 if(!in_array($values['license-nd-sa'], $licenseTypes)) {
2654 $values['license-nd-sa'] = 0;
2655 }
2656
2657 $values['license'] = '1'.$values['license-nc'].$values['license-nd-sa'];
2658 } else {
2659 $value['license'] = 0;
2660 }
2661
2662 // Unset unwated fields
2663 unset($values['day']);
2664 unset($values['month']);
2665 unset($values['year']);
2666 unset($values['license-nc']);
2667 unset($values['license-nd-sa']);
2668
2669 if($type) {
2670 $allowedColumns = array('title', 'description', 'name', 'art', 'tag', 'buy', 'record', 'release', 'license', 'size', 'download', 'public');
2671 $values['title'] = $values['title'][$num];
2672 } else {
2673 $allowedColumns = array('title', 'description', 'art', 'tag', 'buy', 'record', 'release', 'license', 'download', 'public');
2674 $values['title'] = $values['title'][0];
2675 }
2676
2677 // Strip unwated columns
2678 foreach($values as $key => $value) {
2679 if(!in_array($key, $allowedColumns)) {
2680 unset($values[$key]);
2681 }
2682 }
2683
2684 // Validate Description
2685 $values['description'] = htmlspecialchars(trim(nl2clean($values['description'])));
2686
2687 $desclimit = 5000;
2688 if(strlen($values['description']) > $desclimit) {
2689 $error[] = array(6, $desclimit);
2690 }
2691
2692 // Validate URL
2693 if(!filter_var($values['buy'], FILTER_VALIDATE_URL) && !empty($values['buy'])) {
2694 $error[] = array(7);
2695 }
2696
2697 // Validate Tags
2698 $tags = array_filter(explode(',', $values['tag']));
2699
2700 foreach($tags as $key => $tag) {
2701 $tag = strtolower($tag);
2702 // Array { Replace any unwated characters, Replace consecutive "-" characters }
2703 $tag = preg_replace(array('/[^[:alnum:]-]/u', '/--+/'), array('', '-'), $tag);
2704 // Remove tags that has only "-" characters
2705 if($tag == '-') {
2706 unset($tags[$key]);
2707 } else {
2708 $tags[$key] = $tag;
2709 }
2710 }
2711
2712 // Remove duplicated tags
2713 $tags = array_unique($tags);
2714 $taglimit = 60;
2715 $tagmax = 30;
2716 $tagmin = 1;
2717 if(count($tags) > $tagmax) {
2718 $error[] = array(8, $tagmax);
2719 } elseif(count($tags) < $tagmin) {
2720 $error[] = array(9, $tagmin);
2721 }
2722
2723 // Check for tags length
2724 foreach($tags as $tag) {
2725 if(strlen($tag) >= $taglimit) {
2726 $error[] = array(12, $taglimit);
2727 }
2728 }
2729
2730 $values['tag'] = implode(',', $tags).',';
2731
2732 // Validate Title
2733 $titlelimit = 100;
2734 if(empty($values['title'])) {
2735 $error[] = array(10);
2736 } elseif(strlen($values['title']) > $titlelimit) {
2737 $error[] = array(11, $titlelimit);
2738 } else {
2739 $values['title'] = htmlspecialchars(trim(nl2clean($values['title'])));
2740 }
2741
2742 // Validate Download
2743 if($values['download'] != 0) {
2744 $values['download'] = 1;
2745 }
2746
2747 // Validate Privacy
2748 if($values['public'] != 0) {
2749 $values['public'] = 1;
2750 }
2751
2752 // Validate the files to be uploaded
2753 if(empty($error)) {
2754 $tpath = __DIR__ .'/../uploads/tracks/';
2755 $mpath = __DIR__ .'/../uploads/media/';
2756
2757 if($type) {
2758 if(isset($_FILES['track']['name'])) {
2759 // Get the total uploaded size
2760 $query = $this->db->query(sprintf("SELECT (SELECT SUM(`size`) FROM `tracks` WHERE `uid` = '%s') as upload_size", $this->db->real_escape_string($this->id)));
2761 $result = $query->fetch_assoc();
2762
2763 $ext = pathinfo($_FILES['track']['name'][$num], PATHINFO_EXTENSION);
2764 $size = $_FILES['track']['size'][$num];
2765 $fullname = $_FILES['track']['name'][$num];
2766 $allowedExt = explode(',', $this->track_format);
2767 $maxsize = $this->track_size;
2768
2769 // Validate the total upload size allowed
2770 if(($result['upload_size'] + $size) > $this->track_size_total) {
2771 $error[] = array(0, saniscape($values['title']));
2772 }
2773
2774 // Get file type validation
2775 $track = validateFile($_FILES['track']['tmp_name'][$num], $_FILES['track']['name'][$num], $allowedExt, 1);
2776
2777 if($track['valid'] && $size < $maxsize && $size > 0) {
2778 $t_tmp_name = $_FILES['track']['tmp_name'][$num];
2779 $name = pathinfo($_FILES['track']['name'][$num], PATHINFO_FILENAME);
2780 $size = $_FILES['track']['size'][$num];
2781 $tName = mt_rand().'_'.mt_rand().'_'.mt_rand().'.'.$this->db->real_escape_string($ext);
2782
2783 // Send the track name in array format to the function
2784 $values['name'] = $tName;
2785 $values['size'] = $size;
2786
2787 $t_upload = true;
2788 } elseif($_FILES['track']['name'][$num] == '') {
2789 // If the file size is higher than allowed or 0
2790 $error[] = array(1);
2791 }
2792 if(!empty($ext) && ($size > $maxsize || $size == 0)) {
2793 // If the file size is higher than allowed or 0
2794 $error[] = array(2, saniscape($values['title']), fsize($maxsize));
2795 }
2796 if(!empty($ext) && !$track['valid']) {
2797 // If the file format is not allowed
2798 $error[] = array(3, saniscape($values['title']), implode(', ', $allowedExt));
2799 }
2800 }
2801 }
2802
2803 if(empty($GLOBALS['multiart'])) {
2804 if(isset($_FILES['art']['name'])) {
2805 foreach($_FILES['art']['error'] as $key => $err) {
2806 $ext = pathinfo($_FILES['art']['name'][$key], PATHINFO_EXTENSION);
2807 $size = $_FILES['art']['size'][$key];
2808 $allowedExt = explode(',', $this->art_format);
2809 $maxsize = $this->art_size;
2810
2811 // Get file type validation
2812 $image = validateFile($_FILES['art']['tmp_name'][$key], $_FILES['art']['name'][$key], $allowedExt, 0);
2813
2814 if($image['valid'] && $size < $maxsize && $size > 0 && !empty($image['width']) && !empty($image['height'])) {
2815 $m_tmp_name = $_FILES['art']['tmp_name'][$key];
2816 $name = pathinfo($_FILES['art']['name'][$key], PATHINFO_FILENAME);
2817 $fullname = $_FILES['art']['name'][$key];
2818 $size = $_FILES['art']['size'][$key];
2819
2820 // If there's no error during the track's upload
2821 if(empty($error)) {
2822 // Generate the file name & store it into a super global to check when multi upload
2823 $mName = $GLOBALS['multiart'] = mt_rand().'_'.mt_rand().'_'.mt_rand().'.'.$this->db->real_escape_string($ext);
2824 }
2825
2826 // Delete the old image when editing the track
2827 if(!$type) {
2828 $query = $this->db->query(sprintf("SELECT `art` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($_GET['id'])));
2829 $result = $query->fetch_assoc();
2830 deleteImages(array($result['art']), 2);
2831 }
2832
2833 // Send the image name in array format to the function
2834 $values['art'] = $mName;
2835
2836 $m_upload = true;
2837 } elseif($_FILES['art']['name'][$key] == '') {
2838 // If no file is selected
2839 if($type) {
2840 $values['art'] = 'default.png';
2841 } else {
2842 // If the cover artwork is not selected, unset the image so that it doesn't update the current one
2843 unset($values['art']);
2844 }
2845 }
2846 if(!empty($ext) && ($size > $maxsize || $size == 0)) {
2847 // If the file size is higher than allowed or 0
2848 $error[] = array(4, fsize($maxsize));
2849 }
2850 if(!empty($ext) && !$image['valid']) {
2851 // If the file format is not allowed
2852 $error[] = array(5, implode(', ', $allowedExt));
2853 }
2854 }
2855 }
2856 } else {
2857 // Generate a new file name
2858 $ext = pathinfo($GLOBALS['multiart'], PATHINFO_EXTENSION);
2859 $finalName = mt_rand().'_'.mt_rand().'_'.mt_rand().'.'.$this->db->real_escape_string($ext);
2860 // Copy the previous track image
2861 copy($mpath.$GLOBALS['multiart'], $mpath.$finalName);
2862 // Store the new file name
2863 $values['art'] = $finalName;
2864 }
2865 }
2866
2867 if(!empty($error)) {
2868 return array(0, $error);
2869 } else {
2870 if($t_upload) {
2871 // Move the file into the uploaded folder
2872 move_uploaded_file($t_tmp_name, $tpath.$tName);
2873 }
2874 if($m_upload) {
2875 // Move the file into the uploaded folder
2876 move_uploaded_file($m_tmp_name, $mpath.$mName);
2877 }
2878 return array(1, $values);
2879 }
2880 }
2881
2882 function updateTrack($values, $type) {
2883 // Type 0: For Edit Page
2884 // Type 1: For Upload Page
2885 global $LNG;
2886 $x = 0;
2887 foreach($values['title'] as $key => $val) {
2888 // Validate the track
2889 $validate = $this->validateTrack($values, $type, $key);
2890
2891 // If there's an error
2892 if(!$validate[0]) {
2893 // Display the errors
2894 foreach($validate[1] as $error) {
2895 $err .= notificationBox('error', sprintf($LNG["{$error[0]}_upload_err"], ((isset($error[1])) ? $error[1] : ''), ((isset($error[2])) ? $error[2] : '')));
2896 }
2897 // Return the error (edit page)
2898 if(!$type) {
2899 return $err;
2900 }
2901 }
2902
2903 // If the track is validated
2904 if($validate[0]) {
2905 // Prepare the values
2906 foreach($validate[1] as $column => $value) {
2907 if($type) {
2908 $columns[$column] = $this->db->real_escape_string($value);
2909 } else {
2910 $columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value));
2911 }
2912 }
2913 $column_list = implode(',', $columns);
2914
2915 if($type) {
2916 $this->db->query(sprintf("INSERT INTO `tracks` (`uid`, `title`, `description`, `name`, `tag`, `art`, `buy`, `record`, `release`, `license`, `size`, `download`, `public`, `time`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', CURRENT_TIMESTAMP)", $this->db->real_escape_string($this->id), $columns['title'], $columns['description'], $columns['name'], $columns['tag'], $columns['art'], $columns['buy'], $columns['record'], $columns['release'], $columns['license'], $columns['size'], $columns['download'], $columns['public']));
2917 $x++;
2918 } else {
2919 $stmt = $this->db->prepare(sprintf("UPDATE `tracks` SET `time` = `time`, %s WHERE `uid` = '%s' AND `id` = '%s'", $column_list, $this->id, $this->db->real_escape_string($_GET['id'])));
2920
2921 // Execute the statement
2922 $stmt->execute();
2923
2924 // Save the affected rows
2925 $affected = $stmt->affected_rows;
2926
2927 // Close the statement
2928 $stmt->close();
2929
2930 if($affected) {
2931 if(!$type) {
2932 return notificationBox('success', $LNG["track_updated"]);
2933 }
2934 }
2935 return notificationBox('info', $LNG["nothing_changed"]);
2936 }
2937 }
2938 }
2939 if($x > 0) {
2940 $query = $this->db->query(sprintf("SELECT * FROM `tracks` WHERE `uid` = '%s' ORDER BY `id` DESC LIMIT 0, %s", $this->db->real_escape_string($this->id), $x));
2941 while($row = $query->fetch_assoc()) {
2942 $err .= notificationBox('success', sprintf($LNG['track_uploaded'], $this->url.'/index.php?a=track&id='.$row['id'], $row['title']));
2943 }
2944 }
2945 return array($err, 1);
2946 }
2947
2948 function getTrackInfo($id, $type) {
2949 // Type 0: Return track title link and author permission
2950 // Type 1: Return track info
2951 $query = $this->db->query(sprintf("SELECT * FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
2952 $result = $query->fetch_assoc();
2953
2954 if($type) {
2955 return $result;
2956 } else {
2957 return array('<a href="'.$this->url.'/index.php?a=track&id='.$id.'" rel="loadpage">'.$result['title'].'</a>', (($this->id == $result['uid']) ? 1 : 0));
2958 }
2959 }
2960
2961 function getTrack($id) {
2962 // Obey the message privacy to the profile privacy and then to the message privacy
2963 $query = $this->db->query(sprintf("SELECT `idu`,`username`,`private`,`tag`, `tracks`.`public` as `public` FROM `tracks`, `users` WHERE `tracks`.`id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id)));
2964 $result = $query->fetch_assoc();
2965
2966 $relationship = $this->verifyRelationship($this->id, $result['idu'], 0);
2967
2968 // Store the current track's name for recommended tracks
2969 $this->track_tag = $result['tag'];
2970
2971 // Check if the track exist
2972 if($query->num_rows > 0) {
2973 // If the track is public
2974 // Check privacy
2975 switch($result['private']) {
2976 case 0:
2977 break;
2978 case 1:
2979 // Check if the username is not same with the profile
2980 if($this->id !== $result['idu']) {
2981 $x = 1;
2982 }
2983 break;
2984 case 2:
2985 // Check relationship
2986 if(!$relationship) {
2987 $x = 2;
2988 }
2989 break;
2990 }
2991 // If the track is private
2992 if($result['public'] == 0) {
2993 if($this->id !== $result['idu']) {
2994 $x = 1;
2995 }
2996 }
2997
2998 // Override any settings and grant admin permissions
2999 if($this->is_admin) {
3000 $x = 0;
3001 }
3002 }
3003
3004 // Get the track for track page
3005 $query = sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id));
3006
3007 if($x) {
3008 if($x == 2) {
3009 return $this->showError('track_hidden_2');
3010 } else {
3011 return $this->showError('track_hidden_1');
3012 }
3013 } elseif($result['public'] == 2) {
3014 return $this->showError('track_suspended_1');
3015 } else {
3016 return $this->getTracks($query, 'trackPage', null);
3017 }
3018 }
3019
3020 function getComments($id, $cid, $start, $type = null) {
3021 // Type 0: Get Comments
3022 // Type 1: Get last comment
3023 global $LNG;
3024 // The query to select the subscribed users
3025
3026 // If the $start value is 0, empty the query;
3027 if($start == 0) {
3028 $start = '';
3029 } else {
3030 // Else, build up the query
3031 $start = 'AND comments.id < \''.$this->db->real_escape_string($cid).'\'';
3032 }
3033
3034 if($type) {
3035 $query = sprintf("SELECT * FROM `comments`, `users` WHERE `uid` = '%s' AND `comments`.`uid` = `users`.`idu` ORDER BY `id` DESC LIMIT 0, 1", $this->db->real_escape_string($this->id));
3036 } else {
3037 $query = sprintf("SELECT * FROM comments, users WHERE comments.tid = '%s' AND comments.uid = users.idu %s ORDER BY comments.id DESC LIMIT %s", $this->db->real_escape_string($id), $start, ($this->c_per_page + 1));
3038 }
3039
3040 // check if the query was executed
3041 if($result = $this->db->query($query)) {
3042
3043 // Set the result into an array
3044 $rows = array();
3045 while($row = $result->fetch_assoc()) {
3046 $rows[] = $row;
3047 }
3048
3049 // Define the $comments variable;
3050 $comments = '';
3051
3052 // If there are more results available than the limit, then show the Load More Comments
3053 if(array_key_exists($this->c_per_page, $rows)) {
3054 $loadmore = 1;
3055
3056 if($type) {
3057 $loadmore = 0;
3058 }
3059 // Unset the last array element because it's not needed, it's used only to predict if the Load More Comments should be displayed
3060 unset($rows[$this->c_per_page]);
3061 }
3062
3063 foreach($rows as $comment) {
3064 // Define the time selected in the Admin Panel
3065 $time = $comment['time']; $b = '';
3066 if($this->time == '0') {
3067 $time = date("c", strtotime($comment['time']));
3068 } elseif($this->time == '2') {
3069 $time = $this->ago(strtotime($comment['time']));
3070 } elseif($this->time == '3') {
3071 $date = strtotime($comment['time']);
3072 $time = date('Y-m-d', $date);
3073 $b = '-standard';
3074 }
3075
3076 if($this->username == $comment['username']) { // If it's current username is the same with the current author
3077 $delete = '<a onclick="delete_the('.$comment['id'].', 0)" title="'.$LNG['delete_this_comment'].'"><div class="delete_btn"></div></a>';
3078 } elseif(empty($this->username)) { // If the user is not registered
3079 $delete = '';
3080 } else { // If the current username is not the same as the author
3081 $delete = '<a onclick="report_the('.$comment['id'].', 0)" title="'.$LNG['report_this_comment'].'"><div class="report_btn"></div></a>';
3082 }
3083
3084 // Variable which contains the result
3085 $comments .= '
3086 <div class="message-reply-container" id="comment'.$comment['id'].'">
3087 '.$delete.'
3088 <div class="message-reply-avatar">
3089 <a href="'.$this->url.'/index.php?a=profile&u='.$comment['username'].'" rel="loadpage"><img onmouseover="profileCard('.$comment['idu'].', '.$comment['id'].', 1, 0)" onmouseout="profileCard(0, 0, 1, 1);" onclick="profileCard(0, 0, 1, 1);" src="'.$this->url.'/thumb.php?src='.$comment['image'].'&t=a" /></a>
3090 </div>
3091 <div class="message-reply-message">
3092 <span class="message-reply-author"><a href="'.$this->url.'/index.php?a=profile&u='.$comment['username'].'" rel="loadpage">'.realName($comment['username'], $comment['first_name'], $comment['last_name']).'</a></span>
3093 <div class="list-time">
3094 (<div class="timeago'.$b.'" title="'.$time.'">
3095 '.$time.'
3096 </div>)
3097 </div>
3098 <div class="message-reply-content">'.$this->parseMessage($comment['message']).'</div>
3099 </div>
3100 <div class="delete_preloader" id="del_comment_'.$comment['id'].'"></div>
3101
3102 </div>';
3103 $message_id = $comment['tid'];
3104 $load_id = $comment['id'];
3105 }
3106
3107 if($loadmore) {
3108 $load = '<div class="load-more-comments" id="comments'.htmlentities($id, ENT_QUOTES).'"><div class="load_more"><a onclick="loadComments('.$message_id.', '.$load_id.', '.($start + $this->c_per_page).')" id="infinite-load">'.$LNG['load_more'].'</a></div></div>';
3109 }
3110
3111 // Close the query
3112 $result->close();
3113
3114 // Return the comments variable
3115 return $comments.$load;
3116 } else {
3117 return false;
3118 }
3119 }
3120
3121 function parseMessage($message) {
3122 global $LNG, $CONF;
3123
3124 // Parse links
3125 $parseUrl = preg_replace_callback('/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“â€â€˜â€™]))/', "parseCallback", $message);
3126
3127 // Parse @mentions and #hashtags
3128 $parsedMessage = preg_replace(array('/(^|[^a-z0-9_])@([a-z0-9_]+)/i', '/(^|[^a-z0-9_])#(\w+)/u'), array('$1<a href="'.$this->url.'/index.php?a=profile&u=$2" rel="loadpage">@$2</a>', '$1<a href="'.$this->url.'/index.php?a=explore&filter=$2" rel="loadpage">#$2</a>'), $parseUrl);
3129
3130 return $parsedMessage;
3131 }
3132
3133 function delete($id, $type) {
3134 // Type 0: Delete Comment
3135 // Type 1: Delete Track
3136 // Type 2: Delete Chat Message
3137
3138 // Prepare the statement
3139 if($type == 0) {
3140 $stmt = $this->db->prepare("DELETE FROM `comments` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `uid` = '{$this->db->real_escape_string($this->id)}'");
3141
3142 // Set $x variable to 1 if the delete query is for `comments`
3143 $x = 0;
3144 } elseif($type == 1) {
3145 // Get the current type (for images and tracks deletion)
3146 $query = $this->db->query(sprintf("SELECT `art`, `name` FROM `tracks` WHERE `id` = '%s' AND `uid` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($this->id)));
3147 $track = $query->fetch_assoc();
3148
3149 $stmt = $this->db->prepare("DELETE FROM `tracks` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `uid` = '{$this->db->real_escape_string($this->id)}'");
3150
3151 // Set $x variable to 1 if the delete query is for `tracks`
3152 $x = 1;
3153 } elseif($type == 2) {
3154 $stmt = $this->db->prepare("DELETE FROM `chat` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `from` = '{$this->db->real_escape_string($this->id)}'");
3155
3156 $x = 2;
3157 } elseif($type == 3) {
3158 $stmt = $this->db->prepare("DELETE FROM `playlists` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `by` = '{$this->db->real_escape_string($this->id)}'");
3159
3160 $x = 3;
3161 }
3162
3163 // Execute the statement
3164 $stmt->execute();
3165
3166 // Save the affected rows
3167 $affected = $stmt->affected_rows;
3168
3169 // Close the statement
3170 $stmt->close();
3171
3172 // If the tracks/comments table was affected
3173 if($affected) {
3174 // Deletes the Comments/Likes/Reports/Notifications/Playlists and Images if the Track was deleted
3175 if($x == 1) {
3176 $this->db->query("DELETE FROM `comments` WHERE `tid` = '{$this->db->real_escape_string($id)}'");
3177 $this->db->query("DELETE FROM `likes` WHERE `track` = '{$this->db->real_escape_string($id)}'");
3178 $this->db->query("DELETE FROM `reports` WHERE `track` = '{$this->db->real_escape_string($id)}' AND `parent` = '0'");
3179 $this->db->query("DELETE FROM `notifications` WHERE `parent` = '{$this->db->real_escape_string($id)}'");
3180 $this->db->query("DELETE FROM `playlistentries` WHERE `track` = '{$this->db->real_escape_string($id)}'");
3181
3182 // Execute the deleteMedia function
3183 deleteMedia($track['art'], $track['name']);
3184 } elseif($x == 0) {
3185 $this->db->query("DELETE FROM `reports` WHERE `post` = '{$this->db->real_escape_string($id)}' AND `parent` != '0'");
3186 $this->db->query("DELETE FROM `notifications` WHERE `child` = '{$this->db->real_escape_string($id)}' AND `type` = '1'");
3187 } elseif($x == 3) {
3188 $this->db->query("DELETE FROM `playlistentries` WHERE `playlist` = '{$this->db->real_escape_string($id)}'");
3189 }
3190 }
3191
3192 return ($affected) ? 1 : 0;
3193 }
3194
3195 function report($id, $type) {
3196 // Type 0: Comments
3197 // Type 1: Tracks
3198 global $LNG;
3199
3200 // Check if the Track exists
3201 if($type == 1) {
3202 $result = $this->db->query(sprintf("SELECT `id` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
3203 } else {
3204 $result = $this->db->query(sprintf("SELECT `id`, `tid`, `message` FROM `comments` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
3205 $parent = $result->fetch_array(MYSQLI_ASSOC);
3206 }
3207
3208 // If the Track/Comment exists
3209 if($result->num_rows) {
3210 $result->close();
3211
3212 // Get the report status, 0 = already exists * 1 = is safe
3213 if($type == 1) {
3214 $query = sprintf("SELECT `state`,`by` FROM `reports` WHERE `track` = '%s' AND `type` = '%s' AND `by` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($type), $this->db->real_escape_string($this->id));
3215 } else {
3216 $query = sprintf("SELECT `state` FROM `reports` WHERE `track` = '%s' AND `type` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($type));
3217 }
3218 $result = $this->db->query($query);
3219 $state = $result->fetch_assoc();
3220
3221 // If the report already exists
3222 if($result->num_rows) {
3223 // If the comment state is 0, then already exists
3224 if($state['state'] == 0) {
3225 return (($type == 1) ? notificationBox('info', $LNG["{$type}_already_reported"]) : $LNG["{$type}_already_reported"]);
3226 } elseif($state['state'] == 1) {
3227 if($type == 1) {
3228 if($state['by'] == $this->id) {
3229 return notificationBox('info', $LNG["{$type}_is_safe"]);
3230 }
3231 } else {
3232 return $LNG["{$type}_is_safe"];
3233 }
3234 } else {
3235 return (($type == 1) ? notificationBox('error', $LNG["{$type}_is_deleted"]) : $LNG["{$type}_is_deleted"]);
3236 }
3237 } else {
3238 if($type == 1) {
3239 $validate = $this->checkReportForm();
3240 if($validate) {
3241 return notificationBox('error', sprintf($LNG["{$validate[0]}"], $validate[1]));
3242 }
3243
3244 $stmt = $this->db->prepare(sprintf("INSERT INTO `reports` (`track`, `parent`, `content`, `by`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s')", $this->db->real_escape_string($id), ($parent['tid']) ? $parent['tid'] : 0, $this->db->real_escape_string(htmlspecialchars(trim(nl2clean($_POST['description']."\r\n\r\n[".$_POST['signature']."]")))), $this->db->real_escape_string($this->id), $this->db->real_escape_string($type)));
3245 } else {
3246 $stmt = $this->db->prepare(sprintf("INSERT INTO `reports` (`track`, `parent`, `content`, `by`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s')", $this->db->real_escape_string($id), ($parent['tid']) ? $parent['tid'] : 0, $this->db->real_escape_string($parent['message']), $this->db->real_escape_string($this->id), $this->db->real_escape_string($type)));
3247 }
3248
3249 // Execute the statement
3250 $stmt->execute();
3251
3252 // Save the affected rows
3253 $affected = $stmt->affected_rows;
3254
3255 // Close the statement
3256 $stmt->close();
3257
3258 // If the comment was added, return 1
3259 if($affected) {
3260 return (($type == 1) ? notificationBox('success', $LNG["{$type}_report_added"]) : $LNG["{$type}_report_added"]);
3261 } else {
3262 return (($type == 1) ? notificationBox('error', $LNG["{$type}_report_error"]) : $LNG["{$type}_report_error"]);
3263 }
3264 }
3265 } else {
3266 return $LNG["{$type}_not_exists"];
3267 }
3268 }
3269
3270 function checkReportForm() {
3271 if(strlen($_POST['description']) > 3000) {
3272 return array('rep_resc_error', 3000);
3273 }
3274
3275 if(!isset($_POST['report1']) || !isset($_POST['report2']) || !isset($_POST['report3']) || !isset($_POST['description']) || !isset($_POST['signature'])) {
3276 return array('all_fields');
3277 }
3278 }
3279
3280 function addComment($id, $comment) {
3281 // Check if the POST is public
3282 $query = sprintf("SELECT * FROM `tracks`,`users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id));
3283 $result = $this->db->query($query);
3284
3285 $row = $result->fetch_assoc();
3286
3287 // If the POST is public
3288 if($row['public'] == 1) {
3289 // Add the insert message
3290 $stmt = $this->db->prepare("INSERT INTO `comments` (`uid`, `tid`, `message`) VALUES ('{$this->db->real_escape_string($this->id)}', '{$this->db->real_escape_string($id)}', '{$this->db->real_escape_string(htmlspecialchars($comment))}')");
3291
3292 // Execute the statement
3293 $stmt->execute();
3294
3295 // Save the affected rows
3296 $affected = $stmt->affected_rows;
3297
3298 // Close the statement
3299 $stmt->close();
3300
3301 // Select the last inserted message
3302 $getId = $this->db->query(sprintf("SELECT `id`,`uid`,`tid` FROM `comments` WHERE `uid` = '%s' AND `tid` = '%s' ORDER BY `id` DESC", $this->db->real_escape_string($this->id), $row['id']));
3303 $lastComment = $getId->fetch_assoc();
3304
3305 // Do the INSERT notification
3306 $insertNotification = $this->db->query(sprintf("INSERT INTO `notifications` (`from`, `to`, `parent`, `child`, `type`, `read`) VALUES ('%s', '%s', '%s', '%s', '1', '0')", $this->db->real_escape_string($this->id), $row['uid'], $row['id'], $lastComment['id']));
3307
3308 if($affected) {
3309 // If email on likes is enabled in admin settings
3310 if($this->email_comment) {
3311
3312 // If user has emails on commentss enabled and he's not commenting on his own track
3313 if($row['email_comment'] && ($this->id !== $row['idu'])) {
3314 global $LNG;
3315
3316 // Send e-mail
3317 sendMail($row['email'], sprintf($LNG['ttl_comment_email'], $this->username), sprintf($LNG['comment_email'], realName($row['username'], $row['first_name'], $row['last_name']), $this->url.'/index.php?a=profile&u='.$this->username, $this->username, $this->url.'/index.php?a=track&id='.$id, $this->title, $this->url.'/index.php?a=settings&b=notifications'), $this->email);
3318 }
3319 }
3320 }
3321
3322 // If the comment was added, return 1
3323 return ($affected) ? 1 : 0;
3324 } else {
3325 return 0;
3326 }
3327 }
3328
3329 function changePrivacy($id, $value, $type = null) {
3330 // Type 0: Tracks privacy
3331 // Type 1: Playlist privacy
3332 if($type == 1) {
3333 $stmt = $this->db->prepare("UPDATE `playlists` SET `public` = '{$this->db->real_escape_string($value)}', `time` = `time` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `by` = '{$this->db->real_escape_string($this->id)}'");
3334 } else {
3335 $stmt = $this->db->prepare("UPDATE `tracks` SET `public` = '{$this->db->real_escape_string($value)}', `time` = `time` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `uid` = '{$this->db->real_escape_string($this->id)}'");
3336 }
3337
3338 // Execute the statement
3339 $stmt->execute();
3340
3341 // Save the affected rows
3342 $affected = $stmt->affected_rows;
3343
3344 // Close the statement
3345 $stmt->close();
3346
3347 return ($affected) ? 1 : 0;
3348 }
3349
3350 function ago($i) {
3351 $m = time()-$i; $o='just now';
3352 $t = array('year'=>31556926,'month'=>2629744,'week'=>604800, 'day'=>86400,'hour'=>3600,'minute'=>60,'second'=>1);
3353 foreach($t as $u=>$s){
3354 if($s<=$m){$v=floor($m/$s); $o="$v $u".($v==1?'':'s').' ago'; break;}
3355 }
3356 return $o;
3357 }
3358
3359 function sidebarFilters($bold) {
3360 global $LNG, $CONF;
3361
3362 // Start the output
3363 $row = array('people', 'tracks', 'playlists');
3364 $link = '<div class="sidebar-container widget-filter"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['search'].'</div>';
3365 foreach($row as $type) {
3366 $class = '';
3367 // Start the strong tag
3368 if($type == $bold || empty($bold) && $type == 'people') {
3369 $class = ' sidebar-link-active';
3370 }
3371 // Output the links
3372
3373 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].'&q='.htmlspecialchars($_GET['q'], ENT_QUOTES, 'UTF-8').'&filter='.$type.'" rel="loadpage"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/filters/'.$type.'.png" />'.$LNG["sidebar_{$type}"].'</a></div>';
3374 }
3375 $link .= '</div></div>';
3376 return $link;
3377 }
3378
3379 function sidebarNotifications($bold) {
3380 global $LNG, $CONF;
3381
3382 // Start the output
3383 $row = array('likes', 'comments', 'friendships', 'chats');
3384 $link = '<div class="sidebar-container widget-notifications"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['filter_notifications'].'</div>';
3385 if(empty($bold)) {
3386 $class = ' sidebar-link-active';
3387 }
3388 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].'" rel="loadpage"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/filters/all_notifications.png" />'.$LNG["all_notifications"].'</a></div>';
3389 foreach($row as $type) {
3390 $class = '';
3391 if($type == $bold) {
3392 $class = ' sidebar-link-active';
3393 }
3394
3395 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].'&filter='.$type.'" rel="loadpage"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/filters/'.$type.'.png" />'.$LNG["sidebar_{$type}"].'</a></div>';
3396 }
3397 $link .= '</div></div>';
3398 return $link;
3399 }
3400
3401 function sidebarCategories($bold) {
3402 global $LNG;
3403 $query = $this->db->query("SELECT * FROM `categories` ORDER BY `name` ASC");
3404
3405 while($row = $query->fetch_assoc()) {
3406 $rows[] = $row;
3407 }
3408
3409 $link = '<div class="sidebar-container widget-categories"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['categories'].'</div>';
3410
3411 if(empty($bold)) {
3412 $class = ' sidebar-link-active';
3413 }
3414 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].'" rel="loadpage">'.$LNG['latest_music'].'</a></div>';
3415
3416
3417 foreach(array('popular_music' => 'popular music', 'liked_music' => 'liked music') as $lang => $value) {
3418 // Start the strong tag
3419 $class = '';
3420 if($value == $bold) {
3421 $class = ' sidebar-link-active';
3422 }
3423
3424 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].'&filter='.$value.'" rel="loadpage">'.$LNG[$lang].'</a></div>';
3425 }
3426 $link .= '<div class="sidebar-link-divider"><div class="divider"></div></div>';
3427 foreach($rows as $category) {
3428 $category['name'] = strtolower($category['name']);
3429 $class = '';
3430 if($category['name'] == $bold) {
3431 $class = ' sidebar-link-active';
3432 }
3433
3434 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].'&filter='.$category['name'].'" rel="loadpage">'.ucfirst($category['name']).'</a></div>';
3435 }
3436 $link .= '</div></div>';
3437 return $link;
3438 }
3439
3440 function sidebarDates($bold, $values = null) {
3441 global $LNG;
3442 $row = $this->listDates($values);
3443
3444 $profile = ($this->profile) ? '&u='.$this->profile : '';
3445 // If the result is not empty
3446 if($row) {
3447 // Start the output
3448 $link = '<div class="sidebar-container widget-archive"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['archive'].'</div>';
3449 if(empty($bold)) {
3450 $class = ' sidebar-link-active';
3451 }
3452 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].$profile.'" rel="loadpage">'.$LNG["all_time"].'</a></div>';
3453 foreach($row as $date) {
3454
3455 // Explode the born value [[0]=>Y,[1]=>M];
3456 $born = explode('-', wordwrap($date, 4, '-', true));
3457
3458 // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language)
3459 $month = intval($born[1]);
3460 $class = '';
3461 // Start the strong tag
3462 if($date == $bold) {
3463 $class = ' sidebar-link-active';
3464 }
3465
3466 // Output the links
3467 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].$profile.'&filter='.$date.'" rel="loadpage">'.$LNG["month_{$month}"].' - '.$born[0].'</a></div>';
3468 }
3469 $link .= '</div></div>';
3470 return $link;
3471 }
3472 }
3473
3474 function listDates($values = null) {
3475 if($values == false) {
3476 return false;
3477 } elseif($values == 'profile') {
3478 $profile = ($this->profile == $this->username) ? '' : 'AND public = 1';
3479 $query = sprintf("SELECT DISTINCT extract(YEAR_MONTH from `time`) AS dates FROM `tracks` WHERE uid = '%s' %s ORDER BY `time` DESC", $this->db->real_escape_string($this->profile_id), $profile);
3480 } elseif($values) {
3481 $query = sprintf("SELECT DISTINCT extract(YEAR_MONTH from `time`) AS dates FROM `tracks` WHERE uid IN (%s) AND `public` = 1 ORDER BY `time` DESC", $this->db->real_escape_string($values));
3482 }
3483
3484 $result = $this->db->query($query);
3485
3486 while($row = $result->fetch_assoc()) {
3487 $rows[] = $row;
3488 }
3489
3490 // If the select was made
3491 if($result = $this->db->query($query)) {
3492 // Define the array;
3493 $store = array();
3494 foreach($rows as $date) {
3495 // Add the elemnts to the array
3496 $store [] = $date['dates'];
3497 }
3498 return $store;
3499 } else {
3500 return false;
3501 }
3502 }
3503
3504 function sidebarReport($id) {
3505 global $LNG;
3506 return '<div class="sidebar-container sidebar-report"><div class="sidebar-description"><a '.(($this->id) ? 'href="'.$this->url.(($this->id) ? '/index.php?a=track&id='.$id.'&type=report' : '/index.php?a=welcome').'" rel="loadpage"' : 'href="javascript:;" onclick="connect_modal()"').'>'.$LNG['rci'].'</a></div></div>';
3507 }
3508
3509 function getTrackList($id) {
3510 $query = $this->db->query(sprintf("SELECT `id` FROM `tracks` WHERE `uid` = '%s'", $this->db->real_escape_string($id)));
3511
3512 while($row = $query->fetch_assoc()) {
3513 $rows[] = $row['id'];
3514 }
3515 return $rows;
3516 }
3517
3518 function proAccountHistory($id = null, $title = null, $type) {
3519 // Title: Decide if the title is included or not
3520 // Type 0: Return all transactions
3521 // Type 1: Return inactive transactions
3522 global $LNG;
3523 if($type) {
3524 $x = ' AND `valid` < \''.date('Y-m-d H:i:s').'\'';
3525 } else {
3526 $x = '';
3527 }
3528 $query = $this->db->query(sprintf("SELECT * FROM `payments` WHERE `by` = '%s'%s ORDER BY `id` DESC", ($id) ? $id : $this->db->real_escape_string($this->id), $x));
3529
3530 while($row = $query->fetch_assoc()) {
3531 $rows[] = $row;
3532 }
3533
3534 if(!empty($rows)) {
3535 $result = '<div class="page-content">';
3536 if($title) {
3537 $result .= '<div class="plan-history-title">'.$LNG['transactions_history'].'</div>
3538 <div class="divider"></div>
3539 <div class="plan-history-container">
3540 <div class="plan-option">'.$LNG['from'].'</div>
3541 <div class="plan-option">'.$LNG['to'].'</div>
3542 <div class="plan-option">'.$LNG['type'].'</div>
3543 <div class="plan-option">'.$LNG['status'].'</div>
3544 </div>';
3545 }
3546
3547 foreach($rows as $row) {
3548 $fromArr = explode('-', $row['time']);
3549 $date = $fromArr[0].'-'.$fromArr[1].'-'.substr($fromArr[2], 0, 2);
3550
3551 $toArr = explode('-', $row['valid']);
3552 $valid = $toArr[0].'-'.$toArr[1].'-'.substr($toArr[2], 0, 2);
3553
3554 $status = paymentStatus($row['status']);
3555
3556 $result .= '<div class="feature-container">
3557 <div class="plan-history">'.$date.'</div>
3558 <div class="plan-history">'.$valid.'</div>
3559 <div class="plan-history">'.$row['amount'].' '.$row['currency'].'</div>
3560 <div class="plan-history">'.$status.'</div>
3561 </div>';
3562 }
3563 $result .= '</div>';
3564 }
3565
3566 return $result;
3567 }
3568
3569 function getProStatus($id = null, $type = null) {
3570 // Type 0: Get the Pro Status of a user
3571 // Type 1: Decide whether the pro accounts are enabled from the Admin Panel, and if so, check the status
3572 // Type 2: Returns all the details of last transaction
3573 $query = $this->db->query(sprintf("SELECT * FROM `payments` WHERE `by` = '%s' ORDER BY `id` DESC LIMIT 0, 1", ($id) ? $id : $this->db->real_escape_string($this->id)));
3574 $result = $query->fetch_assoc();
3575
3576 if($type == 1) {
3577 if($this->paypalapp) {
3578 if($result['status'] == 1 && strtotime($result['valid']) >= time()) {
3579 return 1;
3580 } else {
3581 return 0;
3582 }
3583 } else {
3584 // Always return all features if the pro accounts are disabled
3585 return 1;
3586 }
3587 } elseif($type == 2) {
3588 return $result;
3589 } else {
3590 if($result['status'] == 1 && strtotime($result['valid']) >= time()) {
3591 return 1;
3592 } else {
3593 return 0;
3594 }
3595 }
3596 }
3597
3598 function goProMessage($message = null, $type = null, $artist = null) {
3599 // Message: Certain number to match a string from language file
3600 // Type 0: For Stats page
3601 // Type 1: For Account Plan page
3602 // Type 2: For sidebar widgets
3603 // Artist: If set, it must have at least one track uploaded
3604 global $LNG;
3605 if($type == 1) {
3606 if($this->paypalapp && !$this->getProStatus($this->id)) {
3607 // Generate a random number for a dynamic widget if the $message is not set
3608 if(!$message) {
3609 $message = rand(1, 2);
3610 }
3611 if($artist) {
3612 // If there's no track uploaded by the user and
3613 if(!$this->trackList) {
3614 return false;
3615 }
3616 }
3617 return '<div class="sidebar-container widget-gopro"><div class="go-pro-widget-container"><div class="go-pro-title">'.$LNG["go_pro_ttl_{$message}"].'</div><div class="go-pro-widget-desc">'.$LNG["go_pro_{$message}"].'</div><div class="go-pro-btn go-pro-widget-btn"><a href="'.$this->url.'/index.php?a=pro" rel="loadpage">'.$LNG['go_pro'].'</a></div></div></div>';
3618 }
3619 } else {
3620 return '<div class="go-pro-container"><div class="go-pro-desc">'.$LNG["go_pro_{$message}"].'</div><div class="go-pro-btn"><a href="'.$this->url.'/index.php?a=pro" rel="loadpage">'.$LNG['go_pro'].'</a></div></div>';
3621 }
3622 }
3623
3624 function sidebarDescription($id, $type = null, $raw = null) {
3625 global $LNG;
3626
3627 if($type == 1) {
3628 $query = $this->db->query(sprintf("SELECT `description` FROM `playlists` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
3629 } else {
3630 $query = $this->db->query(sprintf("SELECT `description`, `record`, `release`, `license` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
3631 }
3632
3633 $result = $query->fetch_row();
3634
3635 // Return raw text output
3636 if($raw) {
3637 return nl2br($result[0]);
3638 }
3639
3640 if($type !== 1) {
3641 // Explode the born value [[0]=>Y,[1]=>M,[2]=>D];
3642 $date = explode('-', $result[2]);
3643
3644 // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language)
3645 $month = intval($date[1]);
3646
3647 $extra = (($result[2] !== '0000-00-00') ? '<div class="sidebar-description">'.$LNG['release_date'].'<br> <strong>'.$LNG["month_$month"].' '.$date[2].', '.$date[0].'</strong></div>' : '');
3648 $extra .= (($result[1]) ? '<div class="sidebar-description">'.$LNG['record_label'].'<br> <strong>'.$result[1].'</strong></div>' : '');
3649
3650 if($result[3]) {
3651 $license = str_split($result[3]);
3652
3653 if($license[1] == 1) {
3654 $nc = ' <div class="license-icon license-nc-icon"></div>';
3655 }
3656 if($license[2] == 1) {
3657 $nd = ' <div class="license-icon license-nd-icon"></div>';
3658 } elseif($license[2] == 2) {
3659 $sa = ' <div class="license-icon license-sa-icon"></div>';
3660 }
3661 $extra .= (($result[3]) ? '<div class="sidebar-description">'.$LNG['licensed_under'].'<div class="sidebar-license"><a href="http://creativecommons.org/about/license/" target="_blank" title="'.$LNG['creative_commons'].'" rel="nofollow"><div class="license-icon license-cc-icon"></div> <div class="license-icon license-at-icon"></div>'.$nc.$nd.$sa.'</a></div></div>' : '');
3662 }
3663 }
3664
3665 $description = ($result[0] ? '<div class="sidebar-description">'.nl2br($this->parseMessage($result[0])).'</div>' : '');
3666
3667 if(!empty($description) || !empty($extra)) {
3668 $output = '<div class="sidebar-container widget-description"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['ttl_description'].'</div>'.$description.$extra.'</div></div>';
3669 }
3670
3671 return $output;
3672 }
3673
3674 function sidebarKeywords($id, $type = null) {
3675 // Type 0: Return keywords for Track Page
3676 // Type 1: Return keywords for Playlist Page
3677 global $LNG;
3678
3679 if($type == 1) {
3680 $query = $this->db->query(sprintf("SELECT `tracks`.`tag` FROM `playlistentries`,`users`,`tracks` WHERE (`playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`public` = 1) OR (`playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`uid` = '%s') ORDER BY `playlistentries`.`id` DESC", $this->db->real_escape_string($id), $this->db->real_escape_string($id), $this->id));
3681 } else {
3682 $query = $this->db->query(sprintf("SELECT `tag` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
3683 }
3684
3685 // Store the hashtags into a string
3686 while($row = $query->fetch_assoc()) {
3687 $hashtags .= $row['tag'];
3688 }
3689
3690 if($hashtags) {
3691 $hashtags = explode(',', $hashtags);
3692 if($type == 1) {
3693 // Count the array values and filter out the blank spaces (also lowercase all array elements to prevent case-sensitive showing up, e.g: Test, test, TEST)
3694 $count = array_count_values(array_map('strtolower', array_filter($hashtags)));
3695
3696 // Sort them by must popular
3697 arsort($count);
3698 } else {
3699 // Lowercase all the array elements to prevent case-sensitive tags showing up, e.g: Test, test, TEST
3700 $count = array_map('strtolower', array_filter($hashtags));
3701
3702 // Reverse the keys with values
3703 $count = array_flip($count);
3704 }
3705 // Return only 15 hashtags
3706 $count = array_slice($count, 0, 15, true);
3707
3708 $output = '<div class="sidebar-container widget-trending"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['categories'].'</div><div class="sidebar-description">';
3709 foreach($count as $row => $value) {
3710 $output .= '<div class="sidebar-tag"><a href="'.$this->url.'/index.php?a=explore&filter='.$row.'" rel="loadpage">#'.$row.'</a></div>';
3711 }
3712 $output .= '</div></div></div>';
3713 }
3714
3715 return $output;
3716 }
3717
3718 function sidebarRecommended($id) {
3719 global $LNG;
3720
3721 $current_tags = array_filter(explode(',', $this->track_tag));
3722
3723 $i = 1;
3724 foreach($current_tags as $tag) {
3725 if(count($current_tags) > 1) {
3726 if($i == 1) {
3727 $like .= sprintf("(`tag` LIKE '%s'", '%'.$this->db->real_escape_string($tag).'%');
3728 } else {
3729 $like .= sprintf(" OR `tag` LIKE '%s'", '%'.$this->db->real_escape_string($tag).'%');
3730 }
3731 if($i == (count($current_tags))) {
3732 $like .= ")";
3733 }
3734 } else {
3735 $like = sprintf(" `tag` LIKE '%s'", '%'.$this->db->real_escape_string($tag).'%');
3736 }
3737 $i++;
3738 }
3739
3740 // Get track suggestions based on the current track's categories and exclude the current track from the results
3741 $query = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE %s AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`id` != '%s' AND `tracks`.`public` = 1 ORDER BY `tracks`.`views` DESC LIMIT 0, 100", $like, $this->db->real_escape_string($id)));
3742
3743 // Store the array results
3744 while($row = $query->fetch_assoc()) {
3745 $rows[] = $row;
3746 }
3747
3748 shuffle($rows);
3749
3750 // If suggestions are available
3751 if(!empty($rows)) {
3752 $i = 0;
3753
3754 $output = '<div class="sidebar-container widget-suggestions"><div class="sidebar-header">'.$LNG['recommended'].'</div>';
3755 foreach($rows as $row) {
3756 if($i == 3) break; // Display only the last 6 suggestions
3757
3758 $username = realName($row['username'], $row['first_name'], $row['last_name']);
3759 $subscribersList = $this->getSubs($row['idu'], 1, null);
3760 $tracks = $this->countSongs($row['idu']);
3761
3762 $output .= '<div class="sidebar-suggestions-inner">
3763 <div class="sidebar-suggestions">
3764 <div class="sidebar-suggestions-image"><a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&t=m&w=112&h=112" /></a></div>
3765 <div class="sidebar-suggestions-info"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" title="'.$LNG['profile_view_profile'].'" rel="loadpage"><div class="sidebar-title-name">'.$username.'</div></a>
3766 <div class="sidebar-suggestions-track"><a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" title="'.$row['title'].'" rel="loadpage">'.$row['title'].'</a></div>
3767 </div>
3768 </div>
3769 </div>';
3770 $i++;
3771 }
3772 $output .= '</div>';
3773 return $output;
3774 } else {
3775 return false;
3776 }
3777 }
3778
3779 function sidebarStatistics($id = null, $type = null, $extra = null) {
3780 // Type 0: Return statistics for your own tracks that have been played by other users
3781 // Type 1: Return statistics for track page
3782 global $LNG;
3783
3784 if($type == 1) {
3785 $query = $this->db->query(sprintf("SELECT (SELECT count(`track`) FROM `views` WHERE `track` = '%s') as total, (SELECT count(`track`) FROM `views` WHERE `track` = '%s' AND CURDATE() = date(`time`)) as today, (SELECT count(`track`) FROM `views` WHERE `track` = '%s' AND CURDATE()-1 = date(`time`)) as yesterday", $this->db->real_escape_string($id), $this->db->real_escape_string($id), $this->db->real_escape_string($id)));
3786 } elseif($type == 2) {
3787 $query = $this->db->query(sprintf("SELECT (SELECT count(`id`) FROM `tracks` WHERE `uid` = '%s') as tracks_total, (SELECT SUM(`size`) FROM `tracks` WHERE `uid` = '%s') as upload_size", $this->db->real_escape_string($this->id), $this->db->real_escape_string($this->id), $this->db->real_escape_string($id)));
3788 } else {
3789 if(!$this->trackList) {
3790 return;
3791 }
3792 $query = $this->db->query(sprintf("SELECT (SELECT count(`track`) FROM `views` WHERE `track` IN (%s)) as total, (SELECT count(`track`) FROM `views` WHERE `track` IN (%s) AND CURDATE() = date(`time`)) as today, (SELECT count(`track`) FROM `views` WHERE `track` IN (%s) AND CURDATE()-1 = date(`time`)) as yesterday", $this->trackList, $this->trackList, $this->trackList));
3793 }
3794
3795 $result = $query->fetch_assoc();
3796
3797 $output = '<div class="sidebar-container widget-statistics"><div class="sidebar-content"><div class="sidebar-header">'.((!$type) ? '<a href="'.$this->url.'/index.php?a=stats" rel="loadpage">'.$LNG['statistics'].'</a>' : (($extra) ? $LNG['statistics'].' <div class="sidebar-header-extra"><a href="'.$this->url.'/index.php?a=track&id='.$_GET['id'].'&type=stats" rel="loadpage">'.$LNG['view_more'].'</a></div>' : $LNG['statistics'])).'</div><div class="sidebar-stats-container">';
3798 if($type == 2) {
3799 // Percentage for the stats bar
3800 $percentage = ($result['upload_size']/$this->track_size_total) * 100;
3801 $output .= '
3802 <div class="sidebar-stats-box">'.$LNG['tracks_uploaded'].'</div><div class="sidebar-stats-box sidebar-text-right">'.$result['tracks_total'].'</div>
3803 <div class="sidebar-stats-box">'.$LNG['total_space'].'</div><div class="sidebar-stats-box sidebar-text-right">'.fsize($this->track_size_total).'</div>
3804 <div class="divider sidebar-stats-divider"></div>
3805 <div class="sidebar-stats-box">'.$LNG['used_space'].'</div><div class="sidebar-stats-box sidebar-stats-box-right">'.$LNG['free_space'].'</div>
3806 <div class="sidebar-stats-bar"><div class="sidebar-stats-bar-percentage" style="width: '.$percentage.'%"></div></div>
3807 <div class="sidebar-stats-box">'.fsize($result['upload_size']).'</div><div class="sidebar-stats-box sidebar-stats-box-right">'.fsize($this->track_size_total-$result['upload_size']).'</div>';
3808 } else {
3809 $output .= '
3810 <div class="sidebar-stats-box">'.$LNG['plays_today'].'</div><div class="sidebar-stats-box sidebar-text-right sidebar-stats-today">'.$result['today'].'</div>
3811 <div class="sidebar-stats-box">'.$LNG['plays_yesterday'].'</div><div class="sidebar-stats-box sidebar-text-right">'.$result['yesterday'].'</div>
3812 <div class="sidebar-stats-box">'.$LNG['plays_total'].'</div><div class="sidebar-stats-box sidebar-text-right">'.$result['total'].'</div>';
3813 }
3814 $output .= '</div></div></div>';
3815
3816 return $output;
3817 }
3818
3819 function onlineUsers($type = null, $value = null) {
3820 global $LNG, $CONF;
3821 // Type 2: Show the Friends Results for the live search for Chat/Messages
3822 // : If value is set, find friends from Subscriptions
3823 // Type 1: Display the friends for the Chat/Messages page
3824 // : If value is set, find exact username
3825 // Type 0: Display the friends for stream page
3826
3827 // Get the subscritions
3828 $subscriptions = $this->getSubscriptionsList();
3829 $currentTime = time();
3830
3831 if(!empty($subscriptions)) {
3832 if($type == 1) {
3833 // Display current friends
3834 $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` IN (%s) ORDER BY `online` DESC", $this->db->real_escape_string($subscriptions)));
3835 } elseif($type == 2) {
3836 if($value) {
3837 // Search in friends
3838 $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE (`username` LIKE '%s' OR concat_ws(' ', `first_name`, `last_name`) LIKE '%s') AND `idu` IN (%s) ORDER BY `online` DESC", '%'.$this->db->real_escape_string($value).'%', '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($subscriptions)));
3839 } else {
3840 // Display current friends
3841 $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` IN (%s) ORDER BY `online` DESC", $this->db->real_escape_string($subscriptions)));
3842 }
3843 } else {
3844 // Display the online friends (used in Feed/Subscriptions)
3845 $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` IN (%s) AND `online` > '%s'-'%s' ORDER BY `online` DESC", $this->db->real_escape_string($subscriptions), $currentTime, $this->online_time));
3846 }
3847
3848 // Store the array results
3849 while($row = $query->fetch_assoc()) {
3850 $rows[] = $row;
3851 }
3852 }
3853
3854 // usort($rows, 'sortOnlineUsers');
3855
3856 if($type == 1) {
3857 // Output the users
3858 $output = '<div class="sidebar-container widget-online-users"><div class="sidebar-content"><div class="sidebar-header"><input type="text" placeholder="'.$LNG['search_in_friends'].'" id="search-list"></div><div class="search-list-container"></div><div class="sidebar-chat-list">';
3859 if(!empty($rows)) {
3860 $i = 0;
3861 foreach($rows as $row) {
3862 $class = '';
3863 if($row['username'] == $_GET['u']) {
3864 $class = ' sidebar-link-active';
3865 }
3866 // Switch the images, depending on the online state
3867 if(($currentTime - $row['online']) > $this->online_time) {
3868 $icon = 'offline';
3869 } else {
3870 $icon = 'online';
3871 }
3872
3873 $output .= '<div class="sidebar-users'.$class.'"><a href="'.$this->url.'/index.php?a=messages&u='.$row['username'].'&id='.$row['idu'].'" rel="loadpage"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/'.$icon.'.png" class="sidebar-status-icon"> <img src="'.$this->url.'/thumb.php?src='.$row['image'].'&w=25&h=25&t=a" /> '.realName($row['username'], $row['first_name'], $row['last_name']).'</a></div>';
3874
3875 $i++;
3876 }
3877 } else {
3878 $output .= '<div class="sidebar-inner">'.$LNG['lonely_here'].'</div>';
3879 }
3880 $output .= '</div></div></div>';
3881 } elseif($type == 2) {
3882 $output = '';
3883 if(!empty($rows)) {
3884 $i = 0;
3885 foreach($rows as $row) {
3886 // Switch the images, depending on the online state
3887 if(($currentTime - $row['online']) > $this->online_time) {
3888 $icon = 'offline';
3889 } else {
3890 $icon = 'online';
3891 }
3892
3893 $output .= '<div class="sidebar-users"><a href="'.$this->url.'/index.php?a=messages&u='.$row['username'].'&id='.$row['idu'].'" rel="loadpage"><img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/'.$icon.'.png" class="sidebar-status-icon"> <img src="'.$this->url.'/thumb.php?src='.$row['image'].'&w=25&h=25&t=a" /> '.realName($row['username'], $row['first_name'], $row['last_name']).'</a></div>';
3894
3895 $i++;
3896 }
3897 } else {
3898 $output .= '<div class="sidebar-inner">'.$LNG['no_results'].'</div>';
3899 }
3900 } else {
3901 // If the query has content
3902 if(!empty($rows)) {
3903 // Output the online users
3904 $output = '<div class="sidebar-container widget-online-users"><div class="sidebar-content"><div class="sidebar-header"><a href="'.$this->url.'/index.php?a=messages" rel="loadpage">'.$LNG['online_friends'].'</a></div><div class="sidebar-online-users-inner">';
3905
3906 $i = 0;
3907 $break = $this->friends_online;
3908 foreach($rows as $row) {
3909 // If the limit is hit, break the row and show the + button
3910 if($i == $break) {
3911 $output .= '<div class="sidebar-online-users" id="online-plus"><div class="sidebar-online-users-padding"><a href="'.$this->url.'/index.php?a=messages" rel="loadpage" title="'.$LNG['online_friends'].'"><div class="plus-button"><span class="plus-sign">+'.(count($rows)-$break).'</span></div></a></div></div>';
3912 break;
3913 }
3914
3915 $output .= '<div class="sidebar-online-users"><div class="sidebar-online-users-padding"><a href="'.$this->url.'/index.php?a=messages&u='.$row['username'].'&id='.$row['idu'].'" rel="loadpage" title="'.realName($row['username'], $row['first_name'], $row['last_name']).'"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&w=112&h=112&t=a" /></a></div></div>';
3916
3917 $i++;
3918 }
3919 $output .= '</div></div></div>';
3920 } else {
3921 return false;
3922 }
3923 }
3924 return $output;
3925 }
3926
3927 function getChat($uid, $user) {
3928 global $LNG, $CONF;
3929 $uid = saniscape($uid);
3930 $output = '<div class="message-container">
3931 <div class="message-content">
3932 <div class="page-header">
3933 <span class="chat-username">'.((empty($user['username'])) ? $LNG['conversation'] : realName($user['username'], $user['first_name'], $user['last_name'])).'</span><span class="blocked-button">'.$this->getBlocked($uid).'</span>
3934 <div class="header-loader"></div>
3935 </div>
3936 <div class="chat-container">
3937 '.((empty($user['username'])) ? $this->chatError($LNG['start_conversation']) : $this->getChatMessages($uid)).'
3938 </div>
3939 <div class="divider"></div>
3940
3941 <div class="chat-form-inner"><input id="chat" class="chat-user'.$uid.'" placeholder="'.$LNG['write_message'].'" name="chat" /></div>
3942 </div>
3943 </div>';
3944 return $output;
3945 }
3946
3947 function checkChat($uid) {
3948 $query = $this->db->query(sprintf("SELECT * FROM `chat` WHERE `from` = '%s' AND `to` = '%s' AND `read` = '0'", $this->db->real_escape_string($uid), $this->db->real_escape_string($this->id)));
3949
3950 if($query->num_rows) {
3951 return $this->getChatMessages($uid, null, null, 2);
3952 }
3953 return false;
3954 }
3955
3956 function getChatMessages($uid, $cid, $start, $type = null) {
3957 // uid = user id (from which user the message was sent)
3958 // cid = where the pagination will start
3959 // start = on/off
3960 // type 1: swtich the query to get the last message
3961 global $LNG;
3962 // The query to select the subscribed users
3963
3964 // If the $start value is 0, empty the query;
3965 if($start == 0) {
3966 $start = '';
3967 } else {
3968 // Else, build up the query
3969 $start = 'AND `chat`.`id` < \''.$this->db->real_escape_string($cid).'\'';
3970 }
3971
3972 if($type == 1) {
3973 $query = sprintf("SELECT * FROM `chat`, `users` WHERE (`chat`.`from` = '%s' AND `chat`.`to` = '%s' AND `chat`.`from` = `users`.`idu`) ORDER BY `chat`.`id` DESC LIMIT 1", $this->db->real_escape_string($this->id), $this->db->real_escape_string($uid));
3974 } elseif($type == 2) {
3975 $query = sprintf("SELECT * FROM `chat`,`users` WHERE `from` = '%s' AND `to` = '%s' AND `read` = '0' AND `chat`.`from` = `users`.`idu` ORDER BY `chat`.`id` DESC", $this->db->real_escape_string($uid), $this->db->real_escape_string($this->id));
3976 } else {
3977 $query = sprintf("SELECT * FROM `chat`, `users` WHERE (`chat`.`from` = '%s' AND `chat`.`to` = '%s' AND `chat`.`from` = `users`.`idu`) %s OR (`chat`.`from` = '%s' AND `chat`.`to` = '%s' AND `chat`.`from` = `users`.`idu`) %s ORDER BY `chat`.`id` DESC LIMIT %s", $this->db->real_escape_string($this->id), $this->db->real_escape_string($uid), $start, $this->db->real_escape_string($uid), $this->db->real_escape_string($this->id), $start, ($this->m_per_page + 1));
3978 }
3979
3980 // check if the query was executed
3981 if($result = $this->db->query($query)) {
3982
3983 if($type !== 1) {
3984 // Set the read status to 1 whenever you load messages [IGNORE TYPE: 1]
3985 $update = $this->db->query(sprintf("UPDATE `chat` SET `read` = '1', `time` = `time` WHERE `from` = '%s' AND `to` = '%s' AND `read` = '0'", $this->db->real_escape_string($uid), $this->db->real_escape_string($this->id)));
3986 }
3987
3988 // Set the result into an array
3989 while($row = $result->fetch_assoc()) {
3990 $rows[] = $row;
3991 }
3992 $rows = array_reverse($rows);
3993
3994 // Define the $output variable;
3995 $output = '';
3996
3997 // If there are more results available than the limit, then show the Load More Chat Messages
3998 if(array_key_exists($this->m_per_page, $rows)) {
3999 $loadmore = 1;
4000
4001 // Unset the first array element because it's not needed, it's used only to predict if the Load More Chat Messages should be displayed
4002 unset($rows[0]);
4003 }
4004
4005 foreach($rows as $row) {
4006 // Define the time selected in the Admin Panel
4007 $time = $row['time']; $b = '';
4008 if($this->time == '0') {
4009 $time = date("c", strtotime($row['time']));
4010 } elseif($this->time == '2') {
4011 $time = $this->ago(strtotime($row['time']));
4012 } elseif($this->time == '3') {
4013 $date = strtotime($row['time']);
4014 $time = date('Y-m-d', $date);
4015 $b = '-standard';
4016 }
4017
4018 if($this->username == $row['username']) { // If it's current username is the same with the current author
4019 $delete = '<a onclick="delete_the('.$row['id'].', 2)" title="'.$LNG['delete_this_message'].'"><div class="delete_btn"></div></a>';
4020 $class = 'user-one';
4021 } else {
4022 $delete = '';
4023 $class = 'user-two';
4024 }
4025
4026 // Variable which contains the result
4027 $output .= '
4028 <div class="message-reply-container '.$class.'" id="chat'.$row['id'].'">
4029 '.$delete.'
4030 <div class="message-reply-avatar">
4031 <a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a" /></a>
4032 </div>
4033 <div class="message-reply-message">
4034 <span class="message-reply-author"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">'.realName($row['username'], $row['first_name'], $row['last_name']).'</a></span>: '.$this->parseMessage($row['message']).'
4035 <div class="list-time">
4036 <div class="timeago'.$b.'" title="'.$time.'">
4037 '.$time.'
4038 </div>
4039 </div>
4040 </div>
4041 <div class="delete_preloader" id="del_chat_'.$row['id'].'"></div>
4042 </div>';
4043 $start = $row['id'];
4044 }
4045 if($loadmore) {
4046 $load = '<div class="load-more-chat"><a onclick="loadChat('.htmlentities($uid, ENT_QUOTES).', \'\', \'\', '.$rows[1]['id'].', 1)">'.$LNG['view_more_conversations'].'</a></div>';
4047 }
4048
4049 // Close the query
4050 $result->close();
4051
4052 // Return the conversations
4053 return $load.$output;
4054 } else {
4055 return false;
4056 }
4057 }
4058
4059 function postChat($message, $uid) {
4060 global $LNG;
4061
4062 $user = $this->profileData(null, $uid);
4063
4064 if(strlen($message) > $this->chat_length) {
4065 return $this->chatError(sprintf($LNG['chat_too_long'], $this->chat_length));
4066 } elseif($uid == $this->id) {
4067 return $this->chatError(sprintf($LNG['chat_self']));
4068 } elseif(!$user['username']) {
4069 return $this->chatError(sprintf($LNG['chat_no_user']));
4070 }
4071
4072 $query = $this->db->query(sprintf("SELECT * FROM `blocked` WHERE `by` = '%s' AND uid = '%s'", $this->db->real_escape_string($this->id), $this->db->real_escape_string($uid)));
4073
4074 if($query->num_rows) {
4075 return $this->chatError(sprintf($LNG['blocked_user'], realName($user['username'], $user['first_name'], $user['last_name'])));
4076 } else {
4077 $query = $this->db->query(sprintf("SELECT * FROM `blocked` WHERE `by` = '%s' AND uid = '%s'", $this->db->real_escape_string($uid), $this->db->real_escape_string($this->id)));
4078
4079 if($query->num_rows) {
4080 return $this->chatError(sprintf($LNG['blocked_by'], realName($user['username'], $user['first_name'], $user['last_name'])));
4081 }
4082 }
4083
4084 // Prepare the insertion
4085 $stmt = $this->db->prepare(sprintf("INSERT INTO `chat` (`from`, `to`, `message`, `read`, `time`) VALUES ('%s', '%s', '%s', '%s', CURRENT_TIMESTAMP)", $this->db->real_escape_string($this->id), $this->db->real_escape_string($uid), $this->db->real_escape_string(htmlspecialchars($message)), 0));
4086
4087 // Execute the statement
4088 $stmt->execute();
4089
4090 // Save the affected rows
4091 $affected = $stmt->affected_rows;
4092
4093 // Close the statement
4094 $stmt->close();
4095 if($affected) {
4096 return $this->getChatMessages($uid, null, null, 1);
4097 }
4098 }
4099
4100 function updateStatus($offline = null) {
4101 if(!$offline) {
4102 $this->db->query(sprintf("UPDATE `users` SET `online` = '%s' WHERE `idu` = '%s'", time(), $this->db->real_escape_string($this->id)));
4103 }
4104 }
4105
4106 function chatError($value) {
4107 return '<div class="chat-error">'.$value.'</div>';
4108 }
4109
4110 function playlistEntry($track, $playlist, $type = null) {
4111 // Type 0: Return whether the track exists in playlist or not
4112 // Type 1: Return the playlist entries
4113 // Type 2: Returns the latest added playlist
4114 // Type 3: Add/Remove track from playlist
4115 if($type) {
4116 if($type == 1) {
4117 $query = $this->db->query(sprintf("SELECT `id`,`name` FROM `playlists` WHERE `by` = '%s' ORDER BY `id` DESC", $this->id));
4118 } elseif($type == 2) {
4119 $query = $this->db->query(sprintf("SELECT `id`,`name` FROM `playlists` WHERE `by` = '%s' ORDER BY `id` DESC LIMIT 0, 1", $this->id));
4120 } elseif($type == 3) {
4121 // Verify if track exists
4122 $query = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($track)));
4123 if($query->num_rows > 0) {
4124 $result = $query->fetch_assoc();
4125
4126 // Verify relationship
4127 // Check privacy
4128 switch($result['private']) {
4129 case 0:
4130 break;
4131 case 1:
4132 // Check if the username is not the same with the track owner
4133 if($this->id !== $result['idu']) {
4134 return false;
4135 }
4136 case 2:
4137 $relationship = $this->verifyRelationship($this->id, $result['idu'], 0);
4138
4139 // Check relationship
4140 if(!$relationship) {
4141 return false;
4142 }
4143 break;
4144 }
4145
4146 // Verify playlist ownership
4147 $checkPlaylist = $this->db->query(sprintf("SELECT * FROM `playlists` WHERE `playlists`.`id` = '%s' AND `playlists`.`by` = '%s'", $this->db->real_escape_string($playlist), $this->db->real_escape_string($this->id)));
4148
4149 if($checkPlaylist->num_rows > 0) {
4150
4151 // Check if the track exists in playlist
4152 $checkTrack = $this->db->query(sprintf("SELECT * FROM `playlists`, `playlistentries` WHERE `playlistentries`.`track` = '%s' AND `playlistentries`.`playlist` = '%s' AND `playlistentries`.`playlist` = `playlists`.`id`", $this->db->real_escape_string($track), $this->db->real_escape_string($playlist)));
4153
4154 // If the track exist, delete it
4155 if($checkTrack->num_rows > 0) {
4156 $this->db->query(sprintf("DELETE FROM `playlistentries` WHERE `track` = '%s' AND `playlist` = '%s'", $this->db->real_escape_string($track), $this->db->real_escape_string($playlist)));
4157 }
4158 // Insert the track into playlist
4159 else {
4160 $this->db->query(sprintf("INSERT INTO `playlistentries` (`playlist`, `track`) VALUES ('%s', '%s')", $this->db->real_escape_string($playlist), $this->db->real_escape_string($track)));
4161 }
4162
4163 // Return the playlist entry
4164 $query = $this->db->query(sprintf("SELECT `id`,`name` FROM `playlists` WHERE `playlists`.`by` = '%s' AND `playlists`.`id` = '%s'", $this->id, $this->db->real_escape_string($playlist)));
4165 } else {
4166 return;
4167 }
4168 }
4169 }
4170
4171 // Store the array results
4172 while($row = $query->fetch_assoc()) {
4173 $rows[] = $row;
4174 }
4175
4176 foreach($rows as $row) {
4177 $output .= '<div class="playlist-entry'.(($this->playlistEntry($track, $row['id'])) ? ' playlist-added' : '').'" id="playlist-entry'.$row['id'].'" onclick="addInPlaylist('.saniscape($track).','.$row['id'].')">'.$row['name'].'</div>';
4178 }
4179
4180 return $output;
4181 } else {
4182 // Select the playlists
4183 $query = $this->db->query(sprintf("SELECT * FROM `playlistentries`,`playlists` WHERE `playlists`.`by` = '%s' AND `playlists`.`id` = '%s' AND `playlistentries`.`playlist` = '%s' AND `playlistentries`.`track` = '%s' AND `playlistentries`.`playlist` = `playlists`.`id`", $this->id, $playlist, $this->db->real_escape_string($playlist), $this->db->real_escape_string($track)));
4184
4185 // Store the array results
4186 if($query->num_rows > 0) {
4187 return $query->num_rows;
4188 }
4189 }
4190 }
4191
4192 function managePlaylist($id, $type, $data = null) {
4193 global $LNG;
4194 // Type 0: Return the current playlist info
4195 // Type 1: Update the current playlist
4196 // Type 2: Add a new playlist
4197
4198 if($type == 2) {
4199 $data = trim($data);
4200
4201 // Prepare the statement
4202 if(strlen($data) == 0) {
4203 return;
4204 }
4205
4206 // Prepare the insertion
4207 $stmt = $this->db->prepare(sprintf("INSERT INTO `playlists` (`by`, `name`, `public`, `time`) VALUES ('%s', '%s', 1, CURRENT_TIMESTAMP)", $this->db->real_escape_string($this->id), htmlspecialchars(trim(nl2clean($this->db->real_escape_string($data))))));
4208
4209 // Execute the statement
4210 $stmt->execute();
4211
4212 // Save the affected rows
4213 $affected = $stmt->affected_rows;
4214
4215 // Close the statement
4216 $stmt->close();
4217 if($affected) {
4218 // Return the latest added playlist entry
4219 return $this->playlistEntry($id, 0, 2);
4220 }
4221 } elseif($type == 1) {
4222 // Strip the white spaces at the beginning/end of the name
4223 $data['name'] = trim($data['name']);
4224
4225 // Prepare the statement
4226 if(strlen($data['name']) == 0) {
4227 return notificationBox('error', sprintf($LNG['playlist_name_empty']));
4228 }
4229 if(strlen($data['description']) > 160) {
4230 return notificationBox('error', sprintf($LNG['playlist_description'], 160));
4231 }
4232 $stmt = $this->db->prepare("UPDATE `playlists` SET `description` = '{$this->db->real_escape_string(htmlspecialchars(trim(nl2clean($data['description']))))}', `name` = '{$this->db->real_escape_string(htmlspecialchars($data['name']))}' WHERE `id` = '{$this->db->real_escape_string($id)}' AND `by` = '{$this->id}'");
4233
4234 // Execute the statement
4235 $stmt->execute();
4236
4237 // Save the affected rows
4238 $affected = $stmt->affected_rows;
4239
4240 // Close the statement
4241 $stmt->close();
4242
4243 // If there was anything affected return 1
4244 if($affected) {
4245 return notificationBox('success', $LNG['changes_saved']);
4246 } else {
4247 return notificationBox('info', $LNG['nothing_changed']);
4248 }
4249 } else {
4250 $query = $this->db->query(sprintf("SELECT `name`,`description` FROM `playlists` WHERE `id` = '%s' AND `by` = '%s'", $this->db->real_escape_string($_GET['id']), $this->id));
4251 $result = $query->fetch_array();
4252 return $result;
4253 }
4254 }
4255
4256 function sidebarButton($id = null, $type = null) {
4257 global $LNG;
4258 // Type 0: Upload button for Explore/Stream
4259 // Type 1: Edit button for Track Page
4260 // Type 2: Edit button for Playlist Page
4261 // Type 3: Last track uploaded
4262 if($type == 1) {
4263 $query = $this->db->query(sprintf("SELECT * FROM `tracks` WHERE `id` = '%s' AND `uid` = '%s'", $this->db->real_escape_string($_GET['id']), $this->id));
4264
4265 if($query->num_rows) {
4266 return '<div class="sidebar-container"><div class="sidebar-button-container"><a href="'.$this->url.'/index.php?a=track&id='.$id.(($_GET['type'] !== 'edit') ? '&type=edit' : '').'" rel="loadpage"><div class="'.(($_GET['type'] !== 'edit') ? 'edit' : 'back').'-button"><span class="'.(($_GET['type'] !== 'edit') ? 'edit' : 'back').'-icon"></span>'.(($_GET['type'] !== 'edit') ? $LNG['edit'] : $LNG['go_back']).'</div></a></div></div>';
4267 }
4268 } elseif($type == 2) {
4269 $query = $this->db->query(sprintf("SELECT * FROM `playlists` WHERE `id` = '%s' AND `by` = '%s'", $this->db->real_escape_string($_GET['id']), $this->id));
4270
4271 if($query->num_rows) {
4272 return '<div class="sidebar-container"><div class="sidebar-button-container"><a href="'.$this->url.'/index.php?a=playlist&id='.$id.((!isset($_GET['edit'])) ? '&edit=true' : '').'" rel="loadpage"><div class="'.((!isset($_GET['edit'])) ? 'edit' : 'back').'-button"><span class="'.((!isset($_GET['edit'])) ? 'edit' : 'back').'-icon"></span>'.((!isset($_GET['edit'])) ? $LNG['edit'] : $LNG['go_back']).'</div></a></div></div>';
4273 }
4274 } elseif($type == 3) {
4275 return '<div class="sidebar-button-container"><a href="'.$this->url.'/index.php?a=track&id='.$id.'" rel="loadpage"><div class="edit-button"><span class="success-icon"></span>'.$LNG['view_track'].'</div></a></div>';
4276 } else {
4277 return ($id) ? '<div class="sidebar-button-container"><a href="'.$this->url.'/index.php?a=upload" rel="loadpage"><div class="upload-button"><span class="upload-icon"></span>'.$LNG['upload'].'</div></a></div>' : '<div class="sidebar-container"><div class="sidebar-button-container"><a href="'.$this->url.'/index.php?a=upload" rel="loadpage"><div class="upload-button"><span class="upload-icon"></span>'.$LNG['upload'].'</div></a></div></div>';
4278 }
4279 }
4280
4281 function sidebarFriendsActivity($limit, $type = null) {
4282 global $LNG, $CONF;
4283
4284 $subscriptions = $this->getSubscriptionsList();
4285 // If there is no subscriptions, return false
4286 if(empty($subscriptions)) {
4287 return false;
4288 }
4289
4290 // Define the arrays that holds the values (prevents the array_merge to fail, when one or more options are disabled)
4291 $likes = array();
4292 $comments = array();
4293 $tracks = array();
4294
4295 $checkLikes = $this->db->query(sprintf("SELECT * FROM `likes`,`users` WHERE `likes`.`by` = `users`.`idu` AND `likes`.`by` IN (%s) ORDER BY `id` DESC LIMIT %s", $subscriptions, 25));
4296 while($row = $checkLikes->fetch_assoc()) {
4297 $likes[] = $row;
4298 }
4299
4300 $checkComments = $this->db->query(sprintf("SELECT * FROM `comments`,`users` WHERE `comments`.`uid` = `users`.`idu` AND `comments`.`uid` IN (%s) ORDER BY `id` DESC LIMIT %s", $subscriptions, 25));
4301 while($row = $checkComments->fetch_assoc()) {
4302 $comments[] = $row;
4303 }
4304
4305 $checkMessages = $this->db->query(sprintf("SELECT * FROM `tracks`,`users` WHERE `tracks`.`uid` = `users`.`idu` AND `tracks`.`uid` IN (%s) AND `tracks`.`public` = '1' ORDER BY `id` DESC LIMIT %s", $subscriptions, 25));
4306 while($row = $checkMessages->fetch_assoc()) {
4307 $tracks[] = $row;
4308 }
4309
4310 // If there are no latest notifications
4311 if(empty($likes) && empty($comments) && empty($tracks)) {
4312 return false;
4313 }
4314
4315 // Add the types into the recursive array results
4316 $x = 0;
4317 foreach($likes as $like) {
4318 $likes[$x]['event'] = 'like';
4319 $x++;
4320 }
4321 $y = 0;
4322 foreach($comments as $comment) {
4323 $comments[$y]['event'] = 'comment';
4324 $y++;
4325 }
4326 $z = 0;
4327 foreach($tracks as $track) {
4328 $tracks[$z]['event'] = 'message';
4329 $z++;
4330 }
4331
4332 $array = array_merge($likes, $comments, $tracks);
4333
4334 // Sort the array
4335 usort($array, 'sortDateAsc');
4336
4337 $activity .= '<div class="sidebar-container widget-friends-activity"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['sidebar_friends_activity'].'</div><div class="sidebar-fa-content">';
4338 $i = 0;
4339 foreach($array as $value) {
4340 if($i == $limit) break;
4341 $time = $value['time']; $b = '';
4342 if($this->time == '0') {
4343 $time = date("c", strtotime($value['time']));
4344 } elseif($this->time == '2') {
4345 $time = $this->ago(strtotime($value['time']));
4346 } elseif($this->time == '3') {
4347 $date = strtotime($value['time']);
4348 $time = date('Y-m-d', $date);
4349 $b = '-standard';
4350 }
4351 $activity .= '<div class="notification-row"><div class="notification-padding"><div class="sidebar-fa-image"><a href="'.$this->url.'/index.php?a=profile&u='.$value['username'].'" rel="loadpage"><img class="notifications" src='.$this->url.'/thumb.php?src='.$value['image'].'&t=a&w=50&h=50" /></a></div>';
4352 if($value['event'] == 'like') {
4353 $activity .= '<div class="sidebar-fa-text">'.sprintf($LNG['new_like_fa'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name']), $this->url.'/index.php?a=track&id='.$value['track']).'. <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span>';
4354 } elseif($value['event'] == 'comment') {
4355 $activity .= '<div class="sidebar-fa-text">'.sprintf($LNG['new_comment_fa'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name']), $this->url.'/index.php?a=track&id='.$value['tid']).'. <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span>';
4356 } elseif($value['event'] == 'message') {
4357 $activity .= '<div class="sidebar-fa-text">'.sprintf($LNG['new_track_fa'], $this->url.'/index.php?a=profile&u='.$value['username'], realName($value['username'], $value['first_name'], $value['last_name']), $this->url.'/index.php?a=track&id='.$value['id']).'. <span class="timeago'.$b.'" title="'.$time.'">'.$time.'</span>';
4358 }
4359 $activity .= '</div></div></div>';
4360 $i++;
4361 }
4362 $activity .= '</div></div></div>';
4363
4364 return $activity;
4365 }
4366
4367 function sidebarSuggestions() {
4368 global $LNG;
4369
4370 // Get some friends suggestions
4371 if($this->getSubscriptionsList($this->id)) {
4372 // If he already follows some of the top users, eliminate those
4373 $query = $this->db->query(sprintf("SELECT *, COUNT(`subscriber`) AS popular FROM `relations`, `users` WHERE `relations`.`leader` = `users`.`idu` AND `relations`.`leader` NOT IN (%s) AND `private` = '0' GROUP BY `leader` ORDER BY popular DESC LIMIT 10", $this->id.','.$this->db->real_escape_string($this->getSubscriptionsList($this->id))));
4374 } else {
4375 $query = $this->db->query(sprintf("SELECT *, COUNT(`subscriber`) AS popular FROM `relations`, `users` WHERE `relations`.`leader` = `users`.`idu` AND `users`.`idu` <> '%s' AND `private` = '0' GROUP BY `leader` ORDER BY popular DESC LIMIT 10", $this->id));
4376 }
4377
4378 // Store the array results
4379 while($row = $query->fetch_assoc()) {
4380 $rows[] = $row;
4381 }
4382
4383 // Shuffle the results
4384 shuffle($rows);
4385
4386 // If suggestions are available
4387 if(!empty($rows)) {
4388 $i = 0;
4389
4390 $output = '<div class="sidebar-container widget-suggestions"><div class="sidebar-header">'.$LNG['sidebar_suggestions'].'</div>';
4391 foreach($rows as $row) {
4392 if($i == 3) break; // Display only the last 6 suggestions
4393
4394 $username = realName($row['username'], $row['first_name'], $row['last_name']);
4395 $subscribersList = $this->getSubs($row['idu'], 1, null);
4396 $tracks = $this->countSongs($row['idu']);
4397
4398 $output .= '<div class="sidebar-suggestions-inner">
4399 <div class="sidebar-suggestions">
4400 <div class="sidebar-suggestions-image"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" title="'.$LNG['profile_view_profile'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=112&h=112" /></a></div>
4401 <div id="subscribe'.$row['idu'].'">'.$this->getSubscribe(0, array('idu' => $row['idu'], 'username' => $row['username'], 'private' => $row['private']), 1).'</div>
4402 <div class="sidebar-suggestions-info"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" title="'.$LNG['profile_view_profile'].'" rel="loadpage"><div class="sidebar-title-name">'.$username.'</div></a>
4403 <div class="sidebar-suggestions-small">'.(($tracks) ? '<div class="sidebar-suggestions-tracks" title="'.$tracks.' '.$LNG['tracks'].'">'.$tracks.'</div>' : '').'
4404 '.(($subscribersList[1]) ? '<div class="sidebar-suggestions-followers" title="'.$subscribersList[1].' '.$LNG['subscribers'].'">'.$subscribersList[1].'</div>' : '').'</div>
4405 </div>
4406 </div>
4407 </div>';
4408 $i++;
4409 }
4410 $output .= '</div>';
4411 return $output;
4412 } else {
4413 return false;
4414 }
4415 }
4416
4417 function sidebarTrending($bold, $per_page) {
4418 global $LNG;
4419
4420 // Get some friends suggestions [Top Social users -- SUBJECT TO BE CHANGED]
4421 $query = $this->db->query(sprintf("SELECT * FROM `tracks` WHERE `time` < CURRENT_DATE + INTERVAL 1 WEEK AND `tag` != ''"));
4422
4423 // Store the hashtags into a string
4424 while($row = $query->fetch_assoc()) {
4425 $hashtags .= $row['tag'];
4426 }
4427
4428 // If there are trends available
4429 if(!empty($hashtags)) {
4430 $i = 0;
4431 // Count the array values and filter out the blank spaces (also lowercase all array elements to prevent case-insensitive showing up, e.g: Test, test, TEST)
4432 $hashtags = explode(',', $hashtags);
4433 $count = array_count_values(array_map('strtolower', array_filter($hashtags)));
4434
4435 // Sort them by trend
4436 arsort($count);
4437 $output = '<div class="sidebar-container widget-trending"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['sidebar_trending'].'</div>';
4438 foreach($count as $row => $value) {
4439 if($i == $per_page) break; // Display and break when the trends hits the limit
4440 if($row == $bold) {
4441 $output .= '<div class="sidebar-link"><strong><a href="'.$this->url.'/index.php?a=explore&filter='.$row.'" rel="loadpage">#'.$row.'</a></strong></div>';
4442 } else {
4443 $output .= '<div class="sidebar-link"><a href="'.$this->url.'/index.php?a=explore&filter='.$row.'" rel="loadpage">#'.$row.'</a></div>';
4444 }
4445 $i++;
4446 }
4447 $output .= '</div></div>';
4448 return $output;
4449 } else {
4450 return false;
4451 }
4452 }
4453
4454 function sidebarStatsFilters($bold) {
4455 global $LNG, $CONF;
4456
4457 // Start the output
4458 $row = array('today', 'last7', 'last30', 'last356', 'total');
4459 $link = '<div class="sidebar-container widget-filter"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['filter_stats'].'</div>';
4460 foreach($row as $type) {
4461 $class = '';
4462 if($type == $bold || empty($bold) && $type == 'today') {
4463 $class = ' sidebar-link-active';
4464 }
4465 // Output the links
4466
4467 $link .= '<div class="sidebar-link'.$class.'"><a href="'.$this->url.'/index.php?a='.$_GET['a'].((isset($_GET['id'])) ? '&id='.$_GET['id'].'&type=stats' : '').'&filter='.$type.'" rel="loadpage">'.$LNG["stats_{$type}"].'</a></div>';
4468 }
4469 $link .= '</div></div>';
4470 return $link;
4471 }
4472
4473 function getUserStats($filter, $type, $limit = null) {
4474 // Filter for statistics (today, week, month, etc)
4475 // Type 0: Return results for COUNT statistics
4476 // Type 1: Return results for most plays
4477 $days = intval(str_replace(array('last', 'today', 'total'), array('', '0', '9999'), $filter));
4478
4479 // Check whether the filter value is valid or not
4480 if(!in_array($days, array(0, 7, 30, 356, 9999))) {
4481 $days = 0;
4482 }
4483
4484 // Set a negative integer to bypass the empty IN () error
4485 $trackList = ($this->trackList ? $this->trackList : -1);
4486
4487 if($type) {
4488 $plays = $this->db->query(sprintf("SELECT `views`.`track`,`tracks`.`title`,`tracks`.`art`, COUNT(`by`) as `count` FROM `views`,`tracks` WHERE `views`.`track` IN (%s) AND `views`.`track` = `tracks`.`id` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`views`.`time`) GROUP BY `track` ORDER BY `count` DESC LIMIT %s", $trackList, $days, $limit));
4489
4490 $likes = $this->db->query(sprintf("SELECT `likes`.`track`,`tracks`.`title`,`tracks`.`art`, COUNT(`by`) as `count` FROM `likes`,`tracks` WHERE `likes`.`track` IN (%s) AND `likes`.`track` = `tracks`.`id` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`likes`.`time`) GROUP BY `track` ORDER BY `count` DESC LIMIT %s", $trackList, $days, $limit));
4491
4492 $comments = $this->db->query(sprintf("SELECT `comments`.`tid`,`tracks`.`title`,`tracks`.`art`, COUNT(`comments`.`id`) as `count` FROM `comments`,`tracks` WHERE `comments`.`tid` IN (%s) AND `comments`.`tid` = `tracks`.`id` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`comments`.`time`) GROUP BY `tid` ORDER BY `count` DESC LIMIT %s", $trackList, $days, $limit));
4493
4494 $played = $this->db->query(sprintf("SELECT `views`.`by`,`users`.`idu`,`users`.`username`,`users`.`first_name`,`users`.`last_name`,`users`.`image`, COUNT(`by`) as `count` FROM `views`,`users` WHERE `views`.`track` IN (%s) AND `views`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `by` ORDER BY `count` DESC LIMIT 10", $trackList, $days, $limit));
4495
4496 $downloaded = $this->db->query(sprintf("SELECT `downloads`.`by`,`users`.`idu`,`users`.`username`,`users`.`first_name`,`users`.`last_name`,`users`.`image`, COUNT(`by`) as `count` FROM `downloads`,`users` WHERE `downloads`.`track` IN (%s) AND `downloads`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `by` ORDER BY `count` DESC LIMIT 10", $trackList, $days, $limit));
4497
4498 $countries = $this->db->query(sprintf("SELECT `users`.`country`, COUNT(`country`) AS `count` FROM `views`,`users` WHERE `views`.`track` IN (%s) AND `users`.`country` != '' AND `views`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `country` ORDER BY `count` DESC LIMIT %s", $trackList, $days, $limit));
4499
4500 $cities = $this->db->query(sprintf("SELECT `users`.`city`, COUNT(`city`) AS `count` FROM `views`,`users` WHERE `views`.`track` IN (%s) AND `users`.`city` != '' AND `views`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `city` ORDER BY `count` DESC LIMIT %s", $trackList, $days, $limit));
4501 } else {
4502 $query = $this->db->query(sprintf("SELECT(SELECT COUNT(track) FROM `views` WHERE `track` IN (%s) AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as plays, (SELECT COUNT(track) FROM `downloads` WHERE `track` IN (%s) AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as downloads, (SELECT COUNT(track) FROM `likes` WHERE `track` IN (%s) AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as likes, (SELECT COUNT(tid) FROM `comments` WHERE `tid` IN (%s) AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as comments", $trackList, $days, $trackList, $days, $trackList, $days, $trackList, $days));
4503 }
4504
4505 if($type) {
4506 while($row = $plays->fetch_assoc()) {
4507 $x .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=track&id='.$row['track'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&t=m&w=50&h=50">'.$row['title'].'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4508 }
4509 while($row = $likes->fetch_assoc()) {
4510 $y .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=track&id='.$row['track'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&t=m&w=50&h=50">'.$row['title'].'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4511 }
4512 while($row = $comments->fetch_assoc()) {
4513 $z .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=track&id='.$row['tid'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&t=m&w=50&h=50">'.$row['title'].'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4514 }
4515
4516 $rows['plays'] = $x;
4517 $rows['likes'] = $y;
4518 $rows['comments'] = $z;
4519
4520 if($this->getProStatus($this->id, 1)) {
4521 while($row = $played->fetch_assoc()) {
4522 $a .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50">'.realName($row['username'], $row['first_name'], $row['last_name']).'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4523 }
4524 while($row = $downloaded->fetch_assoc()) {
4525 $d .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50">'.realName($row['username'], $row['first_name'], $row['last_name']).'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4526 }
4527 $i = 1;
4528 while($row = $countries->fetch_assoc()) {
4529 $b .= '<div class="user-stats-row"><div class="user-stats-title"><span class="user-stats-row-count">'.$i.'</span>'.$row['country'].'</div><div class="user-stats-count">'.$row['count'].'</div></div>';
4530 $i++;
4531 }
4532 $i = 1;
4533 while($row = $cities->fetch_assoc()) {
4534 $c .= '<div class="user-stats-row"><div class="user-stats-title"><span class="user-stats-row-count">'.$i.'</span>'.$row['city'].'</div><div class="user-stats-count">'.$row['count'].'</div></div>';
4535 $i++;
4536 }
4537
4538 $rows['played'] = $a;
4539 $rows['countries'] = $b;
4540 $rows['cities'] = $c;
4541 $rows['downloaded'] = $d;
4542 } else {
4543 $rows['gopro'] = $this->goProMessage(0);
4544 }
4545
4546 return $rows;
4547 } else {
4548 return $query->fetch_assoc();
4549 }
4550 }
4551
4552 function getTrackStats($id, $filter, $type, $limit = null) {
4553 // Filter for statistics (today, week, month, etc)
4554 // Type 0: Return results for COUNT statistics
4555 // Type 1: Return results for most plays
4556 $days = intval(str_replace(array('last', 'today', 'total'), array('', '0', '9999'), $filter));
4557
4558 // Check whether the filter value is valid or not
4559 if(!in_array($days, array(0, 7, 30, 356, 9999))) {
4560 $days = 0;
4561 }
4562
4563 if($type) {
4564 $played = $this->db->query(sprintf("SELECT `views`.`by`,`users`.`idu`,`users`.`username`,`users`.`first_name`,`users`.`last_name`,`users`.`image`, COUNT(`by`) as `count` FROM `views`,`users` WHERE `views`.`track` = '%s' AND `views`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `by` ORDER BY `count` DESC LIMIT 10", $this->db->real_escape_string($id), $days, $limit));
4565
4566 $downloaded = $this->db->query(sprintf("SELECT `downloads`.`by`,`users`.`idu`,`users`.`username`,`users`.`first_name`,`users`.`last_name`,`users`.`image`, COUNT(`by`) as `count` FROM `downloads`,`users` WHERE `downloads`.`track` = '%s' AND `downloads`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `by` ORDER BY `count` DESC LIMIT 10", $this->db->real_escape_string($id), $days, $limit));
4567
4568 $countries = $this->db->query(sprintf("SELECT `users`.`country`, COUNT(`country`) AS `count` FROM `views`,`users` WHERE `views`.`track` = '%s' AND `users`.`country` != '' AND `views`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `country` ORDER BY `count` DESC LIMIT %s", $this->db->real_escape_string($id), $days, $limit));
4569
4570 $cities = $this->db->query(sprintf("SELECT `users`.`city`, COUNT(`city`) AS `count` FROM `views`,`users` WHERE `views`.`track` = '%s' AND `users`.`city` != '' AND `views`.`by` = `users`.`idu` AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`) GROUP BY `city` ORDER BY `count` DESC LIMIT %s", $this->db->real_escape_string($id), $days, $limit));
4571 } else {
4572 $query = $this->db->query(sprintf("SELECT(SELECT COUNT(track) FROM `views` WHERE `track` = '%s' AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as plays, (SELECT COUNT(track) FROM `downloads` WHERE `track` = '%s' AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as downloads, (SELECT COUNT(track) FROM `likes` WHERE `track` = '%s' AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as likes, (SELECT COUNT(tid) FROM `comments` WHERE `tid` = '%s' AND DATE_SUB(CURDATE(),INTERVAL %s DAY) <= date(`time`)) as comments", $this->db->real_escape_string($id), $days, $this->db->real_escape_string($id), $days, $this->db->real_escape_string($id), $days, $this->db->real_escape_string($id), $days));
4573 }
4574
4575 if($type) {
4576 if($this->getProStatus($this->id, 1)) {
4577 while($row = $played->fetch_assoc()) {
4578 $x .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50">'.realName($row['username'], $row['first_name'], $row['last_name']).'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4579 }
4580 $i = 1;
4581 while($row = $countries->fetch_assoc()) {
4582 $y .= '<div class="user-stats-row"><div class="user-stats-title"><span class="user-stats-row-count">'.$i.'</span>'.$row['country'].'</div><div class="user-stats-count">'.$row['count'].'</div></div>';
4583 $i++;
4584 }
4585 $i = 1;
4586 while($row = $cities->fetch_assoc()) {
4587 $z .= '<div class="user-stats-row"><div class="user-stats-title"><span class="user-stats-row-count">'.$i.'</span>'.$row['city'].'</div><div class="user-stats-count">'.$row['count'].'</div></div>';
4588 $i++;
4589 }
4590 while($row = $downloaded->fetch_assoc()) {
4591 $a .= '<div class="user-stats-row"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><div class="user-stats-title"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50">'.realName($row['username'], $row['first_name'], $row['last_name']).'</div><div class="user-stats-count">'.$row['count'].'</div></a></div>';
4592 }
4593
4594 $rows['played'] = $x;
4595 $rows['countries'] = $y;
4596 $rows['cities'] = $z;
4597 $rows['downloaded'] = $a;
4598 } else {
4599 $rows['gopro'] = $this->goProMessage(0);
4600 }
4601
4602 return $rows;
4603 } else {
4604 return $query->fetch_assoc();
4605 }
4606 }
4607
4608 function getLikes($start = null, $type = null, $value = null) {
4609 // Type 0: Return the likes count
4610 // Type 1: Return the liked tracks
4611 // Type 2: Return the likes from tracks
4612
4613 if($type) {
4614 global $LNG, $CONF;
4615 if($type == 1) {
4616 // If the $start value is 0, empty the query;
4617 if($start == 0) {
4618 $start = '';
4619 } else {
4620 $start = 'AND `likes`.`id` < \''.$this->db->real_escape_string($start).'\'';
4621 }
4622
4623 $query = sprintf("SELECT `likes`.`id` as `extra_id`, `likes`.`time` as `time`,
4624 `tracks`.`id` as `id`, `tracks`.`title` as `title`, `tracks`.`name` as `name`, `tracks`.`art` as `art`, `tracks`.`public` as `public`, `tracks`.`tag` as `tag`,
4625 `users`.`idu` as `idu`, `users`.`username` as `username`, `users`.`first_name` as `first_name`, `users`.`last_name` as `last_name`, `users`.`image` as `image`
4626 FROM `likes`, `tracks`, `users` WHERE `likes`.`by` = '%s' AND `likes`.`track` = `tracks`.`id` AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`public` = 1 %s ORDER BY `likes`.`time` DESC LIMIT %s", $this->profile_data['idu'], $start, ($this->per_page + 1));
4627
4628 return $this->getTracks($query, 'loadLikes', '\''.$this->profile_data['username'].'\', \''.$this->profile_data['idu'].'\'');
4629 } elseif($type == 2) {
4630 if($start == 0) {
4631 $start = '';
4632 } else {
4633 // Else, build up the query
4634 $start = 'AND `likes`.`id` < \''.$this->db->real_escape_string($start).'\'';
4635 }
4636 $query = $this->db->query(sprintf("SELECT * FROM `likes`, `users` WHERE `likes`.`track` = '%s' AND `likes`.`by` = `users`.`idu` %s ORDER BY `likes`.`id` DESC LIMIT %s", $this->db->real_escape_string($value), $start, ($this->per_page + 1)));
4637
4638 // Declare the rows array
4639 $rows = array();
4640 while($row = $query->fetch_assoc()) {
4641 // Store the result into the array
4642 $rows[] = $row;
4643 }
4644
4645 // Decide whether the load more will be shown or not
4646 if(array_key_exists($this->per_page, $rows)) {
4647 $loadmore = 1;
4648
4649 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
4650 array_pop($rows);
4651 }
4652
4653 foreach($rows as $row) {
4654 $subscribersList = $this->getSubs($row['idu'], 1, null);
4655 $tracks = $this->countSongs($row['idu']);
4656 $fullName = realName(null, $row['first_name'], $row['last_name']);
4657 $output .= '<div class="list-container">
4658 <div class="track-inner">
4659 <div id="subscribe'.$row['idu'].'">'.$this->getSubscribe(0, array('idu' => $row['idu'], 'username' => $row['username'], 'private' => $row['private']), 1).'</div>'.$this->chatButton($row['idu'], $row['username'], 1).'
4660 <div class="list-avatar" id="avatar'.$row['idu'].'">
4661 <a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">
4662 <img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=100&h=100">
4663 </a>
4664 </div>
4665 <div class="list-top" id="user'.$row['idu'].'">
4666 <div class="track-author" id="author'.$row['idu'].'">
4667 <a onmouseover="profileCard('.$row['idu'].', '.$row['idu'].', 3, 0);" onmouseout="profileCard(0, 0, 0, 1);" onclick="profileCard(0, 0, 1, 1);" href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">'.$row['username'].'</a>'.(($this->getProStatus($row['idu'])) ? '<a href="'.$this->url.'/index.php?a=pro" rel="loadpage" title="'.$LNG['pro_user'].'"><span class="pro-icon pro-small"></span></a>' : '').'
4668 </div>
4669 '.((location($row['country'], $row['city']) || !empty($fullName)) ? '<div class="list-time">'.$fullName.''.((location($row['country'], $row['city'])) ? ' ('.location($row['country'], $row['city']).')' : ' ').'</div>' : '').'
4670 <div class="sidebar-suggestions-small">'.(($tracks) ? '<div class="sidebar-suggestions-tracks" title="'.$tracks.' '.$LNG['tracks'].'">'.$tracks.'</div>' : '').'
4671 '.(($subscribersList[1]) ? '<div class="sidebar-suggestions-followers" title="'.$subscribersList[1].' '.$LNG['subscribers'].'">'.$subscribersList[1].'</div>' : '').'</div>
4672 </div>
4673 </div>
4674 </div>';
4675 $last = $row['id'];
4676 }
4677
4678 if($loadmore) {
4679 $output .= '<div id="load-more">
4680 <div class="load_more"><a onclick="loadLikes('.$last.', \''.$value.'\', \''.$type.'\')" id="infinite-load">'.$LNG['load_more'].'</a></div>
4681 </div>';
4682 }
4683
4684 return $output;
4685 }
4686 } else {
4687 $query = $this->db->query(sprintf("SELECT count(`likes`.`id`) FROM `likes`,`tracks` WHERE `likes`.`by` = '%s' AND `likes`.`track` = `tracks`.`id` AND `tracks`.`public` = '1'", $this->profile_data['idu']));
4688
4689 // Store the array results
4690 $result = $query->fetch_array();
4691
4692 // Return the likes value
4693 return $result[0];
4694 }
4695 }
4696
4697 function getHashtags($value, $limit) {
4698 global $LNG;
4699
4700 $query = $this->db->query(sprintf("SELECT tracks.tag FROM tracks WHERE tracks.tag LIKE '%s'", '%'.$this->db->real_escape_string($value).'%', $limit));
4701
4702 // Store the hashtags into a string
4703 while($row = $query->fetch_assoc()) {
4704 $hashtags .= $row['tag'];
4705 }
4706
4707 $output = '<div class="search-content"><div class="search-results"><div class="notification-inner"><a onclick="manageResults(2)">'.$LNG['view_all_results'].'</a> <a onclick="manageResults(0)" title="'.$LNG['close_results'].'"><div class="close_btn"></div></a></div>';
4708 // If there are no results
4709 if(empty($hashtags)) {
4710 $output .= '<div class="message-inner">'.$LNG['no_results'].'</div>';
4711 } else {
4712 // Explore each hashtag string into an array
4713 $explode = explode(',', $hashtags);
4714
4715 // Merge all matched arrays into a string
4716 $rows = array_unique(array_map('strtolower', $explode));
4717
4718 $i = 1;
4719 foreach($rows as $row) {
4720 if(stripos($row, $value) !== false) {
4721 $output .= '<div class="hashtag">
4722 <a href="'.$this->url.'/index.php?a=explore&filter='.$row.'" rel="loadpage">
4723 <div class="hashtag-inner">
4724 #'.$row.'
4725 </div>
4726 </a>
4727 </div>';
4728 if($i == $limit) break;
4729 $i++;
4730 }
4731 }
4732 }
4733 $output .= '</div></div>';
4734 return $output;
4735 }
4736
4737 function searchTracks($start, $value) {
4738 // If the $start value is 0, empty the query;
4739 if($start == 0) {
4740 $start = '';
4741 } else {
4742 // Else, build up the query
4743 $start = 'AND tracks.id < \''.$this->db->real_escape_string($start).'\'';
4744 }
4745
4746 $query = sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`title` LIKE '%s' AND `tracks`.`uid` = `users`.`idu` %s AND `tracks`.`public` = 1 ORDER BY tracks.id DESC LIMIT %s", '%'.$this->db->real_escape_string($value).'%', $start, ($this->per_page + 1));
4747
4748 return $this->getTracks($query, 'searchTracks', '\''.$value.'\'');
4749 }
4750
4751 function getSearch($start, $per_page, $value, $filter = null, $type = null) {
4752 // $type - switches the type for live search or static one [search page]
4753 global $LNG, $CONF;
4754
4755 // Define the query type
4756 // Query Type 0: Normal search username, first and last name
4757 // Query Type 1: Exact Email search
4758 if(filter_var($value, FILTER_VALIDATE_EMAIL)) {
4759 $qt = 1;
4760 } else {
4761 $qt = 0;
4762 }
4763
4764 if($qt == 1) {
4765 $query = $this->db->query(sprintf("SELECT `idu`, `username`, `first_name`, `last_name`, `country`, `city`, `image`, 1 as `profile` FROM `users` WHERE `email` = '%s' LIMIT 1", $this->db->real_escape_string($value)));
4766 } else {
4767 // If type is set, search for music as well
4768 if($type) {
4769 $query = $this->db->query(sprintf("SELECT `idu`, `username`, `first_name`, `last_name`, `country`, `city`, `image`, 1 as `profile`, sum(relevance) FROM (SELECT *, 100 AS relevance FROM users WHERE username = '%s' UNION SELECT *, 10 AS relevance FROM users WHERE username like '%s' UNION SELECT *, 5 AS relevance FROM users WHERE concat_ws(' ', `first_name`, `last_name`) LIKE '%s') results GROUP BY username ORDER BY sum(relevance) DESC LIMIT %s, %s", $this->db->real_escape_string($value), '%'.$this->db->real_escape_string($value).'%', '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));
4770
4771 // Sometimes the query might fail due to the fact that utf8 characters are being passed and the `username` sql field does not allow special chars
4772 if(!$query) {
4773 $query = $this->db->query(sprintf("SELECT `idu`, `username`, `first_name`, `last_name`, `country`, `city`, `image`, 1 as `profile` FROM `users` WHERE concat_ws(' ', `first_name`, `last_name`) LIKE '%s' ORDER BY `idu` DESC, `idu` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));
4774 }
4775
4776 $music = $this->db->query(sprintf("SELECT `id`, `title` as `username`, `art` as `image`, 0 as `profile` FROM `tracks` WHERE `title` LIKE '%s' AND `public` = 1 ORDER BY `id` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), $per_page));
4777
4778 while($row = $music->fetch_assoc()) {
4779 $rows[] = $row;
4780 }
4781
4782 } else {
4783 $query = $this->db->query(sprintf("SELECT `idu`, `username`, `first_name`, `last_name`, `country`, `city`, `image`, 1 as `profile`, sum(relevance) FROM (SELECT *, 100 AS relevance FROM users WHERE username = '%s' UNION SELECT *, 10 AS relevance FROM users WHERE username like '%s' UNION SELECT *, 5 AS relevance FROM users WHERE concat_ws(' ', `first_name`, `last_name`) LIKE '%s') results GROUP BY username ORDER BY sum(relevance) DESC LIMIT %s, %s", $this->db->real_escape_string($value), '%'.$this->db->real_escape_string($value).'%', '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), ($per_page+1)));
4784
4785 // Sometimes the query might fail due to the fact that utf8 characters are being passed and the `username` sql field does not allow special chars
4786 if(!$query) {
4787 $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE concat_ws(' ', `first_name`, `last_name`) LIKE '%s' ORDER BY `idu` DESC, `idu` DESC LIMIT %s, %s", '%'.$this->db->real_escape_string($value).'%', $this->db->real_escape_string($start), ($per_page + 1)));
4788 }
4789 }
4790 }
4791
4792 while($row = $query->fetch_assoc()) {
4793 $rows[] = $row;
4794 }
4795
4796 // If the query type is live, hide the load more button
4797 if(array_key_exists($per_page, $rows)) {
4798 $loadmore = 1;
4799 if($type) {
4800 $loadmore = 0;
4801 } else {
4802 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
4803 array_pop($rows);
4804 }
4805 }
4806
4807 // If the query type is live show the proper style
4808 if($type) {
4809 $output = '<div class="search-content"><div class="search-results"><div class="notification-inner"><a onclick="manageResults(1)">'.$LNG['view_all_results'].'</a> <a onclick="manageResults(0)" title="'.$LNG['close_results'].'"><div class="close_btn"></div></a></div>';
4810 // If there are no results
4811 if(empty($rows)) {
4812 $output .= '<div class="track-inner">'.$LNG['no_results'].'</div>';
4813 } else {
4814 foreach($rows as $row) {
4815 // Verify whether the result is for a profile or not
4816 if($row['profile']) {
4817 $url = '<a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">';
4818 $image = '<img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=50&h=50">';
4819 $kind = '<img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/profile.png" title="'.$LNG['title_profile'].'">';
4820 $x = 1;
4821 } else {
4822 $url = '<a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" rel="loadpage">';
4823 $image = '<img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=m&w=50&h=50">';
4824 $kind = '<img src="'.$this->url.'/'.$CONF['theme_url'].'/images/icons/track.png" title="'.$LNG['track'].'">';
4825 $x = 0;
4826 }
4827 $output .= $url.'
4828 <div class="track-inner">
4829 <div class="search-image">
4830 '.$image.'
4831 </div>
4832 <div class="search-text">
4833 <div>
4834 '.realName($row['username'], $row['first_name'], $row['last_name']).''.((location($row['country'], $row['city'])) ? ' ('.location($row['country'], $row['city']).')' : ' ').' '.(($this->getProStatus($row['idu']) && $x) ? '<span class="pro-icon pro-small" title="'.$LNG['pro_user'].'"></span>' : '').'
4835 </div>
4836 </div><div class="search-icons">'.$kind.'</div>
4837 </div>
4838 </a>';
4839 }
4840 }
4841 $output .= '</div></div>';
4842 } else {
4843 // If there are no results
4844 if(empty($rows)) {
4845 $output .= '<div class="message-inner">'.$LNG['no_results'].'</div>';
4846 } else {
4847 foreach($rows as $row) {
4848 $subscribersList = $this->getSubs($row['idu'], 1, null);
4849 $tracks = $this->countSongs($row['idu']);
4850 $fullName = realName(null, $row['first_name'], $row['last_name']);
4851
4852 $output .= '<div class="list-container">
4853 <div class="list-inner">
4854 <div id="subscribe'.$row['idu'].'">'.$this->getSubscribe(0, array('idu' => $row['idu'], 'username' => $row['username'], 'private' => $row['private']), 1).'</div>'.$this->chatButton($row['idu'], $row['username'], 1).'
4855 <div class="list-avatar" id="avatar'.$row['idu'].'">
4856 <a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">
4857 <img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=100&h=100">
4858 </a>
4859 </div>
4860 <div class="list-top" id="user'.$row['idu'].'">
4861 <div class="track-author" id="author'.$row['idu'].'">
4862 <a onmouseover="profileCard('.$row['idu'].', '.$row['idu'].', 3, 0);" onmouseout="profileCard(0, 0, 0, 1);" onclick="profileCard(0, 0, 1, 1);" href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">'.$row['username'].'</a>'.(($this->getProStatus($row['idu'])) ? '<a href="'.$this->url.'/index.php?a=pro" rel="loadpage" title="'.$LNG['pro_user'].'"><span class="pro-icon pro-small"></span></a>' : '').'
4863 </div>
4864 '.((location($row['country'], $row['city']) || !empty($fullName)) ? '<div class="list-time">'.$fullName.''.((location($row['country'], $row['city'])) ? ' ('.location($row['country'], $row['city']).')' : ' ').'</div>' : '').'
4865 <div class="sidebar-suggestions-small">'.(($tracks) ? '<div class="sidebar-suggestions-tracks" title="'.$tracks.' '.$LNG['tracks'].'">'.$tracks.'</div>' : '').'
4866 '.(($subscribersList[1]) ? '<div class="sidebar-suggestions-followers" title="'.$subscribersList[1].' '.$LNG['subscribers'].'">'.$subscribersList[1].'</div>' : '').'</div>
4867 </div>
4868 </div>
4869 </div>';
4870 }
4871 }
4872 }
4873 if($loadmore) {
4874 $output .= '<div id="load-more">
4875 <div class="load_more"><a onclick="loadPeople('.($start + $per_page).', \''.$value.'\', \''.$filter.'\')" id="infinite-load">'.$LNG['load_more'].'</a></div>
4876 </div>';
4877 }
4878
4879 return $output;
4880 }
4881
4882 function listSubs($type = null) {
4883 global $LNG, $CONF;
4884 $rows = $this->subsList[0];
4885
4886 if(array_key_exists($this->s_per_page, $rows)) {
4887 $loadmore = 1;
4888
4889 // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed
4890 array_pop($rows);
4891 }
4892
4893 foreach($rows as $row) {
4894 $subscribersList = $this->getSubs($row['idu'], 1, null);
4895 $tracks = $this->countSongs($row['idu']);
4896 $fullName = realName(null, $row['first_name'], $row['last_name']);
4897 $output .= '<div class="list-container">
4898 <div class="track-inner">
4899 <div id="subscribe'.$row['idu'].'">'.$this->getSubscribe(0, array('idu' => $row['idu'], 'username' => $row['username'], 'private' => $row['private']), 1).'</div>'.$this->chatButton($row['idu'], $row['username'], 1).'
4900 <div class="list-avatar" id="avatar'.$row['idu'].'">
4901 <a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">
4902 <img src="'.$this->url.'/thumb.php?src='.$row['image'].'&t=a&w=100&h=100">
4903 </a>
4904 </div>
4905 <div class="list-top" id="user'.$row['idu'].'">
4906 <div class="track-author" id="author'.$row['idu'].'">
4907 <a onmouseover="profileCard('.$row['idu'].', '.$row['idu'].', 3, 0);" onmouseout="profileCard(0, 0, 0, 1);" onclick="profileCard(0, 0, 1, 1);" href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage">'.$row['username'].'</a>'.(($this->getProStatus($row['idu'])) ? '<a href="'.$this->url.'/index.php?a=pro" rel="loadpage" title="'.$LNG['pro_user'].'"><span class="pro-icon pro-small"></span></a>' : '').'
4908 </div>
4909 '.((location($row['country'], $row['city']) || !empty($fullName)) ? '<div class="list-time">'.$fullName.''.((location($row['country'], $row['city'])) ? ' ('.location($row['country'], $row['city']).')' : ' ').'</div>' : '').'
4910 <div class="sidebar-suggestions-small">'.(($tracks) ? '<div class="sidebar-suggestions-tracks" title="'.$tracks.' '.$LNG['tracks'].'">'.$tracks.'</div>' : '').'
4911 '.(($subscribersList[1]) ? '<div class="sidebar-suggestions-followers" title="'.$subscribersList[1].' '.$LNG['subscribers'].'">'.$subscribersList[1].'</div>' : '').'</div>
4912 </div>
4913 </div>
4914 </div>';
4915 $last = $row['id'];
4916 }
4917 if($loadmore) {
4918 $output .= '<div id="load-more">
4919 <div class="load_more"><a onclick="loadSubs('.$last.', '.$type.', '.$this->profile_data['idu'].')" id="infinite-load">'.$LNG['load_more'].'</a></div>
4920 </div>';
4921 }
4922 return $output;
4923 }
4924
4925 function getSubs($id, $type, $start = null) {
4926 // Type: 0 Get the subscriptions
4927 // Type: 1 Get the subscribers
4928 if($type == 0) {
4929 // If the $start it set (used to list the users on dedicated profile pages)
4930 if(is_numeric($start)) {
4931 if($start == 0) {
4932 $start = '';
4933 } else {
4934 $start = 'AND `relations`.`id` < \''.$this->db->real_escape_string($start).'\'';
4935 }
4936 $limit = 'LIMIT '.($this->s_per_page + 1);
4937 }
4938 $query = sprintf("SELECT * FROM `relations`, `users` WHERE `relations`.`subscriber` = '%s' AND `relations`.`leader` = `users`.`idu` $start ORDER BY `relations`.`id` DESC $limit", $this->db->real_escape_string($id));
4939 } else {
4940 if(is_numeric($start)) {
4941 if($start == 0) {
4942 $start = '';
4943 } else {
4944 $start = 'AND `relations`.`id` < \''.$this->db->real_escape_string($start).'\'';
4945 }
4946 $limit = 'LIMIT '.($this->s_per_page + 1);
4947 }
4948 $query = sprintf("SELECT * FROM `relations`, `users` WHERE `relations`.`leader` = '%s' AND `relations`.`subscriber` = `users`.`idu` $start ORDER BY `relations`.`id` DESC $limit", $this->db->real_escape_string($id));
4949 }
4950
4951 $result = $this->db->query($query);
4952 while($row = $result->fetch_assoc()) {
4953 $array [] = $row;
4954 }
4955 return array($array, $total = $result->num_rows);
4956 }
4957
4958 function getActions($id, $type = null) {
4959 global $LNG;
4960
4961 // If type 1 do the like
4962 if($type == 1) {
4963 // Verify the Like state
4964 $verify = $this->verifyLike($id);
4965
4966 // Verify if track exists
4967 $result = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id)));
4968 if($result->num_rows == 0) {
4969 return $LNG['like_track_not_exist'];
4970 }
4971 if(!$verify) {
4972 // Prepare the INSERT statement
4973 $stmt = $this->db->prepare("INSERT INTO `likes` (`track`, `by`) VALUES ('{$this->db->real_escape_string($id)}', '{$this->db->real_escape_string($this->id)}')");
4974
4975 // Execute the statement
4976 $stmt->execute();
4977
4978 // Save the affected rows
4979 $affected = $stmt->affected_rows;
4980
4981 // Close the statement
4982 $stmt->close();
4983 if($affected) {
4984 $this->db->query("UPDATE `tracks` SET `likes` = `likes` + 1, `time` = `time` WHERE id = '{$this->db->real_escape_string($id)}'");
4985
4986 $user = $result->fetch_assoc();
4987
4988 // Do the INSERT notification
4989 $insertNotification = $this->db->query(sprintf("INSERT INTO `notifications` (`from`, `to`, `parent`, `type`, `read`) VALUES ('%s', '%s', '%s', '2', '0')", $this->db->real_escape_string($this->id), $user['uid'], $user['id']));
4990
4991 // If email on likes is enabled in admin settings
4992 if($this->email_like) {
4993 // If user has emails on like enabled and he's not liking his own track
4994 if($user['email_like'] && ($this->id !== $user['idu'])) {
4995 // Send e-mail
4996 sendMail($user['email'], sprintf($LNG['ttl_like_email'], $this->username), sprintf($LNG['like_email'], realName($user['username'], $user['first_name'], $user['last_name']), $this->url.'/index.php?a=profile&u='.$this->username, $this->username, $this->url.'/index.php?a=track&id='.$id, $this->title, $this->url.'/index.php?a=settings&b=notifications'), $this->email);
4997 }
4998 }
4999 }
5000 } else {
5001 $x = 'already_liked';
5002 }
5003 } elseif($type == 2) {
5004 // Verify the Like state
5005 $verify = $this->verifyLike($id);
5006
5007 // Verify if track exists
5008 $result = $this->db->query(sprintf("SELECT `id` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id)));
5009 if($result->num_rows == 0) {
5010 return $LNG['like_track_not_exist'];
5011 }
5012 if($verify) {
5013 // Prepare the DELETE statement
5014 $stmt = $this->db->prepare("DELETE FROM `likes` WHERE `track` = '{$this->db->real_escape_string($id)}' AND `by` = '{$this->db->real_escape_string($this->id)}'");
5015
5016 // Execute the statement
5017 $stmt->execute();
5018
5019 // Save the affected rows
5020 $affected = $stmt->affected_rows;
5021
5022 // Close the statement
5023 $stmt->close();
5024 if($affected) {
5025 $this->db->query("UPDATE `tracks` SET `likes` = `likes` - 1, `time` = `time` WHERE id = '{$this->db->real_escape_string($id)}'");
5026 $this->db->query("DELETE FROM `notifications` WHERE `parent` = '{$this->db->real_escape_string($id)}' AND `type` = '2' AND `from` = '{$this->db->real_escape_string($this->id)}'");
5027 }
5028 } else {
5029 $x = 'already_disliked';
5030 }
5031 }
5032
5033 // Get the likes, views, and other info
5034 $query = sprintf("SELECT `id`, `uid`, `title`, `name`, `buy`, `download`, `public`, `likes`, `downloads`, `views` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id));
5035
5036 // Run the query
5037 $result = $this->db->query($query);
5038
5039 // Get the array element for the like
5040 $get = $result->fetch_assoc();
5041
5042 // Determine whether to show the delete/privacy buttons or not
5043 if($this->id == $get['uid']) { // If it's current username is the same with the current author
5044 if($get['public'] == 1) {
5045 $privacy = '<div class="public-button" onclick="privacy('.$get['id'].', 0, 0)" title="'.$LNG['this_track_public'].'"></div>';
5046 $delete = '<div id="delete-button-'.$get['id'].'" class="delete-button" onclick="delete_modal('.$get['id'].', 1)" title="'.$LNG['delete'].'"></div>';
5047 } else {
5048 $privacy = '<div class="private-button" onclick="privacy('.$get['id'].', 1, 0)" title="'.$LNG['this_track_private'].'"></div>';
5049 $delete = '<div id="delete-button-'.$get['id'].'" class="delete-button" onclick="delete_modal('.$get['id'].', 1)" title="'.$LNG['delete'].'"></div>';
5050 }
5051 } else { // If the current username is not the same as the author
5052 $privacy = '';
5053 $delete = '';
5054 }
5055
5056 // Verify the Like state
5057 $verify = $this->verifyLike($id);
5058
5059 if($verify) {
5060 $state = $LNG['dislike'];
5061 $y = 2;
5062 } else {
5063 $state = $LNG['like'];
5064 $y = 1;
5065 }
5066
5067 if($this->l_per_post) {
5068 $query = sprintf("SELECT * FROM `likes`, `users` WHERE `likes`.`track` = '%s' and `likes`.`by` = `users`.`idu` ORDER BY `likes`.`id` DESC LIMIT %s", $this->db->real_escape_string($id), $this->db->real_escape_string($this->l_per_post + 1));
5069
5070 $result = $this->db->query($query);
5071 while($row = $result->fetch_assoc()) {
5072 $array[] = $row;
5073 }
5074
5075 $i = 0;
5076 foreach($array as $row) {
5077 // If the likes counter hits the l_per_post+1 then show the load more button
5078 if($i == $this->l_per_post) {
5079 $likes .= '<a href="'.$this->url.'/index.php?a=track&id='.$id.'&type=likes" rel="loadpage"><div class="likes-plus" title="'.$LNG['view_more'].'"></div></a>';
5080 } else {
5081 $likes .= '<a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" rel="loadpage"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&w=25&h=25&t=a" title="'.realName($row['username'], $row['first_name'], $row['last_name']).' '.$LNG['liked_this'].'" /></a> ';
5082 }
5083 $i++;
5084 }
5085
5086 // If any likes are available
5087 if($i) {
5088 $people .= '<div class="track-likes" id="users_likes'.$id.'" style="'.((empty($likes)) ? 'margin: 0;' : '').'">'.$likes.'</div>';
5089 }
5090 }
5091
5092 // Show the buy button
5093 if(!empty($get['buy'])) {
5094 $buy = '<a href="'.$get['buy'].'" target="_blank" rel="nofollow"><div class="buy-button" title="'.$LNG['buy'].'"></div></a>';
5095 }
5096
5097 // Get the filename extension
5098 $ext = pathinfo($get['name'], PATHINFO_EXTENSION);
5099
5100 // Show the download button
5101 if(!empty($get['download'])) {
5102 $download = '<a href="'.$this->url.'/uploads/tracks/'.$get['name'].'" target="_blank" download="'.$get['title'].'.'.$ext.'" onclick="addDownload('.$id.');"><div class="download-button" title="'.$LNG['download'].'"></div></a>';
5103 }
5104
5105 $getComments = $this->db->query(sprintf("SELECT COUNT(*) FROM `comments` WHERE `tid` = '%s'", $this->db->real_escape_string($id)));
5106 $comments = $getComments->fetch_row();
5107
5108 $url = $this->url.'/index.php?a=track&id='.$id;
5109
5110 // Actions
5111 $views_stats = ($get['views']) ? '<a href="'.$this->url.'/index.php?a=track&id='.$id.'" rel="loadpage"><div class="counter views_counter" title="'.sprintf($LNG['listened_x_times'], $get['views']).'">'.$get['views'].'</div></a>' : '';
5112 $comments_stats = ($comments[0]) ? '<a href="'.$this->url.'/index.php?a=track&id='.$id.'" rel="loadpage"><div class="counter comments_counter" title="'.$comments[0].' '.$LNG['comments'].'">'.$comments[0].'</div></a>' : '';
5113 $likes_stats = ($get['likes']) ? '<a href="'.$this->url.'/index.php?a=track&id='.$id.'&type=likes" rel="loadpage"><div class="counter like_btn" id="like_btn'.$id.'" title="'.$get['likes'].' '.$LNG['likes'].'">'.$get['likes'].'</div></a>' : '';
5114 $downloads_stats = ($get['downloads']) ? '<a href="'.$this->url.'/index.php?a=track&id='.$id.'" rel="loadpage"><div class="counter downloads_counter" title="'.sprintf($LNG['downloaded_x_times'], $get['downloads']).'">'.$get['downloads'].'</div></a>' : '';
5115
5116 $actions = $people.'<div class="track-buttons-container"><div class="'.(($y == 2) ? 'liked' : 'like').'-button" onclick="doLike('.$id.', '.$y.')" id="doLike'.$id.'" title="'.$state.'"><span class="action-text">'.$state.'</span></div><div class="playlist-button" onclick="playlist('.$id.', 1)" title="'.$LNG['add'].'"><span class="action-text">'.$LNG['add'].'</span></div><div class="share-button" onclick="share('.$id.', 1)" title="'.$LNG['share'].'"><span class="action-text">'.$LNG['share'].'</span></div>'.$buy.$download.$delete.'<span id="privacy'.$get['id'].'">'.$privacy.'</span></div> <div class="track-stats">'.$views_stats.$comments_stats.$likes_stats.$downloads_stats.'</div>';
5117
5118 // If the current user is empty (not logged-in)
5119 if(empty($this->id)) {
5120 $actions = $people.'<div class="track-buttons-container"><div class="like-button" onclick="connect_modal()" id="doLike'.$id.'" title="'.$LNG['like'].'"><span class="action-text">'.$LNG['like'].'</span></div><div class="playlist-button" onclick="connect_modal()" title="'.$LNG['add'].'"><span class="action-text">'.$LNG['add'].'</span></div><div class="share-button" onclick="share('.$id.', 1)" title="'.$LNG['share'].'"><span class="action-text">'.$LNG['share'].'</span></div>'.$buy.$download.'</div> <div class="track-stats">'.$views_stats.$comments_stats.$likes_stats.$downloads_stats.'</div>';
5121 }
5122
5123 // Display an error if the user tries to do the same action twice (e.g: liking the same song from two different pages)
5124 if(isset($x)) {
5125 return '<div class="track-buttons-container">'.$LNG["$x"].'</div> <a href="'.$url.'" rel="loadpage"><div class="track-stats">'.$views_stats.$comments_stats.$likes_stats.$downloads_stats.'</div>';
5126 }
5127 return $actions;
5128 }
5129
5130 function verifyLike($id) {
5131 $result = $this->db->query(sprintf("SELECT * FROM `likes` WHERE `track` = '%s' AND `by` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($this->id)));
5132
5133 // If the Message/Comment exists
5134 return ($result->num_rows) ? 1 : 0;
5135 }
5136
5137 function addView($id) {
5138 // Check if the track exists
5139 $result = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id)));
5140
5141 // If the result number is true
5142 if($result->num_rows) {
5143
5144 // Update the track views field
5145 $this->db->query(sprintf("UPDATE `tracks` SET `time` = `time`, `views` = (`views` + 1) WHERE `id` = '%s'", $this->db->real_escape_string($id)));
5146
5147 // If the user who plays the song is logged in, add the count statistics
5148 if($this->id) {
5149 $this->db->query("INSERT INTO `views` (`track`, `by`) VALUES ('{$this->db->real_escape_string($id)}', '{$this->db->real_escape_string($this->id)}')");
5150 }
5151 }
5152 }
5153
5154 function addDownload($id) {
5155 // Check if the track exists
5156 $result = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id)));
5157
5158 // If the result number is true
5159 if($result->num_rows) {
5160
5161 // Update the track views field
5162 $this->db->query(sprintf("UPDATE `tracks` SET `time` = `time`, `downloads` = (`downloads` + 1) WHERE `id` = '%s'", $this->db->real_escape_string($id)));
5163
5164 // If the user who downloads the song is logged in, add the count statistics
5165 if($this->id) {
5166 $this->db->query("INSERT INTO `downloads` (`track`, `by`) VALUES ('{$this->db->real_escape_string($id)}', '{$this->db->real_escape_string($this->id)}')");
5167 }
5168 }
5169 }
5170
5171 function getBlocked($id, $type = null) {
5172 // Type 0: Output the button state
5173 // Type 1: Block/Unblock a user
5174
5175 $profile = $this->profileData(null, $id);
5176
5177 // If the username does not exist, return nothing
5178 if(empty($profile)) {
5179 return false;
5180 } else {
5181 // Verify if there is any block issued for this username
5182 $checkBlocked = $this->db->query(sprintf("SELECT * FROM `blocked` WHERE `uid` = '%s' AND `by` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($this->id)));
5183
5184 // If the Message/Comment exists
5185 $state = $checkBlocked->num_rows;
5186
5187 // If type 1: Add/Remove
5188 if($type) {
5189 // If there is a block issued, remove the block
5190 if($state) {
5191 // Remove the block
5192 $this->db->query(sprintf("DELETE FROM `blocked` WHERE `uid` = '%s' AND `by` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($this->id)));
5193
5194 // Block variable
5195 $y = 0;
5196 } else {
5197 // Insert the block
5198 $this->db->query(sprintf("INSERT INTO `blocked` (`uid`, `by`) VALUES ('%s', '%s')", $this->db->real_escape_string($id), $this->db->real_escape_string($this->id)));
5199
5200 // Unblock variable
5201 $y = 1;
5202 }
5203 return $this->outputBlocked($id, $profile, $y);
5204 } else {
5205 return $this->outputBlocked($id, $profile, $state);
5206 }
5207 }
5208 }
5209
5210 function outputBlocked($id, $profile, $state) {
5211 global $LNG;
5212 if($state) {
5213 $x = '<span class="class="unblock-button""><a onclick="doBlock('.$id.', 1)" title="Unblock '.realName($profile['username'], $profile['first_name'], $profile['last_name']).'">'.$LNG['unblock'].'</a></span>';
5214 } else {
5215 $x = '<a onclick="doBlock('.$id.', 1)" title="Block '.realName($profile['username'], $profile['first_name'], $profile['last_name']).'">'.$LNG['block'].'</a>';
5216 }
5217 return $x;
5218 }
5219}
5220class paypalApi {
5221 public $username;
5222 public $password;
5223 public $signature;
5224
5225 function post($method, $params, $mode) {
5226 // Method: Required
5227 // Parameters: An array containing the requested parameters
5228
5229 // The request URL
5230 $url = "https://api-3t".$mode.".paypal.com/nvp";
5231
5232 // Version of the API
5233 $version = '116.0';
5234
5235 // Construct the query params
5236 // Set the API method, version, and API credentials.
5237 $credentials = array('METHOD' => $method, 'VERSION' => $version, 'USER' => $this->username, 'PWD' => $this->password, 'SIGNATURE' => $this->signature);
5238 $params = array_merge($credentials, $params);
5239
5240 // Set the curl parameters.
5241 if(function_exists('curl_exec')) {
5242 $ch = curl_init();
5243 curl_setopt($ch, CURLOPT_URL, $url);
5244 curl_setopt($ch, CURLOPT_VERBOSE, 1);
5245
5246 // Turn off the server and peer verification (TrustManager Concept).
5247 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
5248 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
5249
5250 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
5251 curl_setopt($ch, CURLOPT_POST, 1);
5252 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
5253
5254 $response = curl_exec($ch);
5255 }
5256
5257 if(empty($response)) {
5258 $opts = array('http' =>
5259 array(
5260 'protocol_version' => '1.1',
5261 'method' => 'POST',
5262 'header' => 'Content-type: application/x-www-form-urlencoded',
5263 'content' => http_build_query($params)
5264 )
5265 );
5266 $context = stream_context_create($opts);
5267 $response = file_get_contents($url, false, $context);
5268 }
5269
5270 // Parse the response
5271 parse_str($response, $responseArr);
5272
5273 // If the request fails
5274 if(empty($responseArr) || !array_key_exists('ACK', $responseArr)) {
5275 global $LNG;
5276 // Mimic a fake response
5277 return array('L_SHORTMESSAGE0' => $LNG['error'], 'L_LONGMESSAGE0' => $LNG['payment_error_0'], 'ACK' => 'REQUEST_FAILED');
5278 }
5279
5280 return $responseArr;
5281 }
5282}
5283class player {
5284 public $db;
5285 public $url;
5286 public $l_per_post;
5287 public $title;
5288
5289 function getEmbed($id) {
5290 global $LNG;
5291 $query = $this->db->query(sprintf("SELECT * FROM `users`, `tracks` WHERE `tracks`.`id` = '%s' AND `tracks`.`uid` = `users`.`idu` AND `tracks`.`public` = 1 AND `users`.`private` != 1", $this->db->real_escape_string($id)));
5292
5293 // Set the result into an array
5294 $rows = array();
5295 while($row = $query->fetch_assoc()) {
5296 $rows[] = $row;
5297 }
5298
5299 if($query->num_rows) {
5300 foreach($rows as $row) {
5301 $tags = explode(',', $row['tag']);
5302 $row['tag'] = $tags[0];
5303 $track = '<div id="track'.$row['id'].'" class="embed-container">
5304 <div class="song-art"><a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['art'].'&t=m&w=112&h=112" id="song-art'.$row['id'].'" /></a></div>
5305 <div class="song-top">
5306 <div class="embed-powered-by">
5307 <a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" id="song-url'.$row['id'].'" target="_blank">'.$this->title.'</a>
5308 </div>
5309 <div data-track-name="'.$row['name'].'" data-track-id="'.$row['id'].'" id="play'.$row['id'].'" class="track song-play-btn">
5310 </div>
5311 <div class="song-titles">
5312 <div class="song-author"><a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank">'.realName($row['username'], $row['first_name'], $row['last_name']).'</a></div>
5313 <div class="song-tag">
5314 <a href="'.$this->url.'/index.php?a=explore&filter='.$row['tag'].'" target="_blank">'.$row['tag'].'</a>
5315 </div>
5316 <div class="song-title">
5317 <a href="'.$this->url.'/index.php?a=track&id='.$row['id'].'" id="song-url'.$row['id'].'" target="_blank"><div id="song-name'.$row['id'].'">'.$row['title'].'</div></a>
5318 </div>
5319 </div>
5320 </div>
5321 <div class="player-controls">
5322 <div id="song-controls'.$row['id'].'">
5323 <div id="jp_container_123" class="jp-audio">
5324 <div class="jp-type-single">
5325 <div class="jp-gui jp-interface">
5326 <div class="jp-progress">
5327 <div class="jp-seek-bar">
5328 <div class="jp-play-bar"></div>
5329 </div>
5330 </div>
5331 </div>
5332 </div>
5333 </div>
5334 </div>
5335 </div>
5336 <div class="track-actions-container">
5337 <div class="track-actions"><div class="track-actions-content" id="track-action'.$row['id'].'">'.$this->embedStats($row['id']).'</div></div>
5338 </div>
5339 </div>';
5340 }
5341 } else {
5342 return '<div style="width: 100%; background: url('.$this->url.'/uploads/media/default.png) top center no-repeat #b6b6b6; height: 140px;" class="embed-error"><div class="embed-error-title"><a href="'.$this->url.'" target="_blank">'.$this->title.'</a></div><div class="embed-error-desc"><a href="'.$this->url.'" target="_blank">'.$LNG['embed_error'].'</a></div></div>';
5343 }
5344 return $track;
5345 }
5346
5347 function embedStats($id) {
5348 global $LNG;
5349
5350 // Get the likes, views, and other info
5351 $query = sprintf("SELECT `id`,`uid`, `buy`, `public`, `likes`, `downloads`, `views` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id));
5352
5353 // Run the query
5354 $result = $this->db->query($query);
5355
5356 // Get the array element for the like
5357 $get = $result->fetch_assoc();
5358
5359 if($this->l_per_post) {
5360 $query = sprintf("SELECT * FROM `likes`,`users` WHERE `likes`.`track` = '%s' and `likes`.`by` = `users`.`idu` ORDER BY `likes`.`id` DESC LIMIT %s", $this->db->real_escape_string($id), $this->db->real_escape_string($this->l_per_post));
5361
5362 $result = $this->db->query($query);
5363 while($row = $result->fetch_assoc()) {
5364 $array[] = $row;
5365 }
5366
5367 // Define the $people who liked variable
5368 $people = '';
5369 foreach($array as $row) {
5370 $people .= '<a href="'.$this->url.'/index.php?a=profile&u='.$row['username'].'" target="_blank"><img src="'.$this->url.'/thumb.php?src='.$row['image'].'&w=25&h=25&t=a" title="'.realName($row['username'], $row['first_name'], $row['last_name']).' '.$LNG['liked_this'].'" /></a> ';
5371 }
5372 }
5373
5374 $getComments = $this->db->query(sprintf("SELECT COUNT(*) FROM `comments` WHERE `tid` = '%s'", $this->db->real_escape_string($id)));
5375 $comments = $getComments->fetch_row();
5376
5377 $url = $this->url.'/index.php?a=track&id='.$id;
5378
5379 // Actions
5380 $views_stats = ($get['views']) ? '<div class="counter views_counter" title="'.sprintf($LNG['listened_x_times'], $get['views']).'">'.$get['views'].'</div>' : '';
5381 $comments_stats = ($comments[0]) ? '<div class="counter comments_counter" title="'.$comments[0].' '.$LNG['comments'].'">'.$comments[0].'</div>' : '';
5382 $likes_stats = ($get['likes']) ? '<div class="counter like_btn" id="like_btn'.$id.'" title="'.$get['likes'].' '.$LNG['likes'].'">'.$get['likes'].'</div>' : '';
5383 $downloads_stats = ($get['downloads']) ? '<div class="counter downloads_counter" title="'.sprintf($LNG['downloaded_x_times'], $get['downloads']).'">'.$get['downloads'].'</div>' : '';
5384
5385 // Output variable
5386 $actions = '<div class="track-likes" id="users_likes'.$id.'" style="'.((empty($people)) ? 'margin: 0;' : '').'">'.$people.'<a href="'.$this->url.'/index.php?a=track&id='.$id.'" target="_blank"><div class="track-stats">'.$views_stats.$comments_stats.$likes_stats.$downloads_stats.'</div></a></div>';
5387
5388 return $actions;
5389 }
5390}
5391function nl2clean($text) {
5392 // Replace two or more new lines with two new rows [blank space between them]
5393 return preg_replace("/(\r?\n){2,}/", "\n\n", $text);
5394}
5395function sendMail($to, $subject, $message, $from) {
5396 // Load up the site settings
5397 global $settings;
5398
5399 // If the SMTP emails option is enabled in the Admin Panel
5400 if($settings['smtp_email']) {
5401 require_once(__DIR__ .'/phpmailer/PHPMailerAutoload.php');
5402
5403 //Create a new PHPMailer instance
5404 $mail = new PHPMailer;
5405 //Tell PHPMailer to use SMTP
5406 $mail->isSMTP();
5407 //Enable SMTP debugging
5408 // 0 = off (for production use)
5409 // 1 = client messages
5410 // 2 = client and server messages
5411 $mail->SMTPDebug = 0;
5412 //Set the CharSet encoding
5413 $mail->CharSet = 'UTF-8';
5414 //Ask for HTML-friendly debug output
5415 $mail->Debugoutput = 'html';
5416 //Set the hostname of the mail server
5417 $mail->Host = $settings['smtp_host'];
5418 //Set the SMTP port number - likely to be 25, 465 or 587
5419 $mail->Port = $settings['smtp_port'];
5420 //Whether to use SMTP authentication
5421 $mail->SMTPAuth = $settings['smtp_auth'] ? true : false;
5422 //Username to use for SMTP authentication
5423 $mail->Username = $settings['smtp_username'];
5424 //Password to use for SMTP authentication
5425 $mail->Password = $settings['smtp_password'];
5426 //Set who the message is to be sent from
5427 $mail->setFrom($from, $settings['title']);
5428 //Set an alternative reply-to address
5429 $mail->addReplyTo($from, $settings['title']);
5430 //Set who the message is to be sent to
5431 if(is_array($to)) {
5432 foreach($to as $address) {
5433 $mail->addAddress($address);
5434 }
5435 } else {
5436 $mail->addAddress($to);
5437 }
5438 //Set the subject line
5439 $mail->Subject = $subject;
5440 //Read an HTML message body from an external file, convert referenced images to embedded,
5441 //convert HTML into a basic plain-text alternative body
5442 $mail->msgHTML($message);
5443
5444 //send the message, check for errors
5445 if(!$mail->send()) {
5446 // Return the error in the Browser's console
5447 //echo $mail->ErrorInfo;
5448 }
5449 } else {
5450 $headers = 'MIME-Version: 1.0' . "\r\n";
5451 $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
5452 $headers .= 'From: '.$from.'' . "\r\n" .
5453 'Reply-To: '.$from . "\r\n" .
5454 'X-Mailer: PHP/' . phpversion();
5455 if(is_array($to)) {
5456 foreach($to as $address) {
5457 @mail($address, $subject, $message, $headers);
5458 }
5459 } else {
5460 @mail($to, $subject, $message, $headers);
5461 }
5462 }
5463}
5464function strip_tags_array($value) {
5465 return strip_tags($value);
5466}
5467function admin_stats($db, $type, $values = null) {
5468 if($type == 1) {
5469 $query = sprintf("SELECT
5470 (SELECT count(idu) FROM `users` WHERE CURDATE() = `date`) as users_today,
5471 (SELECT count(idu) FROM `users` WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) = `date`) as users_yesterday,
5472 (SELECT count(idu) FROM `users` WHERE DATE_SUB(CURDATE(), INTERVAL 2 DAY) = `date`) as users_two_days,
5473 (SELECT count(idu) FROM `users` WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) = `date`) as users_three_days,
5474 (SELECT count(idu) FROM `users` WHERE DATE_SUB(CURDATE(), INTERVAL 4 DAY) = `date`) as users_four_days,
5475 (SELECT count(idu) FROM `users` WHERE DATE_SUB(CURDATE(), INTERVAL 5 DAY) = `date`) as users_five_days,
5476 (SELECT count(idu) FROM `users` WHERE DATE_SUB(CURDATE(), INTERVAL 6 DAY) = `date`) as users_six_days,
5477 (SELECT COUNT(id) FROM `playlists` WHERE CURDATE() = date(`time`)) AS playlists_today,
5478 (SELECT COUNT(id) FROM `playlists` WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) = date(`time`)) AS playlists_yesterday,
5479 (SELECT COUNT(id) FROM `playlists` WHERE DATE_SUB(CURDATE(), INTERVAL 2 DAY) = date(`time`)) AS playlists_two_days,
5480 (SELECT COUNT(id) FROM `playlists` WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) = date(`time`)) AS playlists_three_days,
5481 (SELECT COUNT(id) FROM `playlists` WHERE DATE_SUB(CURDATE(), INTERVAL 4 DAY) = date(`time`)) AS playlists_four_days,
5482 (SELECT COUNT(id) FROM `playlists` WHERE DATE_SUB(CURDATE(), INTERVAL 5 DAY) = date(`time`)) AS playlists_five_days,
5483 (SELECT COUNT(id) FROM `playlists` WHERE DATE_SUB(CURDATE(), INTERVAL 6 DAY) = date(`time`)) AS playlists_six_days,
5484 (SELECT COUNT(id) FROM `tracks` WHERE CURDATE() = date(`time`)) AS messages_today,
5485 (SELECT COUNT(id) FROM `tracks` WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) = date(`time`)) AS messages_yesterday,
5486 (SELECT COUNT(id) FROM `tracks` WHERE DATE_SUB(CURDATE(), INTERVAL 2 DAY) = date(`time`)) AS messages_two_days,
5487 (SELECT COUNT(id) FROM `tracks` WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) = date(`time`)) AS messages_three_days,
5488 (SELECT COUNT(id) FROM `tracks` WHERE DATE_SUB(CURDATE(), INTERVAL 4 DAY) = date(`time`)) AS messages_four_days,
5489 (SELECT COUNT(id) FROM `tracks` WHERE DATE_SUB(CURDATE(), INTERVAL 5 DAY) = date(`time`)) AS messages_five_days,
5490 (SELECT COUNT(id) FROM `tracks` WHERE DATE_SUB(CURDATE(), INTERVAL 6 DAY) = date(`time`)) AS messages_six_days,
5491 (SELECT COUNT(id) FROM `comments` WHERE CURDATE() = date(`time`)) AS comments_today,
5492 (SELECT COUNT(id) FROM `comments` WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) = date(`time`)) AS comments_yesterday,
5493 (SELECT COUNT(id) FROM `comments` WHERE DATE_SUB(CURDATE(), INTERVAL 2 DAY) = date(`time`)) AS comments_two_days,
5494 (SELECT COUNT(id) FROM `comments` WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) = date(`time`)) AS comments_three_days,
5495 (SELECT COUNT(id) FROM `comments` WHERE DATE_SUB(CURDATE(), INTERVAL 4 DAY) = date(`time`)) AS comments_four_days,
5496 (SELECT COUNT(id) FROM `comments` WHERE DATE_SUB(CURDATE(), INTERVAL 5 DAY) = date(`time`)) AS comments_five_days,
5497 (SELECT COUNT(id) FROM `comments` WHERE DATE_SUB(CURDATE(), INTERVAL 6 DAY) = date(`time`)) AS comments_six_days,
5498 (SELECT count(id) FROM `likes` WHERE CURDATE() = date(`time`)) as likes_today,
5499 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) = date(`time`)) as likes_yesterday,
5500 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(), INTERVAL 2 DAY) = date(`time`)) as likes_two_days,
5501 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) = date(`time`)) as likes_three_days,
5502 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(), INTERVAL 4 DAY) = date(`time`)) as likes_four_days,
5503 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(), INTERVAL 5 DAY) = date(`time`)) as likes_five_days,
5504 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(), INTERVAL 6 DAY) = date(`time`)) as likes_six_days,
5505 (SELECT COUNT(id) FROM `downloads` WHERE CURDATE() = date(`time`)) AS downloads_today,
5506 (SELECT COUNT(id) FROM `downloads` WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) = date(`time`)) AS downloads_yesterday,
5507 (SELECT COUNT(id) FROM `downloads` WHERE DATE_SUB(CURDATE(), INTERVAL 2 DAY) = date(`time`)) AS downloads_two_days,
5508 (SELECT COUNT(id) FROM `downloads` WHERE DATE_SUB(CURDATE(), INTERVAL 3 DAY) = date(`time`)) AS downloads_three_days,
5509 (SELECT COUNT(id) FROM `downloads` WHERE DATE_SUB(CURDATE(), INTERVAL 4 DAY) = date(`time`)) AS downloads_four_days,
5510 (SELECT COUNT(id) FROM `downloads` WHERE DATE_SUB(CURDATE(), INTERVAL 5 DAY) = date(`time`)) AS downloads_five_days,
5511 (SELECT COUNT(id) FROM `downloads` WHERE DATE_SUB(CURDATE(), INTERVAL 6 DAY) = date(`time`)) AS downloads_six_days,
5512 (SELECT count(idu) FROM `users` WHERE `online` > '%s'-'%s') AS online_users", time(), $values['conline']);
5513 } else {
5514 $query = sprintf("SELECT
5515 (SELECT COUNT(id) FROM tracks) AS tracks_total,
5516 (SELECT COUNT(id) FROM tracks WHERE public = '1') AS tracks_public,
5517 (SELECT COUNT(id) FROM tracks WHERE public = '0') as tracks_private,
5518 (SELECT COUNT(id) FROM comments) as comments_total,
5519 (SELECT count(idu) FROM users WHERE CURDATE() = `date`) as users_today,
5520 (SELECT count(idu) FROM users WHERE MONTH(CURDATE()) = MONTH(`date`) AND YEAR(CURDATE()) = YEAR(`date`)) as users_this_month,
5521 (SELECT count(idu) FROM users WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= `date`) as users_last_30,
5522 (SELECT count(idu) FROM users) as users_total,
5523 (SELECT count(id) FROM `reports`) as total_reports,
5524 (SELECT count(id) FROM `reports` WHERE `state` = 0) as pending_reports,
5525 (SELECT count(id) FROM `reports` WHERE `state` = 1) as safe_reports,
5526 (SELECT count(id) FROM `reports` WHERE `state` = 2) as deleted_reports,
5527 (SELECT count(id) FROM `reports` WHERE `type` = 1) as total_track_reports,
5528 (SELECT count(id) FROM `reports` WHERE `state` = 0 AND `type` = 1) as pending_track_reports,
5529 (SELECT count(id) FROM `reports` WHERE `state` = 1 AND `type` = 1) as safe_track_reports,
5530 (SELECT count(id) FROM `reports` WHERE `state` = 2 AND `state` = 3 AND `type` = 1) as deleted_track_reports,
5531 (SELECT count(id) FROM `reports` WHERE `type` = 0) as total_comment_reports,
5532 (SELECT count(id) FROM `reports` WHERE `state` = 0 AND `type` = 0) as pending_comment_reports,
5533 (SELECT count(id) FROM `reports` WHERE `state` = 1 AND `type` = 0) as safe_comment_reports,
5534 (SELECT count(id) FROM `reports` WHERE `state` = 2 AND `type` = 0) as deleted_comment_reports,
5535 (SELECT count(id) FROM `likes`) as total_likes,
5536 (SELECT count(id) FROM `likes` WHERE CURDATE() = date(`time`)) as likes_today,
5537 (SELECT count(id) FROM `likes` WHERE MONTH(CURDATE()) = MONTH(date(`time`)) AND YEAR(CURDATE()) = YEAR(date(`time`))) as likes_this_month,
5538 (SELECT count(id) FROM `likes` WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date(`time`)) as likes_last_30,
5539 (SELECT count(id) FROM `views`) as total_plays,
5540 (SELECT count(id) FROM `views` WHERE CURDATE() = date(`time`)) as plays_today,
5541 (SELECT count(id) FROM `views` WHERE MONTH(CURDATE()) = MONTH(date(`time`)) AND YEAR(CURDATE()) = YEAR(date(`time`))) as plays_this_month,
5542 (SELECT count(id) FROM `views` WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date(`time`)) as plays_last_30,
5543 (SELECT count(id) FROM `downloads`) as total_downloads,
5544 (SELECT count(id) FROM `downloads` WHERE CURDATE() = date(`time`)) as downloads_today,
5545 (SELECT count(id) FROM `downloads` WHERE MONTH(CURDATE()) = MONTH(date(`time`)) AND YEAR(CURDATE()) = YEAR(date(`time`))) as downloads_this_month,
5546 (SELECT count(id) FROM `downloads` WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date(`time`)) as downloads_last_30,
5547 (SELECT count(id) FROM `playlists`) as total_playlists,
5548 (SELECT count(id) FROM `playlists` WHERE CURDATE() = date(`time`)) as playlists_today,
5549 (SELECT count(id) FROM `playlists` WHERE MONTH(CURDATE()) = MONTH(date(`time`)) AND YEAR(CURDATE()) = YEAR(date(`time`))) as playlists_this_month,
5550 (SELECT count(id) FROM `playlists` WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date(`time`)) as playlists_last_30,
5551 (SELECT count(id) FROM `payments`) as total_payments,
5552 (SELECT count(id) FROM `payments` WHERE CURDATE() = date(`time`)) as payments_today,
5553 (SELECT count(id) FROM `payments` WHERE MONTH(CURDATE()) = MONTH(date(`time`)) AND YEAR(CURDATE()) = YEAR(date(`time`))) as payments_this_month,
5554 (SELECT count(id) FROM `payments` WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date(`time`)) as payments_last_30,
5555 (SELECT sum(`amount`) FROM `payments` WHERE `status` = 1 AND `currency` = '%s') as total_earnings,
5556 (SELECT sum(`amount`) FROM `payments` WHERE CURDATE() = date(`time`) AND `status` = 1 AND `currency` = '%s') as earnings_today,
5557 (SELECT sum(`amount`) FROM `payments` WHERE MONTH(CURDATE()) = MONTH(date(`time`)) AND YEAR(CURDATE()) = YEAR(date(`time`)) AND `status` = 1 AND `currency` = '%s') as earnings_this_month,
5558 (SELECT sum(`amount`) FROM `payments` WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date(`time`) AND `status` = 1 AND `currency` = '%s') as earnings_last_30", $db->real_escape_string($values['currency']), $db->real_escape_string($values['currency']), $db->real_escape_string($values['currency']), $db->real_escape_string($values['currency']));
5559 }
5560 $result = $db->query($query);
5561 while($row = $result->fetch_assoc()) {
5562 $rows[] = $row;
5563 }
5564 $stats = array();
5565 foreach($rows[0] as $value) {
5566 $stats[] = ($value) ? $value : 0;
5567 }
5568 return $stats;
5569}
5570function percentage($current, $old) {
5571 $result = number_format((($current - $old) / $old * 100), 0);
5572 if($result < 0) {
5573 return '<span class="negative">'.$result.'%</span>';
5574 } elseif($result > 0) {
5575 return '<span class="positive">+'.$result.'%</span>';
5576 } else {
5577 return '<span class="neutral">'.$result.'%</span>';
5578 }
5579}
5580function fsize($bytes) { #Determine the size of the file, and print a human readable value
5581 $bytes = empty($bytes) ? 0 : $bytes;
5582 if ($bytes < 1024) return ($bytes < 0) ? 0 : $bytes.' B';
5583 elseif ($bytes < 1048576) return round($bytes / 1024, 2).' KB';
5584 elseif ($bytes < 1073741824) return round($bytes / 1048576, 2).' MB';
5585 elseif ($bytes < 1099511627776) return round($bytes / 1073741824, 2).' GB';
5586 else return round($bytes / 1099511627776, 2).' TB';
5587}
5588function realName($username, $first = null, $last = null, $fullname = null) {
5589 if($fullname) {
5590 if($first && $last) {
5591 return $first.' '.$last;
5592 } else {
5593 return $username;
5594 }
5595 }
5596 if($first && $last) {
5597 return $first.' '.$last;
5598 } elseif($first) {
5599 return $first;
5600 } elseif($last) {
5601 return $last;
5602 } elseif($username) { // If username is not set, return empty (example: the real-name under the subscriptions)
5603 return $username;
5604 }
5605}
5606function location($country, $city) {
5607 if($country && $city) {
5608 return $city.', '.$country;
5609 } elseif($country) {
5610 return $country;
5611 } elseif($city) {
5612 return $city;
5613 }
5614}
5615function welcomeTracks($rows, $url) {
5616 foreach($rows as $row) {
5617 $x .= '<div class="welcome-track"><a href="'.$url.'/index.php?a=track&id='.$row['track'].'" title="'.$row['title'].'" rel="loadpage"><img src="'.$url.'/thumb.php?src='.$row['art'].'&t=m&w=112&h=112"></a></div>';
5618 }
5619 return $x;
5620}
5621function welcomeCategories($rows, $url) {
5622 foreach($rows as $row) {
5623 $x .= '<a href="'.$url.'/index.php?a=explore&filter='.strtolower($row['name']).'" title="'.$row['name'].'" rel="loadpage">'.$row['name'].'</a>';
5624 }
5625 return $x;
5626}
5627function parseCallback($matches) {
5628 // If match www. at the beginning, at http before, to be html valid
5629 if(substr($matches[1], 0, 4) == 'www.') {
5630 $url = 'http://'.$matches[1];
5631 } else {
5632 $url = $matches[1];
5633 }
5634 return '<a href="'.$url.'" target="_blank" rel="nofollow">'.$matches[1].'</a>';
5635}
5636function pageHeader($title) {
5637 return '<div class="page-header page-header-extra">'.htmlspecialchars($title).'</div>';
5638}
5639function generateDateForm($type, $current) {
5640 global $LNG;
5641 $rows = '';
5642 if($type == 0) {
5643 $rows .= '<option value="">'.$LNG['year'].'</option>';
5644 for ($i = date('Y')+10; $i >= (date('Y')+10 - 110); $i--) {
5645 if($i == $current) {
5646 $selected = ' selected="selected"';
5647 } else {
5648 $selected = '';
5649 }
5650 $rows .= '<option value="'.$i.'"'.$selected.'>'.$i.'</option>';
5651 }
5652 } elseif($type == 1) {
5653 $rows .= '<option value="">'.$LNG['month'].'</option>';
5654 for ($i = 1; $i <= 12; $i++) {
5655 if($i == $current) {
5656 $selected = ' selected="selected"';
5657 } else {
5658 $selected = '';
5659 }
5660 $rows .= '<option value="'.$i.'"'.$selected.'>'.$LNG["month_$i"].'</option>';
5661 }
5662 } elseif($type == 2) {
5663 $rows .= '<option value="">'.$LNG['day'].'</option>';
5664 for ($i = 1; $i <= 31; $i++) {
5665 if($i == $current) {
5666 $selected = ' selected="selected"';
5667 } else {
5668 $selected = '';
5669 }
5670 $rows .= '<option value="'.$i.'"'.$selected.'>'.$i.'</option>';
5671 }
5672 }
5673 return $rows;
5674}
5675function generateAd($content) {
5676 global $LNG;
5677 if(empty($content)) {
5678 return false;
5679 }
5680 $ad = '<div class="sidebar-container widget-ad-unit"><div class="sidebar-content"><div class="sidebar-header">'.$LNG['sponsored'].'</div>'.$content.'</div></div>';
5681 return $ad;
5682}
5683function sortDateDesc($a, $b) {
5684 // Convert the array value into a UNIX timestamp
5685 strtotime($a['time']);
5686 strtotime($b['time']);
5687
5688 return strcmp($a['time'], $b['time']);
5689}
5690function sortDateAsc($a, $b) {
5691 // Convert the array value into a UNIX timestamp
5692 strtotime($a['time']);
5693 strtotime($b['time']);
5694
5695 if ($a['time'] == $b['time']) {
5696 return 0;
5697 }
5698 return ($a['time'] > $b['time']) ? -1 : 1;
5699}
5700function sortOnlineUsers($a, $b) {
5701 // Convert the array value into a UNIX timestamp
5702 strtotime($a['online']);
5703 strtotime($b['online']);
5704
5705 if ($a['online'] == $b['online']) {
5706 return 0;
5707 }
5708 return ($a['online'] > $b['online']) ? -1 : 1;
5709}
5710function getLanguage($url, $ln = null, $type = null) {
5711 // Type 1: Output the available languages
5712 // Type 2: Change the path for the /requests/ folder location
5713 // Set the directory location
5714 if($type == 2) {
5715 $languagesDir = '../languages/';
5716 } else {
5717 $languagesDir = './languages/';
5718 }
5719 // Search for pathnames matching the .png pattern
5720 $language = glob($languagesDir . '*.php', GLOB_BRACE);
5721
5722 if($type == 1) {
5723 // Add to array the available languages
5724 foreach($language as $lang) {
5725 // The path to be parsed
5726 $path = pathinfo($lang);
5727
5728 // Add the filename into $available array
5729 $available .= '<a href="'.$url.'/index.php?lang='.$path['filename'].'">'.ucfirst(strtolower($path['filename'])).'</a> - ';
5730 }
5731 return substr($available, 0, -3);
5732 } else {
5733 // If get is set, set the cookie and stuff
5734 $lang = 'english'; // Default Language
5735 if($type == 2) {
5736 $path = '../languages/';
5737 } else {
5738 $path = './languages/';
5739 }
5740 if(isset($_GET['lang'])) {
5741 if(in_array($path.$_GET['lang'].'.php', $language)) {
5742 $lang = $_GET['lang'];
5743 setcookie('lang', $lang, time() + (10 * 365 * 24 * 60 * 60)); // Expire in one month
5744 } else {
5745 setcookie('lang', $lang, time() + (10 * 365 * 24 * 60 * 60)); // Expire in one month
5746 }
5747 } elseif(isset($_COOKIE['lang'])) {
5748 if(in_array($path.$_COOKIE['lang'].'.php', $language)) {
5749 $lang = $_COOKIE['lang'];
5750 }
5751 } else {
5752 setcookie('lang', $lang, time() + (10 * 365 * 24 * 60 * 60)); // Expire in one month
5753 }
5754
5755 if(in_array($path.$lang.'.php', $language)) {
5756 return $path.$lang.'.php';
5757 }
5758 }
5759}
5760function saniscape($value) {
5761 return htmlspecialchars(addslashes($value), ENT_QUOTES, 'UTF-8');
5762}
5763function generateToken($type = null) {
5764 if($type) {
5765 return '<input type="hidden" name="token_id" value="'.$_SESSION['token_id'].'">';
5766 } else {
5767 if(!isset($_SESSION['token_id'])) {
5768 $token_id = md5(substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10));
5769 $_SESSION['token_id'] = $token_id;
5770 return $_SESSION['token_id'];
5771 }
5772 return $_SESSION['token_id'];
5773 }
5774}
5775function getUserIp() {
5776 if($_SERVER['REMOTE_ADDR']) {
5777 return $_SERVER['REMOTE_ADDR'];
5778 } else {
5779 return false;
5780 }
5781}
5782function validateSession($name, $time) {
5783 // Name holds the session name
5784 // Time holds the session time difference
5785
5786 // If the session is set
5787 if(!empty($_SESSION[$name])) {
5788
5789 // Compare the session time since last request
5790 if((time()-$_SESSION[$name]) > $time) {
5791 // If the time difference is meet, make the view and regenerate the session time
5792 $_SESSION[$name] = time();
5793 return 1;
5794 } else {
5795 return 0;
5796 }
5797 // If the session is not set, then generate a new one
5798 } else {
5799 $_SESSION[$name] = time();
5800 return 1;
5801 }
5802}
5803function validateFile($path, $name, $allowed, $type) {
5804 // Type 0: Image
5805 // Type 1: Audio
5806 $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
5807
5808 if(!$type) {
5809 $image = getimagesize($path);
5810 $output['width'] = $image[0];
5811 $output['height'] = $image[1];
5812 $output['mime'] = str_replace('image/', '', $image['mime']);
5813
5814 // Verify if the mime type and extensions are allowed
5815 if(in_array($output['mime'], $allowed) && in_array($ext, $allowed)) {
5816 $output['valid'] = 1;
5817 } else {
5818 $output['valid'] = 0;
5819 }
5820 } else {
5821 // If the mime_content_type function exist and the mp3 file is valid
5822 if(function_exists('mime_content_type')) {
5823 // Read the mime type
5824 $mime = mime_content_type($path);
5825
5826 if($mime == 'audio/mpeg' || $mime == 'audio/mp4' || $mime == 'application/octet-stream') {
5827 $mime = 1;
5828 } else {
5829 $mime = 0;
5830 }
5831 } else {
5832 $mime = 1;
5833 }
5834
5835 if(in_array($ext, $allowed) && $mime) {
5836 $output['valid'] = 1;
5837 } else {
5838 $output['valid'] = 0;
5839 }
5840 }
5841 return $output;
5842}
5843function imageOrientation($filename) {
5844 if(function_exists('exif_read_data')) {
5845 // Read the image exif data
5846 $exif = exif_read_data($filename);
5847
5848 // Store the image exif orientation data
5849 $orientation = $exif['Orientation'];
5850
5851 // Check whether the image has an orientation, and if the orientation is 3, 6, 8
5852 if(!empty($orientation) && in_array($orientation, array(3, 6, 8))) {
5853 $image = imagecreatefromjpeg($filename);
5854 if($orientation == 3) {
5855 $image = imagerotate($image, 180, 0);
5856 } elseif($orientation == 6) {
5857 $image = imagerotate($image, -90, 0);
5858 } elseif($orientation == 8) {
5859 $image = imagerotate($image, 90, 0);
5860 }
5861
5862 // Save the new rotated image
5863 imagejpeg($image, $filename, 90);
5864 }
5865 }
5866}
5867function deleteMedia($art, $track, $type = null) {
5868 // Type 0: If the request is made from another folder
5869 // Explode the images string value
5870 $arts = explode(',', $art);
5871 $tracks = explode(',', $track);
5872
5873 // Delete each image except default images
5874 foreach($arts as $art) {
5875 if($art !== 'default.png') {
5876 unlink(($type ? '' : '.').'./uploads/media/'.$art);
5877 }
5878 }
5879
5880 // Delete each song
5881 foreach($tracks as $track) {
5882 unlink(($type ? '' : '.').'./uploads/tracks/'.$track);
5883 }
5884}
5885function deleteImages($image, $type) {
5886 // Type 0: Delete covers
5887 // Type 1: Delete avatars
5888 // Type 2: Delete album art
5889
5890 if($type == 1) {
5891 $path = 'avatars';
5892 } elseif($type == 2) {
5893 $path = 'media';
5894 } else {
5895 $path = 'covers';
5896 }
5897
5898 foreach($image as $name) {
5899 if($name !== 'default.png') {
5900 unlink(__DIR__ .'/../uploads/'.$path.'/'.$name);
5901 }
5902 }
5903}
5904function proStatus($db, $settings, $id = null) {
5905 $query = $db->query(sprintf("SELECT * FROM `payments` WHERE `by` = '%s' ORDER BY `id` DESC LIMIT 0, 1", ($id) ? $id : $this->db->real_escape_string($this->id)));
5906 $result = $query->fetch_assoc();
5907
5908 if($settings['paypalapp']) {
5909 if($result['status'] == 1 && strtotime($result['valid']) >= time()) {
5910 return 0;
5911 } else {
5912 return 1;
5913 }
5914 } else {
5915 // Return false if pro accounts are not enabled
5916 return 0;
5917 }
5918}
5919function emulatePayment($db, $settings, $user) {
5920 $info = 'promoted';
5921 $date = date("Y-m-d H:m:s", strtotime("+1 year"));
5922 $db->query(sprintf("INSERT INTO `payments`
5923 (`by`, `payer_id`, `payer_first_name`, `payer_last_name`, `payer_email`, `payer_country`, `txn_id`, `amount`, `currency`, `type`, `status`, `valid`, `time`) VALUES
5924 ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s','%s', '%s', '%s', '%s')",
5925 $db->real_escape_string($user['idu']), $info, $info, $info, $info, $info, $info, 0, $db->real_escape_string($settings['currency']), 1, 1, $date, date("Y-m-d H:m:s")));
5926}
5927function paymentStatus($status) {
5928 global $LNG;
5929 if($status == 1) {
5930 $status = $LNG['completed'];
5931 } elseif($status == 2) {
5932 $status = $LNG['reversed'];
5933 } elseif($status == 3) {
5934 $status = $LNG['refunded'];
5935 } elseif($status == 4) {
5936 $status = $LNG['pending'];
5937 } elseif($status == 5) {
5938 $status = $LNG['failed'];
5939 } elseif($status == 6) {
5940 $status = $LNG['denied'];
5941 } else {
5942 $status = $LNG['suspended'];
5943 }
5944 return $status;
5945}
5946function fetch($url) {
5947 if(function_exists('curl_exec')) {
5948 $ch = curl_init($url);
5949 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
5950 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
5951 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
5952 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
5953 curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36');
5954 $response = curl_exec($ch);
5955 }
5956 if(empty($response)) {
5957 $response = file_get_contents($url);
5958 }
5959 return $response;
5960}
5961function open_graph() {
5962 return false;
5963}
5964?>