?php //======================================================================\\ // yungcloud - Music Sharing Platform \\ // Copyright © yuncloud llc. All rights reserved. \\ //----------------------------------------------------------------------\\ // http://www.yungcloud.com/ \\ //======================================================================\\ function getSettings() { $querySettings = "SELECT * from `settings`"; return $querySettings; } function menu($user) { global $TMPL, $LNG, $CONF, $db, $settings; $admin_url = ((isset($_SESSION['usernameAdmin']) && isset($_SESSION['passwordAdmin'])) ? '' : ''); if($user !== false) { $skin = new skin('shared/menu'); $menu = ''; $TMPL_old = $TMPL; $TMPL = array(); $TMPL['realname'] = realName($user['username'], $user['first_name'], $user['last_name']); $TMPL['avatar'] = $user['image']; $TMPL['username'] = $user['username']; $TMPL['url'] = $CONF['url']; $TMPL['theme_url'] = $CONF['theme_url']; $TMPL['intervaln'] = $settings['intervaln']; /** * Array Map * array => {url, name, dynamic load, class type} */ $links = array( array('profile&u='.$user['username'], realName($user['username'], $user['first_name'], $user['last_name']), 1, 0), array('upload', $LNG['upload'], 1, 1), (proStatus($db, $settings, $user['idu']) ? array('pro', $LNG['go_pro'], 1, 0) : ''), array('stream', $LNG['stream'], 1, 2), array('explore', $LNG['explore'], 1, 2), array('profile&u='.$user['username'].'&r=likes', $LNG['likes'], 1, 0), array('profile&u='.$user['username'].'&r=playlists', $LNG['playlists'], 1, 0), array('stats', $LNG['statistics'], 1, 0), array('settings', $LNG['user_ttl_sidebar'], 1, 0), array('stream&logout=1&token_id='.$_SESSION['token_id'], $LNG['admin_menu_logout'], 0, 0)); foreach($links as $element => $value) { if($value) { $TMPL['links'] .= $divider.''; $divider = ''; } } $TMPL['admin_url'] = $admin_url; $TMPL['messages_url'] = permalink($CONF['url'].'/index.php?a=messages'); $menu = $skin->make(); $TMPL = $TMPL_old; unset($TMPL_old); return $menu; } else { // Else show the LogIn Register button return ''.$LNG['connect'].''.$admin_url; } } function menuButtons($user) { global $LNG, $CONF; // Buttons list if($user) { $links = array('stream', 'explore'); } else { $links = array('explore'); } foreach($links as $url) { $menu .= ''.$LNG[$url].''; } return $menu; } function info_urls() { global $CONF, $db; $pages = $db->query("SELECT `url`, `title` FROM `info_pages` WHERE `public` = 1 ORDER BY `id` ASC"); while($row = $pages->fetch_assoc()) { $output .= ''.skin::parse($row['title']).''; } return $output; } function notificationBox($type, $message, $extra = null) { // Extra 1: Add the -modal class name if($extra == 1) { $extra = ' notification-box-modal'; } return '

'.$message.'

'; } class register { public $db; // Database Property public $url; // Installation URL Property public $username; // The inserted username public $password; // The inserted password public $first_name; // First name (used for social logins) public $last_name; // Last name (used for social logins) public $email; // The inserted email public $captcha; // The inserted captcha public $captcha_on; // Store the Admin Captcha settings public $email_register; // Store the Admin Email on Register settings public $accounts_per_ip; // Store the Admin settings for Accounts Per IP public $email_like; // The general e-mail like setting [if allowed, it will turn on emails on likes] public $email_comment; // The general e-mail like setting [if allowed, it will turn on emails on comments] public $email_new_friend; // The general e-mail new friend setting [if allowed, it will turn on emails on new friendships] public $fbapp; // Facebook App (0 disabled, 1 enabled) public $fbappid; // Facebook App ID public $fbappsecret; // Facebook App Secret function facebook() { if($this->fbapp) { $getToken = $this->getFbToken($this->fbappid, $this->fbappsecret, $this->url.'/requests/connect.php?facebook=true', $this->fbcode); $user = $this->parseFbInfo($getToken['access_token']); if($getToken == null || $_SESSION['state'] == null || ($_SESSION['state'] != $this->fbstate) || empty($user->email)) { header("Location: ".$this->url); } if(!empty($user->email)) { $this->email = $user->email; $this->first_name = $user->first_name; $this->last_name = $user->last_name; $checkEmail = $this->verify_if_email_exists(1); // If user already exist if($checkEmail) { // Set sessions and log-in $_SESSION['username'] = $checkEmail['username']; $_SESSION['password'] = $checkEmail['password']; // Redirect user header("Location: ".$this->url); } else { $this->profile_image = $this->parseFbPicture($getToken['access_token']); $this->generateUsername(); $this->password = $this->generatePassword(8); $this->query(); $_SESSION['username'] = $this->username; $_SESSION['password'] = md5($this->password); return 1; } } } } function generateUsername($type = null) { // If type is set, generate a random username if($type) { $this->username = $this->parseUsername().rand(0, 999); } else { $this->username = $this->parseUsername(); } // Replace the '.' sign with '_' (allows @user_mention) $this->username = str_replace('.', '_', $this->username); // Check if the username exists $checkUser = $this->verify_if_user_exist(); if($checkUser) { $this->generateUsername(1); } } function parseUsername() { if(ctype_alnum($this->first_name) && ctype_alnum($this->last_name)) { return $this->username = $this->first_name.'.'.$this->last_name; } elseif(ctype_alnum($this->first_name)) { return $this->first_name; } elseif(ctype_alnum($this->last_name)) { return $this->last_name; } else { // Parse email address $email = explode('@', $this->email); $email = preg_replace("/[^a-z0-9]+/i", "", $email[0]); if(ctype_alnum($email)) { return $email; } else { return rand(0, 9999); } } } function generatePassword($length) { // Allowed characters $chars = str_split("abcdefghijklmnopqrstuvwxyz0123456789"); // Generate password for($i = 1; $i <= $length; $i++) { // Get a random character $n = array_rand($chars, 1); // Store random char $password .= $chars[$n]; } return $password; } function getFbToken($app_id, $app_secret, $redirect_url, $code) { // Build the token URL $url = 'https://graph.facebook.com/oauth/access_token?client_id='.$app_id.'&redirect_uri='.urlencode($redirect_url).'&client_secret='.$app_secret.'&code='.$code; // Get the file $response = json_decode(fetch($url), true); // Return parameters return $response; } function parseFbInfo($access_token) { // Build the Graph URL $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; // Get the file $user = json_decode(fetch($url)); // Return user if($user != null && isset($user->name)) { return $user; } return null; } function parseFbPicture($access_token) { // Build the Graph URL $url = "https://graph.facebook.com/me/picture?width=500&height=500&access_token=".$access_token; // Get the image $image = fetch($url); // Generate the file name $file_name = mt_rand().'_'.mt_rand().'_'.mt_rand().'.jpg'; $file_path = __DIR__ .'/../uploads/avatars/'; // Create the file $fp = fopen($file_path.$file_name, 'wb'); // If the file can't be written if(!file_exists($file_path.$file_name)) { // Return the file name return false; } // Write the image fwrite($fp, $image); // Close fclose($fp); // Return the filename return $file_name; } function process() { global $LNG; // Prevents bypassing the FILTER_VALIDATE_EMAIL $this->email = htmlspecialchars($this->email, ENT_QUOTES, 'UTF-8'); $arr = $this->validate_values(); // Must be stored in a variable before executing an empty condition if(empty($arr)) { // If there is no error message then execute the query; $this->query(); // Set a session and log-in the user $_SESSION['username'] = $this->username; $_SESSION['password'] = md5($this->password); // Return (int) 1 if everything was validated return 1; // return $LNG['user_success']; } else { // If there is an error message foreach($arr as $err) { return notificationBox('error', $LNG["$err"], 1); // Return the error value for translation file } } } function verify_if_user_exist() { $query = sprintf("SELECT `username` FROM `users` WHERE `username` = '%s'", $this->db->real_escape_string(strtolower($this->username))); $result = $this->db->query($query); return ($result->num_rows == 0 && !in_array(strtolower($this->username), array('playlists', 'subscribers', 'subscriptions', 'about', 'messages'))) ? 0 : 1; } function verify_accounts_per_ip() { if($this->accounts_per_ip) { $query = $this->db->query(sprintf("SELECT COUNT(`ip`) FROM `users` WHERE `ip` = '%s'", $this->db->real_escape_string(getUserIP()))); $result = $query->fetch_row(); if($result[0] < $this->accounts_per_ip) { return true; } else { return false; } } else { return true; } } function verify_if_email_exists($type = null) { // Type 0: Normal check // Type 1: Facebook check & return type if($type) { $query = sprintf("SELECT `username`, `password` FROM `users` WHERE `email` = '%s'", $this->db->real_escape_string(strtolower($this->email))); } else { $query = sprintf("SELECT `email` FROM `users` WHERE `email` = '%s'", $this->db->real_escape_string(strtolower($this->email))); } $result = $this->db->query($query); if($type) { return ($result->num_rows == 0) ? 0 : $result->fetch_assoc(); } else { return ($result->num_rows == 0) ? 0 : 1; } } function verify_captcha() { if($this->captcha_on) { if($this->captcha == "{$_SESSION['captcha']}" && !empty($this->captcha)) { return true; } else { return false; } } else { return true; } } function validate_values() { // Create the array which contains the Language variable $error = array(); // Define the Language variable for each type of error if($this->verify_accounts_per_ip() == false) { $error[] = 'user_limit'; } if($this->verify_if_user_exist() !== 0) { $error[] = 'user_exists'; } if($this->verify_if_email_exists() !== 0) { $error[] = 'email_exists'; } if(empty($this->username) && empty($this->password) && empty($email)) { $error[] = 'all_fields'; } if(strlen($this->password) < 6) { $error[] = 'password_too_short'; } if(!ctype_alnum($this->username)) { $error[] = 'user_alnum'; } if(strlen($this->username) <= 2 || strlen($this->username) >= 33) { $error[] = 'user_too_short'; } if(!filter_var($this->email, FILTER_VALIDATE_EMAIL)) { $error[] = 'invalid_email'; } if($this->verify_captcha() == false) { $error[] = 'invalid_captcha'; } return $error; } function query() { $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); $this->db->query($query); } } class logIn { public $db; // Database Property public $url; // Installation URL Property public $username; // Username Property public $password; // Password Property public $remember; // Option to remember the usr / pwd (_COOKIE) Property function in() { global $LNG; // If an user is found if($this->queryLogIn() == 1) { // Regenerate the SID session_regenerate_id(); if($this->remember == 1) { // If checkbox, then set cookie setcookie("username", $this->username, time() + 30 * 24 * 60 * 60, '/'); // Expire in one month setcookie("password", md5($this->password), time() + 30 * 24 * 60 * 60, '/'); // Expire in one month } else { // Else set session $_SESSION['username'] = $this->username; $_SESSION['password'] = md5($this->password); } $stmt = $this->db->prepare("UPDATE `users` SET `salted` = '' WHERE `username` = '{$this->db->real_escape_string( $this->username)}'"); // Execute the statement $stmt->execute(); // Return logged in state return 1; } else { // If wrong credentials are entered, unset everything $this->logOut(); return notificationBox('error', $LNG['invalid_user_pw'], 1); } } function queryLogIn() { // If the username input string is an e-mail, switch the query if(filter_var($this->db->real_escape_string($this->username), FILTER_VALIDATE_EMAIL)) { $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))); } else { $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))); } // If the query can't be executed (e.g: use of special characters in inputs) if(!$result = $this->db->query($query)) { return 0; } return ($result->num_rows == 0) ? 0 : 1; } function logOut() { unset($_SESSION['username']); unset($_SESSION['password']); setcookie("username", '', 1, '/'); setcookie("password", '', 1, '/'); } } class loggedIn { public $db; // Database Property public $url; // Installation URL Property public $username; // Username Property public $password; // Password Property function verify() { // Set the query result into $query variable; $query = $this->query(); if(!is_int($query)) { // If the $query variable is not 0 (int) // Fetch associative array into $result variable $result = $query->fetch_assoc(); return $result; } } function query() { // If the username input string is an e-mail, switch the query if(filter_var($this->db->real_escape_string($this->username), FILTER_VALIDATE_EMAIL)) { $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)); } else { $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)); } $result = $this->db->query($query); return ($result->num_rows == 0) ? 0 : $result; } function logOut() { unset($_SESSION['username']); unset($_SESSION['password']); setcookie("username", '', 1, '/'); setcookie("password", '', 1, '/'); } } class logInAdmin { public $db; // Database Property public $url; // Installation URL Property public $username; // Username Property public $password; // Password Property function in() { global $LNG; // If an user is found if($this->queryLogIn() == 1) { // Regenerate the SID session_regenerate_id(); // Set session $_SESSION['usernameAdmin'] = $this->username; $_SESSION['passwordAdmin'] = md5($this->password); // Redirect the user to his personal profile // header("Location: ".$this->url."/index.php?a=feed"); } else { // If wrong credentials are entered, unset everything $this->logOut(); return notificationBox('error', $LNG['invalid_user_pw']); } } function queryLogIn() { $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))); $result = $this->db->query($query); return ($result->num_rows == 0) ? 0 : 1; } function logOut() { unset($_SESSION['usernameAdmin']); unset($_SESSION['passwordAdmin']); } } class loggedInAdmin { public $db; // Database Property public $url; // Installation URL Property public $username; // Username Property public $password; // Password Property function verify() { // Set the query result into $query variable; $query = $this->query(); if(!is_int($query)) { // If the $query variable is not 0 (int) // Fetch associative array into $result variable $result = $query->fetch_assoc(); return $result; } } function query() { $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)); $result = $this->db->query($query); return ($result->num_rows == 0) ? 0 : $result; } function logOut() { unset($_SESSION['usernameAdmin']); unset($_SESSION['passwordAdmin']); } } class updateSettings { public $db; // Database Property public $url; // Installation URL Property function validate_password($password) { $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)))); return $query->num_rows ? 1 : 0; } function truncate_data($data) { // Select the columns $query = $this->db->query("SHOW COLUMNS FROM `settings`"); while($result = $query->fetch_assoc()) { foreach($data as $key => $val) { // If the data matches the column and the column type is varchar if($result['Field'] == $key && substr($result['Type'], 0, 8) === 'varchar(') { // Strip out any extra characters that exceed the maximum field length $output[$key] = substr($val, 0, filter_var($result['Type'], FILTER_SANITIZE_NUMBER_INT)); } if($result['Field'] == $key && (substr($result['Type'], 0, 4) === 'int(' || substr($result['Type'], 0, 8) === 'tinyint(')) { // Strip out any extra characters that exceed the maximum field length $output[$key] = intval($val); } } } // Return array if empty (prevents breaking the array_merge function) return ($output ? $output : array()); } function query_array($table, $data) { // Verify if the user has a valid token if($data['token_id'] == $_SESSION['token_id']) { unset($data['token_id']); // If a logo has been selected, and the file was uploaded with no error and the logo is in PNG format if(isset($_FILES['logo']) && $_FILES['logo']['error'] == 0 && pathinfo($_FILES['logo']['name'], PATHINFO_EXTENSION) == 'png') { global $CONF; move_uploaded_file($_FILES['logo']['tmp_name'], __DIR__ . '/../'.$CONF['theme_url'].'/images/logo.png'); // Set a flag to notify that the logo has been changed $logo = true; } // Truncate any extra characters $data = array_merge($data, $this->truncate_data($data)); // Get the columns of the query-ed table $available = $this->getColumns($table); if($table == 'admin') { if(isset($data['password']) && !isset($data['current_password']) || isset($data['current_password']) && !$this->validate_password($data['current_password'])) { return 2; } if(isset($data['password']) && strlen($data['password']) < 6) { return 4; } if(isset($data['password']) && $data['password'] !== $data['repeat_password']) { return 3; } unset($data['repeat_password'], $data['current_password']); } foreach ($data as $key => $value) { // Check if all arrays introduced are available table fields if(!array_key_exists($key, $available)) { $x = 1; return 0; } } // If all array keys are valid database columns if($x !== 1) { foreach ($data as $column => $value) { $columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value)); } $column_list = implode(',', $columns); // Prepare the database for specific page if($table == 'admin') { // Prepare the statement $stmt = $this->db->prepare("UPDATE `$table` SET `password` = md5('{$data['password']}') WHERE `username` = '{$_SESSION['usernameAdmin']}'"); $_SESSION['passwordAdmin'] = md5($data['password']); } else { // Prepare the statement $stmt = $this->db->prepare("UPDATE `$table` SET $column_list"); } // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If there was anything affected return 1 return ($affected || $logo) ? 1 : 0; } } else { return 0; } } function getColumns($table) { if($table == 'admin') { $query = $this->db->query("SHOW columns FROM `$table` WHERE Field NOT IN ('id', 'username')"); } else { $query = $this->db->query("SHOW columns FROM `$table`"); } // Define an array to store the results $columns = array(); // Fetch the results set while ($row = $query->fetch_array()) { // Store the result into array $columns[] = $row[0]; } // Return the array; return array_flip($columns); } function getThemes() { global $CONF, $LNG; $themes = scandir('./'.$CONF['theme_path'].'/'); foreach($themes as $theme) { if($theme != '.' && $theme != '..' && $theme != 'index.html' && file_exists('./'.$CONF['theme_path'].'/'.$theme.'/info.php')) { $allowedThemes[] = $theme; include('./'.$CONF['theme_path'].'/'.$theme.'/info.php'); if($CONF['theme_name'] == $theme) { $state = ''; } else { $state = ''; } if(file_exists('./'.$CONF['theme_path'].'/'.$theme.'/icon.png')) { $image = ''; } else { $image = ''; } $output .= '
'.$image.'
'.$name.' '.$version.'
'.$LNG['by'].': '.$author.'
'.$state.'
'; } } return array($output, $allowedThemes); } function getLanguages() { global $CONF, $LNG, $settings; $languages = scandir('./languages/'); $LNGO = $LNG; $by = $LNG['by']; $default = $LNG['default']; $make = $LNG['make_default']; foreach($languages as $language) { if($language != '.' && $language != '..' && substr($language, -4, 4) == '.php') { $language = substr($language, 0, -4); $allowedLanguages[] = $language; include('./languages/'.$language.'.php'); if($settings['language'] == $language) { $state = ''; } else { $state = ''; } $output .= '
'.$state.'
'.$name.'
'.$by.': '.$author.'
'; } } $LNG = $LNGO; return array($output, $allowedLanguages); } function getInfoPages() { global $CONF, $LNG; $pages = $this->db->query("SELECT * FROM `info_pages` ORDER BY `id` ASC"); while($row = $pages->fetch_assoc()) { $row['content'] = skin::parse($row['content']); $output .= '
'.((strlen($row['content']) > 65) ? substr(strip_tags($row['content']), 0, 65).'...' : strip_tags($row['content'])).'
'; } return $output; } function createInfoPage($values, $type) { global $CONF; // Type 0: Create page // Type 1: Update page if($values['token_id'] != $_SESSION['token_id']) { return false; } // Type 1: Edit the page global $LNG; $values['page_title'] = substr(strip_tags($values['page_title']), 0, 64); $values['page_url'] = substr(htmlspecialchars(strip_tags($values['page_url'])), 0, 64); $values['page_public'] = ($values['page_public'] == 1 ? 1 : 0); // Verify URL $checkUrl = $this->db->query(sprintf("SELECT `id`, `url` FROM `info_pages` WHERE `url` = '%s'", $this->db->real_escape_string($values['page_url']))); $resultUrl = $checkUrl->fetch_assoc(); if(empty($values['page_title']) || empty($values['page_url']) || empty($values['page_content'])) { $error = $LNG['all_fields']; } if($type) { // Check if the URL already exists on another page if($checkUrl->num_rows && $resultUrl['id'] != $_GET['id']) { $error = $LNG['url_exists']; } } else { if($checkUrl->num_rows) { $error = $LNG['url_exists']; } } if($error) { return notificationBox('error', $error); } if($type) { // Prepare the statement $stmt = $this->db->prepare("UPDATE `info_pages` SET `title` = ?, `url` = ?, `public` = ?, `content` = ? WHERE `id` = ?"); $stmt->bind_param('sssss', $values['page_title'], $values['page_url'], $values['page_public'], $values['page_content'], $_GET['id']); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; $stmt->close(); if($affected) { return notificationBox('success', $LNG['settings_saved']); } else { return notificationBox('info', $LNG['nothing_changed']); } } else { $this->db->query(sprintf("INSERT INTO `info_pages` (`title`, `url`, `public`, `content`) VALUES ('%s', '%s', '%s', '%s')", $this->db->real_escape_string($values['page_title']), $this->db->real_escape_string($values['page_url']), $this->db->real_escape_string($values['page_public']), $this->db->real_escape_string($values['page_content']))); header("Location: ".permalink($CONF['url'].'/index.php?a=page&b='.$values['page_url'])); } } function deleteInfoPage($id) { // Prepare the statement $stmt = $this->db->prepare("DELETE FROM `info_pages` WHERE `id` = ?"); $stmt->bind_param('s', $id); $stmt->execute(); $affected = $stmt->affected_rows; $stmt->close(); return ($affected ? 1 : 0); } } class updateUserSettings { public $db; // Database Property public $url; // Installation URL Property public $id; // Logged in user id function validate_password($password) { $query = $this->db->query(sprintf("SELECT `password` FROM `users` WHERE `idu` = '%s' AND `password` = '%s'", $this->id, $this->db->real_escape_string(md5($password)))); return $query->num_rows ? 1 : 0; } function validate_inputs($data) { if(isset($data['password']) && !isset($data['current_password']) || isset($data['current_password']) && !$this->validate_password($data['current_password'])) { return array('wrong_current_password'); } if(isset($data['email']) && !filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { return array('valid_email'); } if(!countries(0, $data['country'])) { return array('valid_country'); } if((!filter_var($data['website'], FILTER_VALIDATE_URL) && !empty($data['website'])) || (substr($data['website'], 0, 7) != 'http://' && substr($data['website'], 0, 8) != 'https://' && !empty($data['website']))) { return array('valid_url'); } if(isset($data['email']) && $this->verify_if_email_exists($this->id, $data['email'])) { return array('email_exists'); } if(strlen($data['description']) > 160) { return array('profile_description', 160); } if(isset($data['password']) && strlen($data['password']) < 6) { return array('password_too_short'); } if(isset($data['password']) && $data['password'] !== $data['repeat_password']) { return array('password_not_match'); } } function truncate_data($data) { // Select the columns $query = $this->db->query("SHOW COLUMNS FROM `users`"); while($result = $query->fetch_assoc()) { foreach($data as $key => $val) { // If the data matches the column and the column type is varchar if($result['Field'] == $key && substr($result['Type'], 0, 8) === 'varchar(') { // Strip out any extra characters that exceed the maximum field length $output[$key] = substr($val, 0, filter_var($result['Type'], FILTER_SANITIZE_NUMBER_INT)); } } } // Return array if empty (prevents breaking the array_merge function) return ($output ? $output : array()); } function query_array($table, $data) { global $LNG; // Verify if the user has a valid token if($data['token_id'] == $_SESSION['token_id']) { // Truncate any extra characters foreach($data as $key => $val) { if($key != 'password' && $key != 'current_password' && $key != 'repeat_password') { $data[$key] = htmlspecialchars($val, ENT_QUOTES, 'UTF-8'); } } $data = array_merge($data, $this->truncate_data($data)); // Validate the inputs $validate = $this->validate_inputs($data); if($validate) { return notificationBox('error', sprintf($LNG["{$validate[0]}"], $validate[1])); } // Unset unused values unset($data['repeat_password'], $data['current_password'], $data['token_id']); // Clean the description if(isset($data['description'])) { $data['description'] = trim(nl2clean($data['description'])); } // Get the columns of the query-ed table $available = $this->getColumns($table); foreach ($data as $key => $value) { // Check if password array key exist and set a variable if so if($key == 'password') { $password = true; } // Check if all arrays introduced are available table fields if(!array_key_exists($key, $available)) { $x = 1; break; } } // If the password array key exists, encrypt the password if($password) { $data['password'] = md5($data['password']); } // If all array keys are valid database columns if($x !== 1) { foreach ($data as $column => $value) { $columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value)); } $column_list = implode(',', $columns); // Prepare the statement $stmt = $this->db->prepare("UPDATE `$table` SET $column_list WHERE `idu` = '{$this->id}'"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the SQL was executed, and the password field was set, save the new password if($affected && $password) { if(isset($_COOKIE['password'])) { setcookie("password", $data['password'], time() + 30 * 24 * 60 * 60); // Expire in one month } else { $_SESSION['password'] = $data['password']; } } // If there was anything affected return 1 if($affected) { return notificationBox('success', $LNG['settings_saved']); } else { return notificationBox('info', $LNG['nothing_changed']); } } } else { return notificationBox('info', $LNG['nothing_changed']); } } function getColumns($table) { $query = $this->db->query("SHOW columns FROM `$table` WHERE Field NOT IN ('idu', 'username', 'date', 'salted')"); // Define an array to store the results $columns = array(); // Fetch the results set while ($row = $query->fetch_array()) { // Store the result into array $columns[] = $row[0]; } // Return the array; return array_flip($columns); } function deleteAvatar($image) { // Prepare the statement $stmt = $this->db->prepare("UPDATE `users` SET `image` = 'default.png' WHERE `idu` = '{$this->id}'"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the change was made, then unlink the old image if($affected) { unlink('uploads/avatars/'.$image); } // If there was anything affected return 1 return ($affected) ? 1 : 0; } function verify_if_email_exists($id, $email) { $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))); $result = $this->db->query($query); return ($result->num_rows == 0) ? 0 : 1; } function getSettings() { $result = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` = '%s'", $this->db->real_escape_string($this->id))); return $result->fetch_assoc(); } function getBlockedUsers() { global $LNG; $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))); while($row = $result->fetch_assoc()) { $output .= '
'.$row['username'].'
'.realName(null, $row['first_name'], $row['last_name']).''.((location($row['country'], $row['city']) && $row['private'] == 0) ? ' ('.location($row['country'], $row['city']).')' : ' ').'
'; } return $output; } } class recover { public $db; // Database Property public $url; // Installation URL Property public $username; // The username to recover function checkUser() { // Query the database and check if the username exists if(filter_var($this->db->real_escape_string($this->username), FILTER_VALIDATE_EMAIL)) { $query = sprintf("SELECT `username`,`email` FROM `users` WHERE `email` = '%s'", $this->db->real_escape_string(strtolower($this->username))); } else { $query = sprintf("SELECT `username`,`email` FROM `users` WHERE `username` = '%s'", $this->db->real_escape_string(strtolower($this->username))); } $result = $this->db->query($query); // If a valid username is found if ($result->num_rows > 0) { // Fetch Associative values $assoc = $result->fetch_assoc(); // Generate the salt for that username $generateSalt = $this->generateSalt($assoc['username']); // If the salt was generated if($generateSalt) { // Return the username, email and salted code return array($assoc['username'], $assoc['email'], $generateSalt); } } } function generateSalt($username) { // Generate the salted code $salt = md5(mt_rand()); // Prepare to update the database with the salted code $stmt = $this->db->prepare("UPDATE `users` SET `salted` = '{$this->db->real_escape_string($salt)}' WHERE `username` = '{$this->db->real_escape_string(strtolower($username))}'"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the query $stmt->close(); // If there was anything affected return 1 if($affected) return $salt; else return false; } function changePassword($username, $password, $salt) { // Query the database and check if the username and the salted code exists $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)); $result = $this->db->query($query); // If a valid match was found if ($result->num_rows > 0) { // Change the password $stmt = $this->db->prepare("UPDATE `users` SET `password` = md5('{$password}'), `salted` = '' WHERE `username` = '{$this->db->real_escape_string(strtolower($username))}'"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the query $stmt->close(); if($affected) { return true; } else { return false; } } } } class manageUsers { public $db; // Database Property public $url; // Installation URL Property public $title; // Installation WebSite Title public $per_page; // Limit per page function getUsers($start) { global $LNG; // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'WHERE `idu` < \''.$this->db->real_escape_string($start).'\''; } // Query the database and get the latest 20 users // If load more is true, switch the query for the live query $query = sprintf("SELECT * FROM `users` %s ORDER BY `idu` DESC LIMIT %s", $start, $this->db->real_escape_string($this->per_page + 1)); $result = $this->db->query($query); while($row = $result->fetch_assoc()) { $rows[] = $row; } if(array_key_exists($this->per_page, $rows)) { $loadmore = 1; // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed array_pop($rows); } $output = ''; // Define the rows variable foreach($rows as $row) { $output .= '
'.$row['username'].'
'.$row['email'].'
'; $last = $row['idu']; } if($loadmore) { $output .= '
'; } // Return the array set return $output; } function getUser($id, $profile = null) { if($profile) { $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)); } else { $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)); } $result = $this->db->query($query); // If the user exists if($result->num_rows > 0) { $row = $result->fetch_assoc(); return $row; } else { return false; } } function suspendUser($id, $type) { // Type 0: Restore // Type 1: Suspend $user = $this->getUser($id); if($type && $user['suspended'] == 0) { $stmt = $this->db->prepare(sprintf("UPDATE `users` SET `suspended` = 1, `private` = 1 WHERE `idu` = '%s'", $this->db->real_escape_string($id))); } else { $stmt = $this->db->prepare(sprintf("UPDATE `users` SET `suspended` = 0, `private` = 1 WHERE `idu` = '%s'", $this->db->real_escape_string($id))); } $stmt->execute(); $affected = $stmt->affected_rows; $stmt->close(); if($affected) { if($type) { global $LNG; // Send suspended account email 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); } } } function deleteUser($id) { // Prepare the statement to delete the user from the database $stmt = $this->db->prepare("DELETE FROM `users` WHERE `idu` = '{$this->db->real_escape_string($id)}'"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the user was returned if($affected) { // Get the current pages created by the user $query = $this->db->query(sprintf("SELECT `id`,`name`,`art`,`as3_track` FROM `tracks` WHERE `uid` = '%s' ORDER BY `id` ASC", $this->db->real_escape_string($id))); $tracks = array(); while($rows = $query->fetch_assoc()) { $arts[] = $rows['art']; $tracks[$rows['name']] = $rows['as3_track']; } $arts = implode(',', $arts); // Delete the art covers and tracks from the server deleteMedia($arts, $tracks, 1); $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))); $this->db->query("DELETE FROM `playlistentries` WHERE `track` IN (SELECT `id` FROM `tracks` WHERE `uid` = '{$this->db->real_escape_string($id)}')"); $this->db->query("DELETE FROM `playlistentries` WHERE `playlist` IN (SELECT `id` FROM `playlists` WHERE `by` = '{$this->db->real_escape_string($id)}')"); $this->db->query("DELETE FROM `tracks` WHERE `uid` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `comments` WHERE `uid` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `likes` WHERE `by` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `views` WHERE `by` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `reports` WHERE `by` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `relations` WHERE `subscriber` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `relations` WHERE `leader` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `chat` WHERE `from` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `chat` WHERE `to` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `blocked` WHERE `uid` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `blocked` WHERE `by` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `notifications` WHERE `to` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `notifications` WHERE `from` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `playlists` WHERE `by` = '{$this->db->real_escape_string($id)}'"); return 1; } else { return 0; } } } class manageCategories { public $db; // Database Property public $url; // Installation URL Property function getCategories($type = null) { global $LNG; // Type 0: Return all categories // Type 1: Return the last category added if($type) { $query = sprintf("SELECT * FROM `categories` ORDER BY `id` DESC LIMIT 0, 1"); } else { $query = sprintf("SELECT * FROM `categories` ORDER BY `name` ASC"); } $result = $this->db->query($query); while($row = $result->fetch_assoc()) { $rows[] = $row; } foreach($rows as $row) { $output .= '
'.$row['name'].'
'; } return $output; } function addCategory($value) { $value = preg_replace(array('/[^[:alnum:]-]/u', '/--+/'), array('', '-'), $value); $stmt = $this->db->prepare(sprintf("INSERT INTO `categories` (`name`) VALUES ('%s')", $this->db->real_escape_string($value))); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If category was added return the latest category if($affected) { return $this->getCategories(1); } } function deleteCategory($id) { $stmt = $this->db->prepare(sprintf("DELETE FROM `categories` WHERE `id` = '%s'", $this->db->real_escape_string($id))); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If category was deleted return ($affected) ? 1 : 0; } } class managePayments { public $db; // Database Property public $url; // Installation URL Property public $title; // Installation WebSite Title public $per_page; // Limit per page function validatePayment($id) { // If the ID is the txn_id if(!ctype_digit($id)) { $field = 'txn_id'; } else { $field = 'id'; } // Select the report $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))); // Fetch the result $row = $query->fetch_assoc(); return $row; } function updatePayment($id, $type) { /* @function updatePayment Type 0: Suspended Type 1: Completed Type 2: Reversed Type 3: Refunded Type 4: Pending Type 5: Failed Type 6: Denied */ $row = $this->validatePayment($id); $types = array(0, 1, 2, 3, 4, 5, 6); if($row && in_array($type, $types)) { // Update the payment $stmt = $this->db->prepare("UPDATE `payments` SET `status` = ?, `time` = `time`, `valid` = `valid` WHERE `id` = ?"); $stmt->bind_param("ii", $type, $row['id']); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the row has been affected return ($affected) ? 1 : 0; } } function getPayments($start, $id = null) { // ID: Set to retrieve the payments history from a specific user global $LNG; // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND `id` < \''.$this->db->real_escape_string($start).'\''; } if($id) { $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)); } else { $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)); } $result = $this->db->query($query); while($row = $result->fetch_assoc()) { $rows[] = $row; } if(array_key_exists($this->per_page, $rows) && !$id) { $loadmore = 1; // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed array_pop($rows); } $output = ''; // Define the rows variable foreach($rows as $row) { if($row['type'] == 0) { $type = $LNG['monthly']; } else { $type = $LNG['yearly']; } // If the transaction is not completed, set a class to display the button in another color (red) if($row['status'] !== '1') { $class = ' modal-btn-active'; } else { $class = ''; } $date = explode('-', $row['time']); // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language) $month = intval($date[1]); $date = substr($LNG["month_$month"], 0, 3).' '.substr($date[2], 0, 2).', '.$date[0]; $output .= '
'.$row['username'].'
'.$date.' - '.$row['amount'].' '.$row['currency'].'
'.$content.'
'; $last = $row['id']; } if($loadmore) { $output .= '
'; } // Return the array set return $output; } function getPayment($id) { global $LNG; $row = $this->validatePayment($id); if($row) { $content = '
'.realName($row['username']).'
'; $date = explode('-', $row['time']); // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language) $month = intval($date[1]); $date = substr($LNG["month_$month"], 0, 3).' '.substr($date[2], 0, 2).', '.$date[0]; $valid = explode('-', $row['valid']); // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language) $month = intval($valid[1]); $valid = substr($LNG["month_$month"], 0, 3).' '.substr($valid[2], 0, 2).', '.$valid[0]; $status = paymentStatus($row['status']); $output = '
'.$LNG['transaction_details'].'
'.$LNG['status'].': '.$status.'
'.$LNG['ttl_last_name'].': '.$row['payer_last_name'].'
'.$LNG['ttl_first_name'].': '.$row['payer_first_name'].'
'.$LNG['ttl_email'].': '.$row['payer_email'].'
'.$LNG['ttl_country'].': '.$row['payer_country'].'
'.$LNG['transaction_id'].': #'.$row['txn_id'].'
'.$LNG['amount'].': '.$row['amount'].' '.$row['currency'].'
'.$LNG['date'].': '.$date.'
'.$LNG['plan'].': '.($row['type'] ? $LNG['yearly'].' '.$LNG['pro_plan'] : $LNG['monthly'].' '.$LNG['pro_plan']).'
'.$LNG['valid'].': '.$valid.'
'.$this->paymentButtons($row); return $output; } } function paymentButtons($payment) { global $LNG; // If the report is not reviewed if($payment['status'] == 0) { $output .= ''; } else { $output .= ''; } return '
'.$output.'
'; } } class manageReports { public $db; // Database Property public $url; // Installation URL Property public $title; // Installation WebSite Title public $per_page; // Limit per page function getReports($start, $tracks = null) { // Tracks: Array of tracks id to retrieve reports for global $LNG; if($tracks) { // If tracks is set but the value is not array, return false if(!is_array($tracks)) { return false; } $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))); } else { // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND `id` < \''.$this->db->real_escape_string($start).'\''; } $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)); } $result = $this->db->query($query); while($row = $result->fetch_assoc()) { $rows[] = $row; } if(array_key_exists($this->per_page, $rows) && !$tracks) { $loadmore = 1; // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed array_pop($rows); } $output = ''; // Define the rows variable foreach($rows as $row) { if($row['type'] == 0) { $type = $LNG['abusive_comment']; } else { $type = $LNG['copyright_infringement']; } $output .= '
'.$row['username'].'
'.$type.'
'.$content.'
'; $last = $row['id']; } if($loadmore) { $output .= '
'; } // Return the array set return $output; } function getReport($id) { global $LNG; // Select the report $query = $this->db->query(sprintf("SELECT * FROM `reports`, `users` WHERE `reports`.`by` = `users`.`idu` AND `reports`.`id` = '%s'", $this->db->real_escape_string($id))); // Fetch the result $row = $query->fetch_assoc(); if($row) { // Output report comment if($row['type'] == 0) { $x = $LNG['reported_by']; $y = $LNG['author']; $title = $LNG['abusive_comment']; $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']))); $result = $query->fetch_assoc(); $content = '
'.realName($result['username']).'
'; } else { $x = $LNG['claimant']; $y = $LNG['infringing_material']; $title = $LNG['copyright_infringement']; $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']))); $result = $query->fetch_assoc(); $content = '
'.$result['title'].' '.strtolower($LNG['by']).' '.realName($result['username']).'
'; } $output = '
'.$x.'
'.realName($row['username']).'
'.$title.'
'.$row['content'].'
'.(($result['username']) ? '
'.$y.'
'.$content.'
' : '').' '.$this->reportButtons($row); return $output; } } function reportButtons($report) { global $LNG; // If the report is not reviewed if($report['state'] == 0) { $output .= '
'; if($report['type'] == 0) { $output .= ' '; } else { $output .= ' '; } $output .= '
'; // If the report is safe } elseif($report['state'] == 1) { $output = notificationBox('info', $LNG['safe_report']); // If the reported material has been deleted } elseif($report['state'] == 2) { if($report['type'] == 0) { $output = notificationBox('error', $LNG['deleted_comment']); } else { $output = notificationBox('error', $LNG['deleted_track']); } } elseif($report['state'] == 3) { $output = notificationBox('error', $LNG['suspended_track']).'
'; } elseif($report['state'] == 4) { $output = notificationBox('info', $LNG['restored_track']).'
'; } return $output; } function manageReport($id, $type) { // Type 0: Delete comment // Type 1: Delete report // Type 2: Delete track // Type 3: Suspend track // Type 4: Restore track // Select the report $query = $this->db->query(sprintf("SELECT * FROM `reports`, `users` WHERE `reports`.`by` = `users`.`idu` AND `reports`.`id` = '%s'", $this->db->real_escape_string($id))); // Fetch the result $report = $query->fetch_assoc(); // Store the track ID $track = $report['track']; if($type == 1) { // Make the report safe $stmt = $this->db->prepare("UPDATE `reports` SET `state` = '1' WHERE `track` = ? AND `type` = ? AND `id` = ?"); $stmt->bind_param("iii", $report['track'], $report['type'], $id); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the row has been affected return ($affected) ? 1 : 0; } else { // Prepare the statement to delete the message from the database if($report['type'] == 1) { // If the track has been suspended, send an email $query = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($track))); $result = $query->fetch_assoc(); if($type == 2) { deleteMedia($result['art'], array($result['name'] => $result['as3_track']), 1); $stmt = $this->db->prepare("DELETE FROM `tracks` WHERE `id` = '{$this->db->real_escape_string($track)}'"); } elseif($type == 3) { $stmt = $this->db->prepare("UPDATE `tracks` SET `public` = '2', `time` = `time` WHERE `id` = '{$this->db->real_escape_string($track)}'"); } elseif($type == 4) { $stmt = $this->db->prepare("UPDATE `tracks` SET `public` = '1', `time` = `time` WHERE `id` = '{$this->db->real_escape_string($track)}'"); } } else { $stmt = $this->db->prepare("DELETE FROM `comments` WHERE `id` = '{$this->db->real_escape_string($track)}'"); } // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); if($affected) { if($type == 3) { // Suspend the track for the selected report, and dimiss the rest of the reports $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)); $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)); } elseif($type == 4) { // Restore the track $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))); } else { $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))); } if($report['type'] == 1) { global $LNG; // Send mail to the copyright claimer sendMail($report['email'], sprintf($LNG['ttl_copyright_notification'], $result['title']), sprintf($LNG['copyright_mail_1'], realName($report['username'], $report['first_name'], $report['last_name']), permalink($this->url.'/index.php?a=track&id='.$result['id'].'&name='.$result['title']), $result['title'], $id, $this->url, $this->title), $this->email); // Send mail to the abuser sendMail($result['email'], sprintf($LNG['ttl_copyright_notification'], $result['title']), sprintf($LNG['copyright_mail_0'], realName($result['username'], $result['first_name'], $result['last_name']), permalink($this->url.'/index.php?a=track&id='.$result['id'].'&name='.$result['title']), $result['title'], permalink($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); // If the track is suspended or restored if($type == 3 || $type == 4) { return 1; } $this->db->query("DELETE FROM `comments` WHERE `tid` = '{$this->db->real_escape_string($track)}'"); $this->db->query("DELETE FROM `likes` WHERE `track` = '{$this->db->real_escape_string($track)}'"); $this->db->query("DELETE FROM `notifications` WHERE `parent` = '{$this->db->real_escape_string($track)}'"); $this->db->query("DELETE FROM `playlistentries` WHERE `track` = '{$this->db->real_escape_string($track)}'"); } else { $this->db->query("DELETE FROM `notifications` WHERE `child` = '{$this->db->real_escape_string($track)}' AND `type` = '1'"); } return 1; } } } } class feed { public $db; // Database Property public $url; // Installation URL Property public $title; // Installation WebSite Title public $email; // Installation Default E-mail public $id; // The ID of the user public $username; // The username public $user_email; // The email of the current username public $per_page; // The per_page limit for feed public $c_start; // The row where to start the nex public $c_per_page; // Comments per_page limit public $s_per_page; // Subscribers per page (dedicated profile page) public $m_per_page; // Conversation Messages (Chat) per page public $time; // The time option from the admin panel public $art_size; // Image size allowed for upload (art cover) public $art_format; // Image formats allowed for upload (art cover) public $track_size; // Track size allowed for upload public $track_format; // Track formats allowed for upload public $track_size_total; // Total track size allowed for upload public $subscriptions; // The public variable to be accessed outside of the class to pass variable to sidebar functions public $message_length; // The maximum message length allowed for messages/comments public $max_images; // The maxium images allowed to be uploaded per message public $is_admin; // The option for is_admin to show the post no matter what public $profile; // The current viewed user profile public $profile_id; // The profile id of the current viewed user profile public $profile_data; // The public variable which holds all the data for queried user public $subscriptionsList; // The subscriptions users list Array([value],[count]) public $subscribersList; // The subscribers users list Array([value],[count]) public $subsList; // The subs list for dedicated subs page public $trackList; // A list of tracks separated by "," (comma) public $l_per_post; // Likes per post (small thumbs) public $online_time; // The amount of time an user is being kept as online public $friends_online; // The amount of online friends to be displayed on the Feed/Subscriptions page public $chat_length; // The maximum chat length allowed for conversations public $email_comment; // The admin settings for allowing e-mails on comments to be sent public $email_like; // The admin settings for allowing e-mails on likes to be sent public $email_new_friend; // The admin settings for allowing e-mails on new friendship to be sent public $categories; // The category list function getTracks($query, $type, $typeVal) { // QUERY: Holds the query string // TYPE: [exploreTracks, loadProfile] // TYPEVAL: Values for the JS functions // EXTRA: Is defined when two ID values are set, and need the extra one as the latest ID global $LNG, $settings, $s3; // Run the query $result = $this->db->query($query); // Set the result into an array $rows = array(); while($row = $result->fetch_assoc()) { $rows[] = $row; } // If the Stream is empty, display a welcome message if(empty($rows) && $type == 'exploreTracks') { return $this->showError('no_results', 1); } elseif(empty($rows) && $type == 'searchTracks') { return $this->showError('no_results', 1); } // Define the $loadmore variable $loadmore = ''; // If there are more results available than the limit, then show the Load More Comments if(array_key_exists($this->per_page, $rows)) { $loadmore = 1; // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed array_pop($rows); } // Define the $messages variable $sound = ''; // If it's set profile, then set $profile if($this->profile) { $profile = ', \''.$this->profile.'\''; } // Start outputting the content foreach($rows as $row) { $time = $row['time']; $b = ''; if($this->time == '0') { $time = date("c", strtotime($row['time'])); } elseif($this->time == '2') { $time = $this->ago(strtotime($row['time'])); } elseif($this->time == '3') { $date = strtotime($row['time']); $time = date('Y-m-d', $date); $b = '-standard'; } // Define the style variable (reset the last value) $style = $row['as3_url'] = $url = ''; // If the track is private if($this->username !== $row['username'] && $row['public'] == 0) { $hide = 1; } else { $hide = 0; } if($row['as3_track']) { if($settings['as3']) { $cmd = $s3->getCommand('GetObject', array( 'Bucket' => $settings['as3_bucket'], 'Key' => 'uploads/tracks/'.$row['name'], 'ResponseContentDisposition' => 'filename='.str_replace(array('%21', '%2A', '%27', '%28', '%29', '%20'), array('!', '*', '\'', '(', ')', ' '), rawurlencode($row['title'].'.'.pathinfo($row['name'], PATHINFO_EXTENSION))) )); $req = $s3->createPresignedRequest($cmd, '1 week'); $url = (string)$req->getUri(); } $row['as3_url'] = $url; } // If the user is a visitor if(empty($this->username)) { $style = ' style="display: none;"'; } if($hide == 1 && !$this->is_admin) { $error = $this->showError('track_hidden_1'); $sound .= $error[0]; } elseif($hide == 2) { $error = $this->showError('track_suspended_1'); $sound .= $error[0]; } else { $tag = $this->fetchCategory($row['tag']); if($type == 'trackPage') { $comment = (($this->id) ? '
'.$LNG['post'].'
' : '').'
'.$this->getComments($row['id'], null, $this->c_start).'
'; } $track .= '
'.$row['title'].'
'.$this->getActions($row['id'], null, ($row['as3_url'] ? $row['as3_url'] : $this->url.'/uploads/tracks/'.$row['name'])).'
'.$comment.'
'; $start = (isset($row['extra_id']) ? $row['extra_id'] : $row['id']); } } // If the $loadmore button is set, then show the Load More Messages button if($loadmore) { $track .= '
'.$LNG['load_more'].'
'; } return array($track, 0); } function explore($start, $value) { // If the $start value is 0, empty the query; if($value == 'popular music' || $value == 'liked music') { $limit = ", ".($this->db->real_escape_string($start) + ($this->per_page))." as `extra_id`"; } else { if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND `tracks`.`id` < \''.$this->db->real_escape_string($start).'\''; } } // Query for the Popular Music filter if($value == 'popular music') { $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)); $value = '\''.$value.'\''; } elseif($value == 'liked music') { $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)); $value = '\''.$value.'\''; } elseif(!empty($value)) { $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)); $value = '\''.$value.'\''; } else { $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)); $value = '\'\''; } return $this->getTracks($query, 'exploreTracks', $value); } function stream($start, $value) { $this->subscriptions = $this->getSubscriptionsList(); // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND tracks.id < \''.$this->db->real_escape_string($start).'\''; } if(!empty($this->subscriptions)) { $uid = $this->id.','.$this->subscriptions; } else { $uid = $this->id; } // The query to select the subscribed users $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)); $value = '\'\''; // If the user subscribed to other users get the tracks (prevents fatal error because of empty IN () query) if(!empty($this->subscriptions)) { return $this->getTracks($query, 'loadStream', $value); } else { return $this->showError('welcome_stream'); } } function getProfile($start, $value) { $profile = $this->profile_data; $this->profile_id = $profile['idu']; // If the username exist if(!empty($profile['idu'])) { $relationship = $this->verifyRelationship($this->id, $this->profile_id, 0); // Check privacy switch($profile['private']) { case 0: break; case 1: // Check if the username is not same with the profile if($this->profile !== $this->username) { if($profile['suspended']) { return $this->showError('profile_suspended'); } return $this->showError('profile_private'); } break; case 2: // Check relationship if(!$relationship) { return $this->showError('profile_semi_private'); } break; } $allowedDates = $this->listDates('profile'); // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND tracks.id < \''.$this->db->real_escape_string($start).'\''; } // Decide if the query will include only public sounds or not $public = ($this->username == $this->profile) ? 'AND `tracks`.`public` != 2' : 'AND `tracks`.`public` = 1'; if(in_array($value, $allowedType)) { $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)); $value = '\''.$value.'\''; } elseif(in_array($value, $allowedDates)) { $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)); $value = '\''.$value.'\''; } else { $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)); $value = '\'\''; } return $this->getTracks($query, 'loadProfile', $value); } else { return $this->showError('profile_not_exist'); } } function getSubscriptionsList() { // The query to select the subscribed users $query = sprintf("SELECT `leader` FROM `relations` WHERE `subscriber` = '%s'", $this->db->real_escape_string($this->id)); // Run the query $result = $this->db->query($query); // The array to store the subscribed users $subscriptions = array(); while($row = $result->fetch_assoc()) { $subscriptions[] = $row['leader']; } // Close the query $result->close(); // Return the subscriptions list (e.g: 13,22,19) return implode(',', $subscriptions); } public function profileData($username = null, $id = null) { // The query to select the profile // If the $id is set (used in Subscribe function for profiels) then search for the ID if($id) { $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)); } else { $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)); } // Run the query $result = $this->db->query($query); return $result->fetch_assoc(); } function fetchProfile($profile) { global $LNG, $CONF; $coverImage = ((!empty($profile['cover'])) ? $profile['cover'] : 'default.png'); $coverAvatar = ((!empty($profile['image'])) ? $profile['image'] : 'default.png'); $profileButtons = ((!empty($profile['idu'])) ? '
'.$this->getSubscribe(null, null, null).'
'.$this->chatButton($profile['idu'], $profile['username'], 1) : ''); $cover = '
'.realName($profile['username'], $profile['first_name'], $profile['last_name']).''.(($this->getProStatus($profile['idu'])) ? '' : '').'
'.((location($profile['country'], $profile['city'])) ? '
'.location($profile['country'], $profile['city']).'
' : '').'
'.$profileButtons.'
'.$this->coverButtons().'
'; return $cover; } function countSongs($id = null) { // If the logged in username is the same as the profile, count the private songs as well, otherwise only public ones $public = ($this->username == $this->profile) ? 'AND `tracks`.`public` != 2' : 'AND `tracks`.`public` = 1'; $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)); $result = $query->fetch_row(); return $result[0]; } function getPlaylistTracks($id) { // Get the tracks for Playlist page $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); return $this->getTracks($query, 'loadPlaylist', null); } function getPlaylists($start = null, $type = null, $query = null) { global $LNG; // Type 0: Return the number of playlists from user // Type 1: Return the playlists for profiles // Type 2: Return the playlists for search // Type 3: Return the playlist for playlist page if($type) { if($start == 0) { $start = ''; } else { $start = 'AND `playlists`.`id` < \''.$this->db->real_escape_string($start).'\''; } if($type == 1) { $public = ($this->username == $this->profile) ? '' : 'AND `playlists`.`public` = 1'; $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)); } elseif($type == 2) { $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)); } elseif($type == 3) { $public = ($this->username == $this->profile) ? '' : 'AND `playlists`.`public` = 1'; $q = sprintf("SELECT * FROM `playlists`,`users` WHERE `playlists`.`id` = '%s' AND `users`.`idu` = `playlists`.`by`", $this->db->real_escape_string($query)); } $getPlaylists = $this->db->query($q); // Declare the rows array $rows = array(); while($row = $getPlaylists->fetch_assoc()) { // Store the result into the array $rows[] = $row; } if($type == 3) { // If the playlist doesn't exist if(!$rows) { return; } // If the playlist is private, and the logged-in user is not the author of the playlist elseif($rows[0]['public'] == 0 && $rows[0]['by'] !== $this->id) { return $this->showError('playlist_hidden'); } } else { // Decide whether the load more will be shown or not if(array_key_exists($this->per_page, $rows)) { $loadmore = 1; // Unset the last array element because it's not needed, it's used only to predict if the Load More Messages should be displayed array_pop($rows); } } // Start the output foreach($rows as $value) { $time = $value['time']; $b = ''; if($this->time == '0') { $time = date("c", strtotime($value['time'])); } elseif($this->time == '2') { $time = $this->ago(strtotime($value['time'])); } elseif($this->time == '3') { $date = strtotime($value['time']); $time = date('Y-m-d', $date); $b = '-standard'; } $output .= '
'; } if($loadmore) { $output .= '
'.$LNG['load_more'].'
'; } // If the query is for the playlist page, return array if($type == 3) { $tracks = $this->getPlaylistTracks($query); return array($output.$tracks[0], 0); } return $output; } else { $public = ($this->username == $this->profile) ? '' : 'AND `playlists`.`public` = 1'; $query = $this->db->query(sprintf("SELECT count(`by`) FROM `playlists` WHERE `playlists`.`by` = '%s' %s", $this->db->real_escape_string($this->profile_id), $public)); $result = $query->fetch_row(); return $result[0]; } } function getPlaylistActions($id, $type = null) { global $LNG; // Get the likes, views, and other info $query = sprintf("SELECT * FROM `playlists` WHERE `id` = '%s'", $this->db->real_escape_string($id)); // Run the query $result = $this->db->query($query); // Get the array element for the like $get = $result->fetch_assoc(); $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)); $tracks = $count->fetch_row(); $count->close(); // Determine whether to show the delete/privacy buttons or not if($this->id == $get['by']) { // If it's current username is the same with the current author if($get['public'] == 1) { $privacy = '
'; $delete = '
'; } else { $privacy = '
'; $delete = '
'; } } else { // If the current username is not the same as the author $privacy = ''; $delete = ''; } if($this->shuffle) { $shuffle = '
'; } $output = '
'.$delete.''.$privacy.''.$shuffle.'
'.$tracks[0].' '.$LNG['tracks'].'
'; return $output; } function playlistArt($id, $limit) { $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))); while($result = $query->fetch_assoc()) { $rows[] = $result; } if(!empty($rows)) { // Display the album artwork $n = 0; foreach($rows as $row) { $output .= '
'; $n++; } } else { // Show the default artwork $output .= '
'; } return $output; } function coverButtons() { global $LNG; $buttons = array( 't'.$this->countSongs() => array('', '', (($this->countSongs() == 1) ? 'track' : 'tracks')), ((!empty($this->subscriptionsList[1])) ? 'g'.$this->subscriptionsList[1] : '') => array('&r=', 'subscriptions'), ((!empty($this->subscribersList[1])) ? 's'.$this->subscribersList[1] : '') => array('&r=', 'subscribers'), (($this->getLikes()) ? 'l'.$this->getLikes() : '') => array('&r=', 'likes'), (($this->getPlaylists()) ? 'p'.$this->getPlaylists() : '') => array('&r=', 'playlists')); /* array map: value => parameter => parameter value 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 */ foreach($buttons as $value => $name) { // Check whether the value is empty or not in order to return the button if($value) { $button .= ''.str_replace(array('t', 'g', 's', 'l', 'p'), '', $value).' '.$LNG[$name[1].$name[2]].''; } } return $button; } function getProfileCard($profile) { global $LNG, $CONF; $coverImage = ((!empty($profile['cover'])) ? $profile['cover'] : 'default.png'); $coverAvatar = ((!empty($profile['image'])) ? $profile['image'] : 'default.png'); $subscribersList = $this->getSubs($profile['idu'], 1, null); $subscribe = $this->getSubscribe(null, null, 1); $count = $this->countSongs($profile['idu']); $card = '
'.realName($profile['username'], $profile['first_name'], $profile['last_name']).''.(($this->getProStatus($profile['idu'])) ? '' : '').'
'.((location($profile['country'], $profile['city'])) ? location($profile['country'], $profile['city']) : '').'
'.(($count) ? '
'.$count.'
' : '').(($subscribersList[1]) ? '
'.$subscribersList[1].'
' : '').''.((!empty($subscribe)) ? '
'.$subscribe.'
'.$this->chatButton($profile['idu'], $profile['username'], 1).'
' : '').'
'; return $card; } function fetchProfileInfo($profile) { global $LNG, $CONF; // Array: database column name => url model $social = array( 'website' => '%s', 'facebook' => 'http://facebook.com/%s', 'gplus' => 'http://plus.google.com/%s', 'twitter' => 'http://twitter.com/%s', 'youtube' => 'http://youtube.com/%s', 'soundcloud' => 'https://soundcloud.com/%s', 'myspace' => 'http://myspace.com/%s', 'lastfm' => 'http://last.fm/user/%s', 'vimeo' => 'https://vimeo.com/%s', 'tumblr' => 'http://%s.tumblr.com' ); $info = ''; return $info; } function checkNewNotifications($limit, $type = null, $for = null, $ln = null, $cn = null, $fn = null, $dn = null) { global $LNG, $CONF; // $ln, $cn, $fn, $dn holds the filters for the notifications // Type 0: Just check for and show the new notification alert // Type 1: Return the last X notifications from each category. (Drop Down Notifications) // Type 2: Return the latest X notifications (read and unread) (Notifications Page) // For 0: Returns the Global Notifications // For 1: Return results for the Chat Messages Notifications (Drop Down) // For 2: Return Chat Messages results for the Notifications Page // Start checking for new notifications if(!$type) { // Check for new likes events if($ln) { $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))); $lc = $checkLikes->num_rows; } // Check for new comments events if($cn) { $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))); // If any, return 1 (show notification) $cc = $checkComments->num_rows; } // Check for new friend additions if($fn) { $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))); // If any, return 1 (show notification) $fc = $checkFriends->num_rows; } if($for) { if($dn) { $checkChats = $this->db->query(sprintf("SELECT `id` FROM `chat` WHERE `to` = '%s' AND `read` = '0'", $this->db->real_escape_string($this->id))); // If any, return 1 (show notification) $dc = $checkChats->num_rows; } } $output = array('response' => array('global' => $lc + $cc + $fc, 'messages' => $dc)); return json_encode($output); } else { // Define the arrays that holds the values (prevents the array_merge to fail, when one or more options are disabled) $likes = array(); $comments = array(); $friends = array(); $chats = array(); if($type) { // Get the events and display all unread messages [applies only to the drop down widgets] if($for == 2 && $type !== 2 || !$for && $type !== 2) { if($ln) { // Check for new likes events $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))); // Fetch the comments while($row = $checkLikes->fetch_assoc()) { $likes[] = $row; } } if($cn) { // Check for new comments events $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))); // Fetch the comments while($row = $checkComments->fetch_assoc()) { $comments[] = $row; } } if($fn) { // Check for new messages events $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))); // Fetch the messages while($row = $checkFriends->fetch_assoc()) { $friends[] = $row; } } if($for == 2) { if($dn) { // Check for new messages events $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))); // Fetch the chat while($row = $checkChats->fetch_assoc()) { $chats[] = $row; } } } } // Return the unread messages for drop-down messages notifications (excludes $for 2 and $type 2) elseif($type !== 2 && $for == 1) { if($dn) { // Check for new messages events $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))); // Fetch the chat while($row = $checkChats->fetch_assoc()) { $chats[] = $row; } } } // If there are no new (unread) notifications (for the drop-down wdigets), get the lastest notifications if(!$for) { // Verify for the drop-down notifications if(empty($likes) && empty($comments) && empty($friends) || $type == 2) { $all = 1; } } // For the Notifications Page elseif($for == 2 && $type == 2) { // Verify for the notifications page $all = 1; } if($all) { // LR: Enable limit rows when there are unread messages $lr = 1; if($ln) { $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)); while($row = $checkLikes->fetch_assoc()) { $likes[] = $row; } } if($cn) { $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)); while($row = $checkComments->fetch_assoc()) { $comments[] = $row; } } if($fn) { $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)); while($row = $checkFriends->fetch_assoc()) { $friends[] = $row; } } if($for == 2) { if($dn) { $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)); while($row = $checkChats->fetch_assoc()) { $chats[] = $row; } } } // If there are no latest notifications if($for == 2) { // Verify for the notifications page if(empty($likes) && empty($comments) && empty($friends) && empty($chats)) { return '
'.$LNG['no_notifications'].'
'.$LNG['notifications_settings'].'
'; } } else { // Verify for the drop-down notifications if(empty($likes) && empty($comments) && empty($friends)) { return '
'.$LNG['no_notifications'].'
'; } } } } // Add the types into the recursive array results $x = 0; foreach($likes as $like) { $likes[$x]['event'] = 'like'; $x++; } $y = 0; foreach($comments as $comment) { $comments[$y]['event'] = 'comment'; $y++; } $a = 0; foreach($friends as $friend) { $friends[$a]['event'] = 'friend'; $a++; } $b = 0; foreach($chats as $chat) { $chats[$b]['event'] = 'chat'; $b++; } $array = array_merge($likes, $comments, $friends, $chats); // Sort the array usort($array, 'sortDateAsc'); $i = 0; foreach($array as $value) { if($i == $limit && $lr == 1) break; $time = $value['time']; $b = ''; if($this->time == '0') { $time = date("c", strtotime($value['time'])); } elseif($this->time == '2') { $time = $this->ago(strtotime($value['time'])); } elseif($this->time == '3') { $date = strtotime($value['time']); $time = date('Y-m-d', $date); $b = '-standard'; } $events .= '
'; if($value['event'] == 'like') { $events .= '
'; } elseif($value['event'] == 'comment') { $events .= '
'.sprintf($LNG['new_comment_notification'], permalink($this->url.'/index.php?a=profile&u='.$value['username']), realName($value['username'], $value['first_name'], $value['last_name']), permalink($this->url.'/index.php?a=track&id='.$value['parent'].'#comment'.$value['child'])).'.
'.$time.'
'; } elseif($value['event'] == 'friend') { $events .= '
'.sprintf($LNG['new_friend_notification'], permalink($this->url.'/index.php?a=profile&u='.$value['username']), realName($value['username'], $value['first_name'], $value['last_name'])).'.
'.$time.'
'; } elseif($value['event'] == 'chat') { $events .= '
'.sprintf($LNG['new_chat_notification'], permalink($this->url.'/index.php?a=profile&u='.$value['username']), realName($value['username'], $value['first_name'], $value['last_name']), permalink($this->url.'/index.php?a=messages&u='.$value['username'].'&id='.$value['idu'])).'.
'.$this->parseMessage(substr($value['message'], 0, 45)).'...
'.$time.'
'; } $events .= '
'; $i++; } if(!$for) { // Mark global notifications as read $this->db->query("UPDATE `notifications` SET `read` = '1', `time` = `time` WHERE `to` = '{$this->id}' AND `read` = '0'"); } // Update when the for is set, and it's not viewed from the Notifications Page elseif($type !== 2) { // Mark chat messages notifications as read $this->db->query("UPDATE `chat` SET `read` = '1', `time` = `time` WHERE `to` = '{$this->id}' AND `read` = '0'"); } // return the result return $events; } // If no notification was returned, return 0 } function getCategories() { $query = $this->db->query("SELECT `name` FROM `categories`"); while($row = $query->fetch_assoc()) { $rows[] = $row; } // Flat the array foreach($rows as $category) { $categories[] = $category['name']; } return $categories; } function fetchCategory($categories) { $categories = explode(',', $categories); // If the tag is viewed from a filter page, set it to the filter's name if($_GET['a'] == 'explore' && !empty($_GET['filter']) && $_GET['filter'] !== 'popular music' && $_GET['filter'] !== 'liked music') { return strtolower($_GET['filter']); } $list = array_map('strtolower', $this->categories); // If a tag is matched with one of the categories foreach($categories as $category) { if(in_array(strtolower($category), $list)) { return $category; } } // Return the first tag return $categories[0]; } function chatButton($id, $username, $z = null) { // Profile: Returns the current row username // Z: A switcher for the sublist CSS class global $LNG; if($z == 1) { $style = ' subslist_message'; } if(!empty($this->username) && $this->username !== $username) { return '
'; } } function getSubscribe($type = null, $list = null, $z = null) { global $LNG; // Type 0: Just show the button // Type 1: Go trough the add friend query // List: Array (for the dedicated profile page list) // Z: A switcher for the sublist CSS class if($list) { $profile = $list; } else { $profile = $this->profile_data; } if($z == 1) { $style = ' subslist'; } // 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 // Verify if the profile is completely private if($profile['private'] == 1) { // Run the query only if the user is logged-in if($this->id) { $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))); } if($avoid->num_rows == 0) { if($this->username == $profile['username']) { // Set a variable if the profile is private and the one who views the profile is the owner, then show settings button $a = 1; } else { return false; } } } elseif($profile['private'] == 2) { if($this->id) { $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))); // If the user have semi-private profile, hide the add button $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))); } if($result->num_rows == 0 && $avoid->num_rows == 0) { if($this->username == $profile['username']) { // Set a variable if the profile is semi-private and the one who views the profile is the owner, then show settings button $a = 1; } else { return false; } } } // Verify if the username is logged in, and it's not the same with the viewed profile if(!empty($this->username) && $this->username !== $profile['username']) { if($type) { $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']))); // If a relationship already exist, then remove if($result->num_rows) { $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']))); $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'])); } else { $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']))); $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'])); if($this->email_new_friend) { // If user has emails on new friendships enabled if($profile['email_new_friend']) { // Send e-mail 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']), permalink($this->url.'/index.php?a=profile&u='.$this->username), $this->username, $this->title, permalink($this->url.'/index.php?a=settings&b=notifications')), $this->email); } } } } } elseif($this->username == $profile['username'] || $a == 1) { return '
'; } else { return false; } $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']))); if($result->num_rows) { return '
Unfollow
'; } else { return '
Follow
'; } } function showError($error, $type = null) { global $LNG; // Type 1: return only the description // Type 0: return title and description if($type) { $message = '
'.$LNG["$error"].'
'; } else { $message = '
'.$LNG["$error"].'
'; } return array($message, 1); } function verifyRelationship($user_id, $profile_id, $type) { // Type 0: The viewed profile subscribed to the logged in username // Type 1: The logged in username is a subscriber of the viewed profile if($type == 0) { $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))); } elseif($type == 1) { $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))); } // If the logged in username is the same with the viewed profile if($user_id == $profile_id) { return 2; } // If a relationship exist elseif($result->num_rows) { return 1; } else { return 0; } } function validateTrack($values, $type, $num) { global $settings; // Type 0: For Edit Page // Type 1: For Upload Page // Validate Release date if(!empty($values['day']) && !empty($values['month']) && !empty($values['year'])) { $values['release'] = date("Y-m-d", mktime(0, 0, 0, $values['month'], $values['day'], $values['year'])); } else { $values['release'] = 0; } $values['record'] = htmlspecialchars(trim(nl2clean($values['record'], ENT_QUOTES, 'UTF-8'))); // Validate License if($values['license']) { if($values['license-nc'] != 0) { $values['license-nc'] = 1; } // License Types $licenseTypes = array(0, 1, 2); if(!in_array($values['license-nd-sa'], $licenseTypes)) { $values['license-nd-sa'] = 0; } $values['license'] = '1'.$values['license-nc'].$values['license-nd-sa']; } else { $value['license'] = 0; } // Unset unwated fields unset($values['day']); unset($values['month']); unset($values['year']); unset($values['license-nc']); unset($values['license-nd-sa']); if($type) { $allowedColumns = array('title', 'description', 'name', 'art', 'tag', 'buy', 'record', 'release', 'license', 'size', 'download', 'public'); $values['title'] = $values['title'][$num]; } else { $allowedColumns = array('title', 'description', 'art', 'tag', 'buy', 'record', 'release', 'license', 'download', 'public'); $values['title'] = $values['title'][0]; } // Strip unwated columns foreach($values as $key => $value) { if(!in_array($key, $allowedColumns)) { unset($values[$key]); } } // Validate Description $values['description'] = htmlspecialchars(trim(nl2clean($values['description']))); $desclimit = 5000; if(strlen($values['description']) > $desclimit) { $error[] = array(6, $desclimit); } // Validate URL if((!filter_var($values['buy'], FILTER_VALIDATE_URL) && !empty($values['buy'])) || (substr($values['buy'], 0, 7) != 'http://' && substr($values['buy'], 0, 8) != 'https://' && !empty($values['buy']))) { $error[] = array(7); } // Validate Tags $tags = array_filter(explode(',', $values['tag'])); foreach($tags as $key => $tag) { $tag = strtolower($tag); // Array { Replace any unwated characters, Replace consecutive "-" characters } $tag = preg_replace(array('/[^[:alnum:]-]/u', '/--+/'), array('', '-'), $tag); // Remove tags that has only "-" characters if($tag == '-') { unset($tags[$key]); } else { $tags[$key] = $tag; } } // Remove empty and duplicated tags $tags = array_filter(array_unique($tags)); $taglimit = 60; $tagmax = 30; $tagmin = 1; if(count($tags) > $tagmax) { $error[] = array(8, $tagmax); } elseif(count($tags) < $tagmin) { $error[] = array(9, $tagmin); } // Check for tags length foreach($tags as $tag) { if(strlen($tag) >= $taglimit) { $error[] = array(12, $taglimit); } } $values['tag'] = implode(',', $tags).','; // Validate Title $titlelimit = 100; if(empty($values['title'])) { $error[] = array(10); } elseif(strlen($values['title']) > $titlelimit) { $error[] = array(11, $titlelimit); } else { $values['title'] = htmlspecialchars(trim(nl2clean($values['title']))); } // Validate Download if($values['download'] != 0) { $values['download'] = 1; } // Validate Privacy if($values['public'] != 0) { $values['public'] = 1; } // Validate the files to be uploaded if(empty($error)) { $tpath = __DIR__ .'/../uploads/tracks/'; $mpath = __DIR__ .'/../uploads/media/'; if($type) { if(isset($_FILES['track']['name'])) { // Get the total uploaded size $query = $this->db->query(sprintf("SELECT (SELECT SUM(`size`) FROM `tracks` WHERE `uid` = '%s') as upload_size", $this->db->real_escape_string($this->id))); $result = $query->fetch_assoc(); $ext = strtolower(pathinfo($_FILES['track']['name'][$num], PATHINFO_EXTENSION)); $size = $_FILES['track']['size'][$num]; $fullname = $_FILES['track']['name'][$num]; $allowedExt = explode(',', $this->track_format); $maxsize = $this->track_size; // Validate the total upload size allowed if(($result['upload_size'] + $size) > $this->track_size_total) { $error[] = array(0, saniscape($values['title'])); } // Get file type validation $track = validateFile($_FILES['track']['tmp_name'][$num], $_FILES['track']['name'][$num], $allowedExt, 1); if($track['valid'] && $size < $maxsize && $size > 0) { $t_tmp_name = $_FILES['track']['tmp_name'][$num]; $name = pathinfo($_FILES['track']['name'][$num], PATHINFO_FILENAME); $size = $_FILES['track']['size'][$num]; $tName = mt_rand().'_'.mt_rand().'_'.mt_rand().'.'.$this->db->real_escape_string($ext); // Send the track name in array format to the function $values['name'] = $tName; $values['size'] = $size; $t_upload = true; } elseif($_FILES['track']['name'][$num] == '') { // If the file size is higher than allowed or 0 $error[] = array(1); } if(!empty($ext) && ($size > $maxsize || $size == 0)) { // If the file size is higher than allowed or 0 $error[] = array(2, saniscape($values['title']), fsize($maxsize)); } if(!empty($ext) && !$track['valid']) { // If the file format is not allowed $error[] = array(3, saniscape($values['title']), implode(', ', $allowedExt)); } } } if(empty($GLOBALS['multiart'])) { if(isset($_FILES['art']['name'])) { foreach($_FILES['art']['error'] as $key => $err) { $ext = strtolower(pathinfo($_FILES['art']['name'][$key], PATHINFO_EXTENSION)); $size = $_FILES['art']['size'][$key]; $allowedExt = explode(',', $this->art_format); $maxsize = $this->art_size; // Get file type validation $image = validateFile($_FILES['art']['tmp_name'][$key], $_FILES['art']['name'][$key], $allowedExt, 0); if($image['valid'] && $size < $maxsize && $size > 0 && !empty($image['width']) && !empty($image['height'])) { $m_tmp_name = $_FILES['art']['tmp_name'][$key]; $name = pathinfo($_FILES['art']['name'][$key], PATHINFO_FILENAME); $fullname = $_FILES['art']['name'][$key]; $size = $_FILES['art']['size'][$key]; // If there's no error during the track's upload if(empty($error)) { // Generate the file name & store it into a super global to check when multi upload $mName = $GLOBALS['multiart'] = mt_rand().'_'.mt_rand().'_'.mt_rand().'.'.$this->db->real_escape_string($ext); } // Delete the old image when editing the track if(!$type) { $query = $this->db->query(sprintf("SELECT `art` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($_GET['id']))); $result = $query->fetch_assoc(); deleteImages(array($result['art']), 2); } // Send the image name in array format to the function $values['art'] = $mName; $m_upload = true; } elseif($_FILES['art']['name'][$key] == '') { // If no file is selected if($type) { $values['art'] = 'default.png'; } else { // If the cover artwork is not selected, unset the image so that it doesn't update the current one unset($values['art']); } } if(!empty($ext) && ($size > $maxsize || $size == 0)) { // If the file size is higher than allowed or 0 $error[] = array(4, fsize($maxsize)); } if(!empty($ext) && !$image['valid']) { // If the file format is not allowed $error[] = array(5, implode(', ', $allowedExt)); } } } } else { // Generate a new file name $ext = strtolower(pathinfo($GLOBALS['multiart'], PATHINFO_EXTENSION)); $finalName = mt_rand().'_'.mt_rand().'_'.mt_rand().'.'.$this->db->real_escape_string($ext); // Copy the previous track image copy($mpath.$GLOBALS['multiart'], $mpath.$finalName); // Store the new file name $values['art'] = $finalName; } } if(!empty($error)) { return array(0, $error); } else { if($t_upload) { if($settings['as3']) { global $s3; try { $s3->putObject(array( 'Bucket' => $settings['as3_bucket'], 'Key' => 'uploads/tracks/'.$tName, 'Body' => fopen($t_tmp_name, 'rb') )); $values['as3_track'] = 1; } catch(S3Exception $e) { return array(0, $e); } } else { $values['as3_track'] = 0; // Move the file into the uploaded folder move_uploaded_file($t_tmp_name, $tpath.$tName); } } if($m_upload) { // Move the file into the uploaded folder move_uploaded_file($m_tmp_name, $mpath.$mName); } return array(1, $values); } } function updateTrack($values, $type) { // Type 0: For Edit Page // Type 1: For Upload Page global $LNG; $x = 0; foreach($values['title'] as $key => $val) { // Validate the track $validate = $this->validateTrack($values, $type, $key); // If there's an error if(!$validate[0]) { // Display the errors foreach($validate[1] as $error) { $err .= notificationBox('error', sprintf($LNG["{$error[0]}_upload_err"], ((isset($error[1])) ? $error[1] : ''), ((isset($error[2])) ? $error[2] : ''))); } // Return the error (edit page) if(!$type) { return $err; } } // If the track is validated if($validate[0]) { // Prepare the values foreach($validate[1] as $column => $value) { // Set a date for the MySQL strict mode validation if($column == 'release') { $value = (empty($value) ? '0000-00-00' : $value); } if($type) { $columns[$column] = $this->db->real_escape_string($value); } else { $columns[] = sprintf("`%s` = '%s'", $column, $this->db->real_escape_string($value)); } } $column_list = implode(',', $columns); if($type) { $this->db->query(sprintf("INSERT INTO `tracks` (`uid`, `title`, `description`, `name`, `tag`, `art`, `buy`, `record`, `release`, `license`, `size`, `as3_track`, `download`, `public`, `time`) VALUES ('%s', '%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['as3_track'], $columns['download'], $columns['public'])); $x++; } else { $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']))); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); if($affected) { if(!$type) { return notificationBox('success', $LNG["track_updated"]); } } return notificationBox('info', $LNG["nothing_changed"]); } } } if($x > 0) { $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)); while($row = $query->fetch_assoc()) { $err .= notificationBox('success', sprintf($LNG['track_uploaded'], permalink($this->url.'/index.php?a=track&id='.$row['id'].'&name='.cleanUrl($row['title'])), $row['title'])); } } return array($err, 1); } function getTrackInfo($id, $type) { // Type 0: Return track title link and author permission // Type 1: Return track info $query = $this->db->query(sprintf("SELECT * FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id))); $result = $query->fetch_assoc(); if($type) { return $result; } else { return array(''.$result['title'].'', (($this->id == $result['uid']) ? 1 : 0)); } } function getTrack($id) { // Obey the message privacy to the profile privacy and then to the message privacy $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))); $result = $query->fetch_assoc(); $relationship = $this->verifyRelationship($this->id, $result['idu'], 0); // Store the current track's name for recommended tracks $this->track_tag = $result['tag']; // Check if the track exist if($query->num_rows > 0) { // If the track is public // Check privacy switch($result['private']) { case 0: break; case 1: // Check if the username is not same with the profile if($this->id !== $result['idu']) { $x = 1; } break; case 2: // Check relationship if(!$relationship) { $x = 2; } break; } // If the track is private if($result['public'] == 0) { if($this->id !== $result['idu']) { $x = 1; } } // Override any settings and grant admin permissions if($this->is_admin) { $x = 0; } } // Get the track for track page $query = sprintf("SELECT * FROM `tracks`, `users` WHERE `tracks`.`id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id)); if($x) { if($x == 2) { return $this->showError('track_hidden_2'); } else { return $this->showError('track_hidden_1'); } } elseif($result['public'] == 2) { return $this->showError('track_suspended_1'); } else { return $this->getTracks($query, 'trackPage', null); } } function getComments($id, $cid, $start, $type = null) { // Type 0: Get Comments // Type 1: Get last comment global $LNG; // The query to select the subscribed users // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND comments.id < \''.$this->db->real_escape_string($cid).'\''; } if($type) { $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)); } else { $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)); } // check if the query was executed if($result = $this->db->query($query)) { // Set the result into an array $rows = array(); while($row = $result->fetch_assoc()) { $rows[] = $row; } // Define the $comments variable; $comments = ''; // If there are more results available than the limit, then show the Load More Comments if(array_key_exists($this->c_per_page, $rows)) { $loadmore = 1; if($type) { $loadmore = 0; } // Unset the last array element because it's not needed, it's used only to predict if the Load More Comments should be displayed unset($rows[$this->c_per_page]); } foreach($rows as $comment) { // Define the time selected in the Admin Panel $time = $comment['time']; $b = ''; if($this->time == '0') { $time = date("c", strtotime($comment['time'])); } elseif($this->time == '2') { $time = $this->ago(strtotime($comment['time'])); } elseif($this->time == '3') { $date = strtotime($comment['time']); $time = date('Y-m-d', $date); $b = '-standard'; } if($this->username == $comment['username']) { // If it's current username is the same with the current author $delete = '
'; } elseif(empty($this->username)) { // If the user is not registered $delete = ''; } else { // If the current username is not the same as the author $delete = '
'; } // Variable which contains the result $comments .= '
'.$delete.'
'.realName($comment['username'], $comment['first_name'], $comment['last_name']).'
(
'.$time.'
)
'.$this->parseMessage($comment['message']).'
'; $message_id = $comment['tid']; $load_id = $comment['id']; } if($loadmore) { $load = '
'.$LNG['load_more'].'
'; } // Close the query $result->close(); // Return the comments variable return $comments.$load; } else { return false; } } function parseMessage($message) { global $LNG, $CONF; // Parse links $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); // Parse @mentions and #hashtags $parsedMessage = preg_replace(array('/(^|[^a-z0-9_\/])@([a-z0-9_]+)/i', '/(^|[^a-z0-9_\/])#(\w+)/u'), array('$1@$2', '$1#$2'), $parseUrl); return $parsedMessage; } function delete($id, $type) { // Type 0: Delete Comment // Type 1: Delete Track // Type 2: Delete Chat Message // Prepare the statement if($type == 0) { $stmt = $this->db->prepare("DELETE FROM `comments` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `uid` = '{$this->db->real_escape_string($this->id)}'"); // Set $x variable to 1 if the delete query is for `comments` $x = 0; } elseif($type == 1) { // Get the current type (for images and tracks deletion) $query = $this->db->query(sprintf("SELECT `art`, `name`, `as3_track` FROM `tracks` WHERE `id` = '%s' AND `uid` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($this->id))); $track = $query->fetch_assoc(); $stmt = $this->db->prepare("DELETE FROM `tracks` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `uid` = '{$this->db->real_escape_string($this->id)}'"); // Set $x variable to 1 if the delete query is for `tracks` $x = 1; } elseif($type == 2) { $stmt = $this->db->prepare("DELETE FROM `chat` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `from` = '{$this->db->real_escape_string($this->id)}'"); $x = 2; } elseif($type == 3) { $stmt = $this->db->prepare("DELETE FROM `playlists` WHERE `id` = '{$this->db->real_escape_string($id)}' AND `by` = '{$this->db->real_escape_string($this->id)}'"); $x = 3; } // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the tracks/comments table was affected if($affected) { // Deletes the Comments/Likes/Reports/Notifications/Playlists and Images if the Track was deleted if($x == 1) { $this->db->query("DELETE FROM `comments` WHERE `tid` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `likes` WHERE `track` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `reports` WHERE `track` = '{$this->db->real_escape_string($id)}' AND `parent` = '0'"); $this->db->query("DELETE FROM `notifications` WHERE `parent` = '{$this->db->real_escape_string($id)}'"); $this->db->query("DELETE FROM `playlistentries` WHERE `track` = '{$this->db->real_escape_string($id)}'"); deleteMedia($track['art'], array($track['name'] => $track['as3_track'])); } elseif($x == 0) { $this->db->query("DELETE FROM `reports` WHERE `post` = '{$this->db->real_escape_string($id)}' AND `parent` != '0'"); $this->db->query("DELETE FROM `notifications` WHERE `child` = '{$this->db->real_escape_string($id)}' AND `type` = '1'"); } elseif($x == 3) { $this->db->query("DELETE FROM `playlistentries` WHERE `playlist` = '{$this->db->real_escape_string($id)}'"); } } return ($affected) ? 1 : 0; } function report($id, $type) { // Type 0: Comments // Type 1: Tracks global $LNG; // Check if the Track exists if($type == 1) { $result = $this->db->query(sprintf("SELECT `id` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id))); } else { $result = $this->db->query(sprintf("SELECT `id`, `tid`, `message` FROM `comments` WHERE `id` = '%s'", $this->db->real_escape_string($id))); $parent = $result->fetch_array(MYSQLI_ASSOC); } // If the Track/Comment exists if($result->num_rows) { $result->close(); // Get the report status, 0 = already exists * 1 = is safe if($type == 1) { $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)); } else { $query = sprintf("SELECT `state` FROM `reports` WHERE `track` = '%s' AND `type` = '%s'", $this->db->real_escape_string($id), $this->db->real_escape_string($type)); } $result = $this->db->query($query); $state = $result->fetch_assoc(); // If the report already exists if($result->num_rows) { // If the comment state is 0, then already exists if($state['state'] == 0) { return (($type == 1) ? notificationBox('info', $LNG["{$type}_already_reported"]) : $LNG["{$type}_already_reported"]); } elseif($state['state'] == 1) { if($type == 1) { if($state['by'] == $this->id) { return notificationBox('info', $LNG["{$type}_is_safe"]); } } else { return $LNG["{$type}_is_safe"]; } } else { return (($type == 1) ? notificationBox('error', $LNG["{$type}_is_deleted"]) : $LNG["{$type}_is_deleted"]); } } else { if($type == 1) { $validate = $this->checkReportForm(); if($validate) { return notificationBox('error', sprintf($LNG["{$validate[0]}"], $validate[1])); } $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))); } else { $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))); } // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If the comment was added, return 1 if($affected) { return (($type == 1) ? notificationBox('success', $LNG["{$type}_report_added"]) : $LNG["{$type}_report_added"]); } else { return (($type == 1) ? notificationBox('error', $LNG["{$type}_report_error"]) : $LNG["{$type}_report_error"]); } } } else { return $LNG["{$type}_not_exists"]; } } function checkReportForm() { if(strlen($_POST['description']) > 3000) { return array('rep_resc_error', 3000); } if(!isset($_POST['report1']) || !isset($_POST['report2']) || !isset($_POST['report3']) || !isset($_POST['description']) || !isset($_POST['signature'])) { return array('all_fields'); } } function addComment($id, $comment) { // Check if the POST is public $query = sprintf("SELECT * FROM `tracks`,`users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($id)); $result = $this->db->query($query); $row = $result->fetch_assoc(); // If the POST is public if($row['public'] == 1) { // Add the insert message $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))}')"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // Select the last inserted message $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'])); $lastComment = $getId->fetch_assoc(); // Do the INSERT notification $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'])); if($affected) { // If email on likes is enabled in admin settings if($this->email_comment) { // If user has emails on commentss enabled and he's not commenting on his own track if($row['email_comment'] && ($this->id !== $row['idu'])) { global $LNG; // Send e-mail sendMail($row['email'], sprintf($LNG['ttl_comment_email'], $this->username), sprintf($LNG['comment_email'], realName($row['username'], $row['first_name'], $row['last_name']), permalink($this->url.'/index.php?a=profile&u='.$this->username), $this->username, permalink($this->url.'/index.php?a=track&id='.$id.'&name='.cleanUrl($row['title'])), $this->title, permalink($this->url.'/index.php?a=settings&b=notifications')), $this->email); } } } // If the comment was added, return 1 return ($affected) ? 1 : 0; } else { return 0; } } function changePrivacy($id, $value, $type = null) { // Type 0: Tracks privacy // Type 1: Playlist privacy if($type == 1) { $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)}'"); } else { $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)}'"); } // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); return ($affected) ? 1 : 0; } function ago($i) { global $LNG; $m = time() - $i; $o = $LNG['just_now']; $t = array($LNG['year_s'] => 31556926, $LNG['month_s'] => 2629744, $LNG['week_s'] => 604800, $LNG['day_s'] => 86400, $LNG['hour_s'] => 3600, $LNG['minute_s'] =>60, $LNG['second_s'] => 1); foreach($t as $u => $s) { if($s <= $m) { $v = floor($m/$s); $o = "$v $u".' '.$LNG['ago']; break; } } return $o; } function sidebarFilters($bold) { global $LNG, $CONF; // Start the output $row = array('people', 'tracks', 'playlists'); $link = ''; return $link; } function sidebarNotifications($bold) { global $LNG, $CONF; // Start the output $row = array('likes', 'comments', 'friendships', 'chats'); $link = ''; return $link; } function sidebarCategories($bold) { global $LNG; $query = $this->db->query("SELECT * FROM `categories` ORDER BY `name` ASC"); while($row = $query->fetch_assoc()) { $rows[] = $row; } $link = ''; return $link; } /* HASHTAGS MOD BY JUDE */ function sidebarHashtags($bold) { global $LNG; $query = $this->db->query("SELECT * FROM `tracks` ORDER BY `tag` ASC"); // Store the hashtags into a string while($row = $query->fetch_assoc()) { $hashtags .= $row['tag']; } if($hashtags) { // 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) $hashtags = explode(',', $hashtags); $count = array_count_values(array_map('strtolower', array_filter($hashtags))); // Sort them by trend arsort($count); // Return only 10 hashtags $count = array_slice($count, 0, 100); $output = ''; } return $output; } /* HASHTAGS MOD BY JUDE */ function sidebarDates($bold, $values = null) { global $LNG; $row = $this->listDates($values); $profile = ($this->profile) ? '&u='.$this->profile : ''; // If the result is not empty if($row) { // Start the output $link = ''; return $link; } } function listDates($values = null) { if($values == false) { return false; } elseif($values == 'profile') { $profile = ($this->profile == $this->username) ? '' : 'AND public = 1'; $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); } elseif($values) { $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)); } $result = $this->db->query($query); while($row = $result->fetch_assoc()) { $rows[] = $row; } // If the select was made if($result = $this->db->query($query)) { // Define the array; $store = array(); foreach($rows as $date) { // Add the elemnts to the array $store [] = $date['dates']; } return $store; } else { return false; } } function sidebarReport($id) { global $LNG; return ''; } function getTrackList($id) { $query = $this->db->query(sprintf("SELECT `id` FROM `tracks` WHERE `uid` = '%s'", $this->db->real_escape_string($id))); while($row = $query->fetch_assoc()) { $rows[] = $row['id']; } return $rows; } function proAccountHistory($id = null, $title = null, $type) { // Title: Decide if the title is included or not // Type 0: Return all transactions // Type 1: Return inactive transactions global $LNG; if($type) { $x = ' AND `valid` < \''.date('Y-m-d H:i:s').'\''; } else { $x = ''; } $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)); while($row = $query->fetch_assoc()) { $rows[] = $row; } if(!empty($rows)) { $result = '
'; if($title) { $result .= '
'.$LNG['transactions_history'].'
'.$LNG['from'].'
'.$LNG['to'].'
'.$LNG['type'].'
'.$LNG['status'].'
'; } foreach($rows as $row) { $fromArr = explode('-', $row['time']); $date = $fromArr[0].'-'.$fromArr[1].'-'.substr($fromArr[2], 0, 2); $toArr = explode('-', $row['valid']); $valid = $toArr[0].'-'.$toArr[1].'-'.substr($toArr[2], 0, 2); $status = paymentStatus($row['status']); $result .= '
'.$date.'
'.$valid.'
'.$row['amount'].' '.$row['currency'].'
'.$status.'
'; } $result .= '
'; } return $result; } function getProStatus($id = null, $type = null) { // Type 0: Get the Pro Status of a user // Type 1: Decide whether the pro accounts are enabled from the Admin Panel, and if so, check the status // Type 2: Returns all the details of last transaction $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))); $result = $query->fetch_assoc(); if($type == 1) { if($this->paypalapp) { if($result['status'] == 1 && strtotime($result['valid']) >= time()) { return 1; } else { return 0; } } else { // Always return all features if the pro accounts are disabled return 1; } } elseif($type == 2) { return $result; } else { if($result['status'] == 1 && strtotime($result['valid']) >= time()) { return 1; } else { return 0; } } } function goProMessage($message = null, $type = null, $artist = null) { // Message: Certain number to match a string from language file // Type 0: For Stats page // Type 1: For Account Plan page // Type 2: For sidebar widgets // Artist: If set, it must have at least one track uploaded global $LNG; if($type == 1) { if($this->paypalapp && !$this->getProStatus($this->id)) { // Generate a random number for a dynamic widget if the $message is not set if(!$message) { $message = rand(1, 2); } if($artist) { // If there's no track uploaded by the user and if(!$this->trackList) { return false; } } return ''; } } else { return '
'.$LNG["go_pro_{$message}"].'
'.$LNG['go_pro'].'
'; } } function sidebarDescription($id, $type = null, $raw = null) { global $LNG; if($type == 1) { $query = $this->db->query(sprintf("SELECT `description` FROM `playlists` WHERE `id` = '%s'", $this->db->real_escape_string($id))); } else { $query = $this->db->query(sprintf("SELECT `description`, `record`, `release`, `license` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id))); } $result = $query->fetch_row(); // Return raw text output if($raw) { return nl2br($result[0]); } if($type !== 1) { // Explode the born value [[0]=>Y,[1]=>M,[2]=>D]; $date = explode('-', $result[2]); // Make it into integer instead of a string (removes the 0, e.g: 03=>3, prevents breaking the language) $month = intval($date[1]); $extra = (($result[2] !== '0000-00-00') ? '' : ''); $extra .= (($result[1]) ? '' : ''); if($result[3]) { $license = str_split($result[3]); if($license[1] == 1) { $nc = '
'; } if($license[2] == 1) { $nd = '
'; } elseif($license[2] == 2) { $sa = '
'; } $extra .= (($result[3]) ? '' : ''); } } $description = ($result[0] ? '' : ''); if(!empty($description) || !empty($extra)) { $output = ''; } return $output; } function sidebarKeywords($id, $type = null) { // Type 0: Return keywords for Track Page // Type 1: Return keywords for Playlist Page global $LNG; if($type == 1) { $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)); } else { $query = $this->db->query(sprintf("SELECT `tag` FROM `tracks` WHERE `id` = '%s'", $this->db->real_escape_string($id))); } // Store the hashtags into a string while($row = $query->fetch_assoc()) { $hashtags .= $row['tag']; } if($hashtags) { $hashtags = explode(',', $hashtags); if($type == 1) { // 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) $count = array_count_values(array_map('strtolower', array_filter($hashtags))); // Sort them by must popular arsort($count); } else { // Lowercase all the array elements to prevent case-sensitive tags showing up, e.g: Test, test, TEST $count = array_map('strtolower', array_filter($hashtags)); // Reverse the keys with values $count = array_flip($count); } // Return only 15 hashtags $count = array_slice($count, 0, 15, true); $output = ''; } return $output; } function sidebarRecommended($id) { global $LNG; $current_tags = array_filter(explode(',', $this->track_tag)); $i = 1; foreach($current_tags as $tag) { if(count($current_tags) > 1) { if($i == 1) { $like .= sprintf("(`tag` LIKE '%s'", '%'.$this->db->real_escape_string($tag).'%'); } else { $like .= sprintf(" OR `tag` LIKE '%s'", '%'.$this->db->real_escape_string($tag).'%'); } if($i == (count($current_tags))) { $like .= ")"; } } else { $like = sprintf(" `tag` LIKE '%s'", '%'.$this->db->real_escape_string($tag).'%'); } $i++; } // Get track suggestions based on the current track's categories and exclude the current track from the results $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))); // Store the array results while($row = $query->fetch_assoc()) { $rows[] = $row; } shuffle($rows); // If suggestions are available if(!empty($rows)) { $i = 0; $output = ''; return $output; } else { return false; } } function sidebarStatistics($id = null, $type = null, $extra = null) { // Type 0: Return statistics for your own tracks that have been played by other users // Type 1: Return statistics for track page global $LNG; if($type == 1) { $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))); } elseif($type == 2) { $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))); } else { if(!$this->trackList) { return; } $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)); } $result = $query->fetch_assoc(); $output = ''; return $output; } function onlineUsers($type = null, $value = null) { global $LNG, $CONF; // Type 2: Show the Friends Results for the live search for Chat/Messages // : If value is set, find friends from Subscriptions // Type 1: Display the friends for the Chat/Messages page // : If value is set, find exact username // Type 0: Display the friends for stream page // Get the subscritions $subscriptions = $this->getSubscriptionsList(); $currentTime = time(); if(!empty($subscriptions)) { if($type == 1) { // Display current friends $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` IN (%s) ORDER BY `online` DESC", $this->db->real_escape_string($subscriptions))); } elseif($type == 2) { if($value) { // Search in friends $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))); } else { // Display current friends $query = $this->db->query(sprintf("SELECT * FROM `users` WHERE `idu` IN (%s) ORDER BY `online` DESC", $this->db->real_escape_string($subscriptions))); } } else { // Display the online friends (used in Feed/Subscriptions) $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)); } // Store the array results while($row = $query->fetch_assoc()) { $rows[] = $row; } } // usort($rows, 'sortOnlineUsers'); if($type == 1) { // Output the users $output = ''; } elseif($type == 2) { $output = ''; if(!empty($rows)) { $i = 0; foreach($rows as $row) { // Switch the images, depending on the online state if(($currentTime - $row['online']) > $this->online_time) { $icon = 'offline'; } else { $icon = 'online'; } $output .= ''; $i++; } } else { $output .= ''; } } else { // If the query has content if(!empty($rows)) { // Output the online users $output = ''; } else { return false; } } return $output; } function getChat($uid, $user) { global $LNG, $CONF; $uid = saniscape($uid); $output = '
'.((empty($user['username'])) ? $this->chatError($LNG['start_conversation']) : $this->getChatMessages($uid)).'
'; return $output; } function checkChat($uid) { $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))); if($query->num_rows) { return $this->getChatMessages($uid, null, null, 2); } return false; } function getChatMessages($uid, $cid = null, $start = null, $type = null) { // uid = user id (from which user the message was sent) // cid = where the pagination will start // start = on/off // type 1: swtich the query to get the last message global $LNG; // The query to select the subscribed users // If the $start value is 0, empty the query; if($start == 0) { $start = ''; } else { // Else, build up the query $start = 'AND `chat`.`id` < \''.$this->db->real_escape_string($cid).'\''; } if($type == 1) { $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)); } elseif($type == 2) { $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)); } else { $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)); } // check if the query was executed if($result = $this->db->query($query)) { if($type !== 1) { // Set the read status to 1 whenever you load messages [IGNORE TYPE: 1] $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))); } // Set the result into an array while($row = $result->fetch_assoc()) { $rows[] = $row; } $rows = array_reverse($rows); // Define the $output variable; $output = ''; // If there are more results available than the limit, then show the Load More Chat Messages if(array_key_exists($this->m_per_page, $rows)) { $loadmore = 1; // 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 unset($rows[0]); } foreach($rows as $row) { // Define the time selected in the Admin Panel $time = $row['time']; $b = ''; if($this->time == '0') { $time = date("c", strtotime($row['time'])); } elseif($this->time == '2') { $time = $this->ago(strtotime($row['time'])); } elseif($this->time == '3') { $date = strtotime($row['time']); $time = date('Y-m-d', $date); $b = '-standard'; } if($this->username == $row['username']) { // If it's current username is the same with the current author $delete = '
'; $class = 'user-one'; } else { $delete = ''; $class = 'user-two'; } // Variable which contains the result $output .= '
'.$delete.'
'.realName($row['username'], $row['first_name'], $row['last_name']).': '.$this->parseMessage($row['message']).'
'.$time.'
'; $start = $row['id']; } if($loadmore) { $load = '
'.$LNG['view_more_conversations'].'
'; } // Close the query $result->close(); // Return the conversations return $load.$output; } else { return false; } } function postChat($message, $uid) { global $LNG; $user = $this->profileData(null, $uid); if(strlen($message) > $this->chat_length) { return $this->chatError(sprintf($LNG['chat_too_long'], $this->chat_length)); } elseif($uid == $this->id) { return $this->chatError(sprintf($LNG['chat_self'])); } elseif(!$user['username']) { return $this->chatError(sprintf($LNG['chat_no_user'])); } $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))); if($query->num_rows) { return $this->chatError(sprintf($LNG['blocked_user'], realName($user['username'], $user['first_name'], $user['last_name']))); } else { $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))); if($query->num_rows) { return $this->chatError(sprintf($LNG['blocked_by'], realName($user['username'], $user['first_name'], $user['last_name']))); } } // Prepare the insertion $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)); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); if($affected) { return $this->getChatMessages($uid, null, null, 1); } } function updateStatus($offline = null) { if(!$offline) { $this->db->query(sprintf("UPDATE `users` SET `online` = '%s' WHERE `idu` = '%s'", time(), $this->db->real_escape_string($this->id))); } } function chatError($value) { return '
'.$value.'
'; } function playlistEntry($track, $playlist, $type = null) { // Type 0: Return whether the track exists in playlist or not // Type 1: Return the playlist entries // Type 2: Returns the latest added playlist // Type 3: Add/Remove track from playlist if($type) { if($type == 1) { $query = $this->db->query(sprintf("SELECT `id`,`name` FROM `playlists` WHERE `by` = '%s' ORDER BY `id` DESC", $this->id)); } elseif($type == 2) { $query = $this->db->query(sprintf("SELECT `id`,`name` FROM `playlists` WHERE `by` = '%s' ORDER BY `id` DESC LIMIT 0, 1", $this->id)); } elseif($type == 3) { // Verify if track exists $query = $this->db->query(sprintf("SELECT * FROM `tracks`, `users` WHERE `id` = '%s' AND `tracks`.`uid` = `users`.`idu`", $this->db->real_escape_string($track))); if($query->num_rows > 0) { $result = $query->fetch_assoc(); // Verify relationship // Check privacy switch($result['private']) { case 0: break; case 1: // Check if the username is not the same with the track owner if($this->id !== $result['idu']) { return false; } case 2: $relationship = $this->verifyRelationship($this->id, $result['idu'], 0); // Check relationship if(!$relationship) { return false; } break; } // Verify playlist ownership $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))); if($checkPlaylist->num_rows > 0) { // Check if the track exists in playlist $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))); // If the track exist, delete it if($checkTrack->num_rows > 0) { $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))); } // Insert the track into playlist else { $this->db->query(sprintf("INSERT INTO `playlistentries` (`playlist`, `track`) VALUES ('%s', '%s')", $this->db->real_escape_string($playlist), $this->db->real_escape_string($track))); } // Return the playlist entry $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))); } else { return; } } } // Store the array results while($row = $query->fetch_assoc()) { $rows[] = $row; } foreach($rows as $row) { $output .= '
'.$row['name'].'
'; } return $output; } else { // Select the playlists $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))); // Store the array results if($query->num_rows > 0) { return $query->num_rows; } } } function managePlaylist($id, $type, $data = null) { global $LNG; // Type 0: Return the current playlist info // Type 1: Update the current playlist // Type 2: Add a new playlist if($type == 2) { $data = trim($data); // Prepare the statement if(strlen($data) == 0) { return; } // Prepare the insertion $stmt = $this->db->prepare(sprintf("INSERT INTO `playlists` (`by`, `name`, `description`, `public`, `time`) VALUES ('%s', '%s', '', 1, CURRENT_TIMESTAMP)", $this->db->real_escape_string($this->id), htmlspecialchars(trim(nl2clean($this->db->real_escape_string($data)))))); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); if($affected) { // Return the latest added playlist entry return $this->playlistEntry($id, 0, 2); } } elseif($type == 1) { // Strip the white spaces at the beginning/end of the name $data['name'] = trim($data['name']); // Prepare the statement if(strlen($data['name']) == 0) { return notificationBox('error', sprintf($LNG['playlist_name_empty'])); } if(strlen($data['description']) > 160) { return notificationBox('error', sprintf($LNG['playlist_description'], 160)); } $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}'"); // Execute the statement $stmt->execute(); // Save the affected rows $affected = $stmt->affected_rows; // Close the statement $stmt->close(); // If there was anything affected return 1 if($affected) { return notificationBox('success', $LNG['changes_saved']); } else { return notificationBox('info', $LNG['nothing_changed']); } } else { $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)); $result = $query->fetch_array(); return $result; } } function sidebarButton($id = null, $type = null) { global $LNG; // Type 0: Upload button for Explore/Stream // Type 1: Edit button for Track Page // Type 2: Edit button for Playlist Page // Type 3: Last track uploaded if($type == 1) { $query = $this->db->query(sprintf("SELECT * FROM `tracks` WHERE `id` = '%s' AND `uid` = '%s'", $this->db->real_escape_string($_GET['id']), $this->id)); if($query->num_rows) { return ''; } } elseif($type == 2) { $query = $this->db->query(sprintf("SELECT * FROM `playlists` WHERE `id` = '%s' AND `by` = '%s'", $this->db->real_escape_string($_GET['id']), $this->id)); if($query->num_rows) { return ''; } } elseif($type == 3) { return ''; } else { return ($id) ? '' : ''; } } function sidebarFriendsActivity($limit, $type = null) { global $LNG, $CONF; $subscriptions = $this->getSubscriptionsList(); // If there is no subscriptions, return false if(empty($subscriptions)) { return false; } // Define the arrays that holds the values (prevents the array_merge to fail, when one or more options are disabled) $likes = array(); $comments = array(); $tracks = array(); $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)); while($row = $checkLikes->fetch_assoc()) { $likes[] = $row; } $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)); while($row = $checkComments->fetch_assoc()) { $comments[] = $row; } $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)); while($row = $checkMessages->fetch_assoc()) { $tracks[] = $row; } // If there are no latest notifications if(empty($likes) && empty($comments) && empty($tracks)) { return false; } // Add the types into the recursive array results $x = 0; foreach($likes as $like) { $likes[$x]['event'] = 'like'; $x++; } $y = 0; foreach($comments as $comment) { $comments[$y]['event'] = 'comment'; $y++; } $z = 0; foreach($tracks as $track) { $tracks[$z]['event'] = 'message'; $z++; } $array = array_merge($likes, $comments, $tracks); // Sort the array usort($array, 'sortDateAsc'); $activity .= '