<?php\n\ndefined('BASEPATH') or exit('No direct script access allowed');\n\nclass User extends MY_Controller\n{\n\n    public function __construct()\n    {\n        parent::__construct();\n\n        $no_logged_methods = array('login', 'membership', 'register', 'reset_password', 'confirm_account', 'ban_reason', 'mail_test', 'virwox_notification', 'accubcendqffdfdv');\n\n        if (empty($this->session->logged) && !in_array($this->router->fetch_method(), $no_logged_methods)) {\n            $this->session->set_flashdata('show_login_form', true);\n            redirect('engine/error?http_code=403');\n        }\n\n        if ($this->router->fetch_method() == '<b>openssl_e</b>' || $this->router->fetch_method() == 'opensll_d') {\n            $this->config->load('config');\n        }\n\n    }\n\n    public function account()\n    {\n        $this->load->helper('countries');\n        $data = array(\n            'countries' => get_countries(),\n            'user' => $this->db->where('id', $this->session->id)->get('users')->row(),\n            'torrents_count' => $this->db->select('id')->where('uploader', $this->session->id)->get('torrents')->num_rows(),\n            'comments_count' => $this->db->select('id')->where('publisher', $this->session->id)->get('comments')->num_rows(),\n        );\n        $this->load->view('user/account', $data);\n    }\n\n    public function turbo()\n    {\n        // Vérifier si l'utilisateur est soumis aux restrictions (même conditions que le timer)\n        $this->config->load('yggconfig');\n        $min_user_id = $this->config->item('download_timer_min_user_id');\n        $exempt_ranks = $this->config->item('download_timer_exempt_ranks') ?: [];\n        \n        $is_restricted = ($this->session->id >= $min_user_id && !in_array($this->session->rank, $exempt_ranks));\n        \n        // Si l'utilisateur n'est pas restreint, rediriger vers la page compte\n        if (!$is_restricted) {\n            redirect('user/account');\n        }\n        \n        // Récupérer premium_until depuis la session (Turbo = téléchargements sans attente ni limites)\n        $premium_until = isset($this->session->premium_until) ? (int)$this->session->premium_until : 0;\n        \n        if ($premium_until == -1) {\n            // Turbo à vie\n            $is_turbo = true;\n            $turbo_end = null;\n            $days_remaining = -1;\n            $is_lifetime = true;\n        } elseif ($premium_until > 0 && $premium_until > now()) {\n            // Turbo actif avec date de fin\n            $is_turbo = true;\n            $turbo_end = $premium_until;\n            $days_remaining = floor(($premium_until - now()) / 86400);\n            $is_lifetime = false;\n        } else {\n            // Pas de Turbo ou expiré\n            $is_turbo = false;\n            $turbo_end = null;\n            $days_remaining = 0;\n            $is_lifetime = false;\n        }\n        \n        $data = array(\n            'is_turbo' => $is_turbo,\n            'is_lifetime' => $is_lifetime,\n            'turbo_end' => $turbo_end,\n            'days_remaining' => $days_remaining,\n        );\n        \n        $this->load->view('user/turbo', $data);\n    }\n\n    public function allow_porn()\n    {\n        $this->form_validation->set_rules('allow_porn', 'allow_porn option', 'trim|xss_clean');\n        if ($this->form_validation->run()) {\n            if ($this->input->post('allow_porn') == 1) {\n                $porn_val = 1;\n                $this->session->set_flashdata('options_msg', '<strong style="color:green;">Section XXX activée !</strong>');\n            } else {\n                $porn_val = 0;\n                $this->session->set_flashdata('options_msg', '<strong style="color:red;">Section XXX désactivée !</strong>');\n            }\n            $this->db->set('allow_porn', $porn_val)->where('id', $this->session->id)->update('users');\n            $this->session->allow_porn = $porn_val;\n            $this->session->set_flashdata('settings_update', true);\n            redirect($this->agent->referrer());\n        }\n\n    }\n\n    public function notifications()\n    {\n        $this->load->library('notify', array());\n        $data['notifications'] = $this->db->where('guid', $this->session->id)->order_by('id', 'desc')->get('notifications')->result();\n        $this->db->query('UPDATE users SET notified = notifications WHERE id = ' . $this->session->id . ' ');\n        $this->load->view('user/notifications', $data);\n    }\n\n    public function blacklist()\n    {\n        // $this->output->enable_profiler();\n        $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;\n        $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);\n        $ignoredList = array_flip($ignoredList);\n        //  print_r($ignoredList);\n        $ids = join('\\',\\'', $ignoredList);\n\n        $sql = "SELECT id, avatar, rank, uploaded, downloaded, last_activity_date, nickname, country FROM users WHERE id IN ('$ids') ORDER BY FIELD (users.id,'$ids')";\n\n        $data['users'] = $this->db->query($sql)->result();\n\n        $this->load->view('user/ignored', $data);\n    }\n\n    public function ignore()\n    {\n        $action = $this->input->get('action');\n        $user_id = $this->input->post('user_id');\n\n        if ($_SERVER['REQUEST_METHOD'] == 'POST') {\n            // S'il s'agit d'un ajout\n            if ($action == 'add') {\n                $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;\n                $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);\n\n                if (array_key_exists($user_id, $ignoredList)) {\n                    $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'false')));\n                } else {\n                    $isUserExists = $this->db->select('id')->where('id', $user_id)->get('users')->num_rows() > 0;\n\n                    if (!$isUserExists) {\n                        $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'false')));\n                    } else {\n                        // On ajoute l'utilisateur à la liste avec la date d'ajout\n                        if (!is_array($ignoredList)) {\n                            $ignoredList = array();\n                            $ignoredList[$user_id] = now();\n                        } else {\n                            $ignoredList[$user_id] = now();\n                        }\n\n                        $ignoredList = json_encode($ignoredList);\n                        $this->db->where('id', $this->session->id)->set('ignored', $ignoredList)->update('users');\n\n                        $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'true')));\n                    }\n                }\n            }\n\n            if ($action == 'del') {\n                // Aussi court que ça...\n                $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;\n                $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);\n\n                if (array_key_exists($user_id, $ignoredList)) {\n                    unset($ignoredList[$user_id]);\n                    $ignoredList = json_encode($ignoredList);\n                    $this->db->where('id', $this->session->id)->set('ignored', $ignoredList)->update('users');\n\n                    $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'true')));\n                } else {\n\n                    $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'false')));\n\n                }\n            }\n        }\n    }\n\n    public function settings()\n    {\n        if ($_SERVER['REQUEST_METHOD'] == 'POST') {\n            $this->form_validation->set_rules('sender_age', '<strong>ancienneté de l\\'expéditeur</strong>', 'required|in_list[24hours,4days,1week,2weeks,1month,3months,nocondition]');\n            $this->form_validation->set_rules('tracker_id', '<strong>adresse du tracker</strong>', 'required|in_list[1,2]');\n\n            if ($this->form_validation->run()) {\n                // Init parameters to False\n                $settings['pm']['enable'] = false;\n                $settings['enable_at_content'] = false;\n                $settings['anonymous_upload'] = false;\n                $settings['disable_history'] = false;\n                $settings['restrict_comments'] = false;\n\n                $tracker_id = $this->input->post('tracker_id');\n\n                if (isset($_POST['restrict_comments'])) {\n                    $settings['restrict_comments'] = true;\n                }\n\n                if (isset($_POST['anonymous_upload'])) {\n                    $settings['anonymous_upload'] = true;\n                }\n\n                if (isset($_POST['disable_history'])) {\n                    $settings['disable_history'] = true;\n                    $this->db->where('id', $this->session->id)->set('downloads', json_encode([]))->update('users');\n                }\n\n                if (isset($_POST['enable_pm'])) {\n                    $settings['pm']['enable'] = true;\n                }\n\n                $settings['pm']['condition_sender_age'] = $this->input->post('sender_age', true);\n\n                if (isset($_POST['enable_at_content'])) {\n                    $settings['enable_at_content'] = true;\n                }\n\n                $settings = json_encode($settings);\n\n                $this->db->where('id', $this->session->id)->set('settings', $settings)->set('tracker_id', $tracker_id)->update('users');\n\n                $this->output->set_content_type('application/json')->set_output(json_encode($settings));\n            }\n\n            sizeof($this->form_validation->error_array()) > 0 ? $this->show_error(array_values($this->form_validation->error_array())[0]) : '';\n\n        } else {\n\n            $sender_age = $this->session->settings['pm']['condition_sender_age'];\n\n            switch ($sender_age) {\n                case '24hours':\n                    $alias = '24 heures';\n                    break;\n                case '4days':\n                    $alias = '4 jours';\n                    break;\n                case '1week':\n                    $alias = '1 semaine';\n                    break;\n                case '2weeks':\n                    $alias = '2 semaines';\n                    break;\n                case '1month':\n                    $alias = '1 mois';\n                    break;\n                case '3months':\n                    $alias = '3 mois';\n                    break;\n            }\n\n            $data['pretty_alias'] = $alias;\n\n            if ($this->session->tracker_id == 1) {\n                $tracker_host = $this->config->item('secondary_tracker_host');\n            } else {\n                $tracker_host = $this->config->item('first_tracker_host');\n            }\n            $data['tracker_announce'] = 'http://' . $tracker_host . ':8080/' . $this->session->torrent_pass . '/announce';\n            $this->load->view('user/settings', $data);\n        }\n    }\n\n    public function ajax_notifications()\n    {\n        if ($this->session->notified < $this->session->notifications) {\n            $notifs = $this->db->select('id')->where('guid', $this->session->id)->where('state', 0)->from('notifications')->order_by('id', 'asc')->limit(5)->get()->result_array();\n            $notifs_id = array_map(function ($i) {\n                return $i['id'];\n            }, $notifs);\n            $this->load->library('notify', array());\n\n            $n = array();\n            foreach ($notifs as $notif) {\n                $n[] = $this->notify->getNotificationTPL($notif['id']);\n            }\n            $this->db->where_in('id', $notifs_id)->set('state', 1)->update('notifications');\n            $this->db->where('id', $this->session->id)->set('notified', 'notified+' . count($notifs_id), false)->update('users');\n\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('new_notifications' => count($notifs_id), 'list' => json_encode($n))));\n        } else {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('new_notifications' => 0)));\n        }\n    }\n\n    public function support()\n    {\n        $show = $this->input->get('show', true);\n        if ($show == 'donation') {\n            $data['type'] = 'donation';\n            $data['donations'] = $this->db->where('guid', $this->session->id)->order_by('id', 'desc')->get('bills')->result();\n            if ($_SERVER['REQUEST_METHOD'] == 'POST') {\n                $donation_id = $this->input->post('donation_id', true);\n                $donations_id = array();\n\n                foreach ($data['donations'] as $donation) {\n                    $donations_id[] = $donation->id;\n                }\n                //print_r($donations_id);\n                if (!in_array($donation_id, $donations_id)) {\n                    $error = 'L\\'id de transaction est invalide';\n                }\n                $donation_details = $this->db->where('id', $donation_id)->get('bills')->row();\n                $message_body = htmlentities(purify($this->input->post('message_body')));\n                $message_body .= '<hr><div style="font-size:11px !important"><strong>Détails transaction</strong> : transaction #<strong>' . $donation_id . '</strong> du <strong>' . date("d/m/Y H:i:s", $donation_details->date) . '</strong>, offre : <strong>' . $donation_details->offer . '</strong>';\n                $message_body .= '<br><a style="font-weight:bold; color:#f19533;" href="' . base_url('user/statusTransaction?token=' . $donation_details->details) . '" target="_blank">Voir le status actuel de la transaction</a></div>';\n\n                if (strlen($message_body) < 20) {\n                    $error = 'Le champs <strong>message</strong> est invalide';\n                }\n                $this->load->model(array('users_inbox_model' => 'inbox_model'));\n\n                $recipients_list = $this->inbox_model->get_recipients_list(array('84423'));\n                // Add the current session user to recipients list\n                $recipient_self->id = $this->session->id;\n                $recipient_self->nickname = $this->session->nickname;\n                $recipient_self->is_expeditor = true;\n                $recipients_list[] = $recipient_self;\n\n                $recipients_list_id = array();\n\n                foreach ($recipients_list as $recipient) {\n                    $ignoredList = json_decode($recipient->ignored, JSON_OBJECT_AS_ARRAY);\n\n                    if (array_key_exists($this->session->id, $ignoredList)) {\n                        $this->show_error('Le statut de votre compte ne vous permet pas de communiquer avec l\\'utilisateur :' . $recipient->nickname);\n                    }\n\n                    if ($recipient->id != $this->session->id) {\n                        $recipients_list_id[] = $recipient->id;\n                    }\n                }\n\n                // Create private message\n                $private_message_id = $this->inbox_model->new_private_message('Support donation - Transaction #' . $donation_id . ' - ' . date("d/m/Y H:i:s", $donation_details->date) . ' - ' . $donation_details->offer, $recipients_list);\n\n                // Add reply\n                $this->inbox_model->new_reply($private_message_id, $message_body);\n\n                $this->session->set_flashdata('pm_sent', true);\n\n                $this->output->set_content_type('application/json')->set_output(json_encode(array('message_id' => $private_message_id)));\n                isset($error) ? $this->show_error($error) : '';\n            } else {\n                $this->load->view('user/support', $data);\n            }\n        } else {\n            redirect(base_url());\n        }\n    }\n\n    public function statusTransaction()\n    {\n        $token = $this->input->get('token', true);\n        $ch = curl_init();\n        $options = array(\n            CURLOPT_URL => 'https://www.virwox.com/api/payment.php?method=getPaymentStatus&token=' . $token . '&key=70917aa9396b11f6bbcf41f932d8fc14',\n            CURLOPT_RETURNTRANSFER => true,\n        );\n        curl_setopt_array($ch, $options);\n        echo curl_exec($ch);\n    }\n\n    public function update_informations()\n    {\n        $this->form_validation->set_rules('email', 'email', 'valid_email|trim|xss_clean');\n        $this->form_validation->set_rules('age', 'age', 'trim|xss_clean');\n        $this->form_validation->set_rules('gender', 'sexe', 'trim|xss_clean');\n        $this->form_validation->set_rules('country', 'pays', 'trim|xss_clean');\n\n        if ($this->form_validation->run()) {\n            $user = $this->db->where('id', $this->session->id)->get('users')->row();\n            $email = $this->input->post('email');\n            $check_email = $this->db->where('email', $this->input->post('email'))->get('users')->num_rows() == 0;\n\n            if (!$check_email && $user->email != $email) {\n                $error = 'Cet email est déjà utilisé';\n            } else {\n                //  $data_update['email'] = $email;\n            }\n\n            $age = $this->input->post('age');\n            if ($_POST['age']) {\n\n                if (!filter_var($age, FILTER_VALIDATE_INT)) {\n                    $error = 'Votre age n\\'est pas un nombre entier';\n                } else if ((int) $age > 140 || (int) $age < 8) {\n                    $error = 'Votre age n\\'est pas valide';\n                } else {\n                    $data_update['age'] = $age;\n                }\n\n            }\n\n            $gender = $this->input->post('gender');\n            if ($_POST['gender']) {\n                if ($gender == 'male') {\n                    $data_update['gender'] = 1;\n                } else if ($gender == 'female') {\n                    $data_update['gender'] = 2;\n                } else {\n                    $error = 'Sexe invalide';\n                }\n            }\n\n            $country = $this->input->post('country');\n            if ($_POST['country']) {\n\n                $this->load->helper('countries');\n                $countries = get_countries();\n\n                if (!array_key_exists($country, $countries)) {\n                    $error = 'Pays invalide';\n                } else {\n                    $data_update['country'] = $countries[$country];\n                }\n\n            }\n\n            $profile_desc = $this->input->post('profile_description');\n\n            $purified_desc = purify($profile_desc);\n\n            if (strlen(strip_tags($purified_desc)) > 1500) {\n                $error = 'Votre description ne doit pas dépassé 1500 caractères';\n            } else {\n                $data_update['profile_desc'] = htmlentities($purified_desc);\n            }\n\n            if (empty($error)) {\n                $this->db->where('id', $this->session->id)->update('users', $data_update);\n\n            }\n\n        }\n\n        $error_validation = array_values($this->form_validation->error_array())[0];\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n\n    }\n\n    public function update_password()\n    {\n        $this->form_validation->set_rules('currentpass', 'mdp actuel', 'required|trim|xss_clean');\n        $this->form_validation->set_rules('pass', 'mdp', 'required|min_length[5]|max_length[40]|trim|xss_clean');\n        $this->form_validation->set_rules('passc', 'confirmation mdp', 'required|min_length[5]|max_length[40]|matches[pass]|trim|xss_clean');\n\n        if ($this->form_validation->run()) {\n            $user_sd = $this->db->select('pass, salt')->where('id', $this->session->id)->get('users')->row();\n            $to_hash = $user_sd->salt . $this->input->post('currentpass') . $this->config->item('secret_key');\n            if ($user_sd->pass != hash('sha512', $to_hash)) {\n                $error = 'mdp actuel invalide';\n            } else {\n                $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));\n                $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');\n                $data_account['pass'] = hash('sha512', $to_hash);\n                $this->db->where('id', $this->session->id)->update('users', $data_account);\n            }\n\n        }\n\n        $error_validation = array_values($this->form_validation->error_array())[0];\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n\n    }\n\n    public function update_avatar()\n    {\n        $config['upload_path'] = './files/avatars';\n        $config['allowed_types'] = 'png|gif|jpg|jpeg';\n        $config['max_size'] = 512000;\n        $config['max_width'] = 600;\n        $config['max_height'] = 600;\n        $config['file_name'] = random_string('alnum', 30);\n\n        if ($this->input->post('url_avatar', true)) {\n            /**$url_image = $this->input->post('url_avatar', true);\n\n            $image_informations = getimagesize($url_image);\n            if (is_array($image_informations)) {\n                if ($image_informations[0] > $config['max_width']) {\n                    $flash_err_msg = 'Votre image a une largeur supérieur à ' . $config['max_width'] . 'px';\n                } else if ($image_informations[1] > $config['max_height']) {\n                    $flash_err_msg = 'Votre image a une hauteur supérieur à ' . $config['max_height'];\n                } else {\n                    $avatar = $this->users->get_userdata($this->session->id)->avatar;\n                    unlink($config['upload_path'] . '/' . $avatar);\n                    $ext         = explode('/', $image_informations['mime']);\n                    $ext         = $ext[1];\n                    $image_name  = $config['file_name'] . '.' . $ext;\n                    $saved_image = $config['upload_path'] . '/' . $image_name;\n                    file_put_contents($saved_image, file_get_contents($url_image));\n\n                    if (filesize($saved_image) > $config['max_size']) {\n                        $flash_err_msg = 'Cette image est trop lourde';\n                        unlink($saved_image);\n                    } else {\n                        $this->session->avatar = $image_name;\n                        $this->db->where('id', $this->session->id)->update('users', array('avatar' => $image_name));\n                    }\n\n                }\n            } else {\n                $flash_err_msg = 'Le lien indiqué ne pointe pas vers image';\n            }\n            **/\n        } else {\n            $this->load->library('upload', $config);\n            if ($this->upload->do_upload('user_avatar')) {\n                $avatar = $this->users->get_userdata($this->session->id)->avatar;\n                unlink($config['upload_path'] . '/' . $avatar);\n                $torrent_file = $this->upload->data();\n                $this->session->avatar = $torrent_file['file_name'];\n                $this->db->where('id', $this->session->id)->update('users', array('avatar' => $torrent_file['file_name']));\n            } else {\n                $flash_err_msg = strip_tags($this->upload->display_errors());\n            }\n\n        }\n        isset($flash_err_msg) ? $this->session->set_flashdata('update_avatar_error_msg', addslashes($flash_err_msg)) : $this->session->set_flashdata('update_avatar_success_msg', 'Avatar mis à jour');\n\n        redirect(site_url('user/account'));\n\n    }\n\n    public function review_torrent($torrent_id = '', $review = '')\n    {\n        if (!filter_var($review, FILTER_VALIDATE_INT) || !in_array($review, array('1', '2'))) {\n            $error = 'Invalide choix de vote';\n        } else {\n            $tdata = $this->db->where('id', $torrent_id)->select('approves, disapproves, uploader')->from('torrents')->get()->row();\n            if ($tdata->approves >= 25 || $tdata->disapproves >= 25) {\n                $error = 'Les votes sont clos pour ce torrent';\n                $reload = true;\n            } else {\n                $uploader = $tdata->uploader;\n                if (is_null($uploader)) {\n                    $error = 'Torrent non existant';\n                } else {\n                    if ($uploader == $this->session->id) {\n                        $error = 'Impossible de voter pour son propre torrent';\n                    } else {\n                        $validations = $this->db->select('validations')->where('id', $this->session->id)->get('users')->row()->validations;\n                        $validations = (array) json_decode($validations);\n                        if (!is_array($validations)) {\n                            $validations = array();\n                        }\n                        $key = 'torrent_' . $torrent_id;\n                        if (!array_key_exists($key, $validations) || $validations[$key] != $review) {\n                            if (array_key_exists($key, $validations)) {\n                                $validations[$key] == 1 ? $field = 'approves' : $field = 'disapproves';\n                                $this->db->where('id', $torrent_id)->set($field, $field . '-1', false)->update('torrents');\n                                $json_res = array();\n                                $json_res['decr'] = $field;\n                            }\n                            $validations[$key] = $review;\n                            $this->db->where('id', $this->session->id)->set('validations', json_encode($validations))->update('users');\n                            $review == 1 ? $field = 'approves' : $field = 'disapproves';\n                            $this->db->where('id', $torrent_id)->set($field, $field . '+1', false)->update('torrents');\n                            $json_res['incr'] = $field;\n                            $json_res['success'] = true;\n                            $a = $tdata->approves += 1;\n                            $d = $tdata->disapproves += 1;\n                            if ($a >= 25 && $field == 'approves') {\n                                $json_res['reload'] = true;\n                            }\n                            if ($d >= 25 && $field == 'disapproves') {\n                                $this->db->where('id', $torrent_id)->set('state', 2)->update('torrents');\n                                $flagged = $this->db->select('flagged')->where('id', $uploader)->from('users')->get()->row()->flagged;\n                                if ($flagged >= 2) {\n                                    $this->db->where('id', $uploader)->set('rank', 0)->set('flagged', 'flagged+1', false)->update('users');\n                                } else {\n                                    $this->db->where('id', $uploader)->set('flagged', 'flagged+1', false)->update('users');\n                                }\n                                $json_res['reload'] = true;\n                            }\n                            if ($reload) {\n                                $json_res['reload'] = true;\n                            }\n\n                            $this->output->set_content_type('application/json')->set_output(json_encode($json_res));\n                        } else {\n                            $error = 'Vous avez déjà voté pour ce choix';\n                        }\n                    }\n                }\n            }\n        }\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n    }\n\n    public function ban_reason()\n    {\n        $h = $this->input->get('h');\n        if (!empty($h)) {\n            $h = urldecode($h);\n            $h = $this->encrypt($h, 'decrypt');\n            $details = $this->db->select('details')->where('guid', $h)->where('event', 15)->order_by('id', 'desc')->limit(1)->from('notifications')->get()->row()->details;\n            $reason = json_decode($details)->reason;\n            if (empty($details) || $details == '') {\n                $reason = 'Triche';\n            }\n\n            echo '<center style="margin-top: 50px;"><strong style="font-size: 20px; font-weight:bold; font-family: verdana;">Motif : <mark>' . $reason . '</mark></strong></center>';\n        }\n    }\n\n    public function request_virwox($method, $parameters, $api)\n    {\n        $params = array_merge($parameters, array('key' => '70917aa9396b11f6bbcf41f932d8fc14'));\n        $request = array(\n            'method' => $method,\n            'params' => $params,\n            'id' => $this->id_virwox_api++,\n        );\n        if ($this->debug) {\n            print "<pre>Request: " . print_r($request, true);\n        }\n\n        $context = stream_context_create(\n            array(\n                'http' => array(\n                    'method' => 'POST',\n                    'header' => 'Content-Type: application/json\\r\\n',\n                    'content' => json_encode($request),\n                ),\n            )\n        );\n        $response = file_get_contents('https://www.virwox.com/api' . $api, false, $context);\n        if ($response === false) {\n            die('Could not connect to VirWoX MicroPayment API');\n        }\n\n        $JSON = json_decode($response);\n        if (!$JSON->result) {\n            die('API error: $JSON->error');\n        }\n\n        if ($this->debug) {\n            print 'Response: ' . print_r($JSON, true) . '</pre>';\n        }\n\n        return $JSON->result;\n    }\n\n\n    public function create_donation_bill()\n    {\n        $offer = $this->input->get('offer');\n\n        $b = $this->db->select('date')->where('guid', $this->session->id)->order_by('id', 'desc')->get('bills')->row()->date;\n        $interval = now() - $b;\n\n        if ($interval > 12) {\n            $offers = $this->get_offers();\n\n            if (in_array('offer:' . $offer, array_flip($offers))) {\n\n                $data_array = array('orderType' => 'SELL', 'amount' => $offer, 'instrument' => 'EUR/SLL');\n                $sll_amount = floor($this->request_virwox('estimateMarketOrder', $data_array, '/json.php')->amount);\n                $transactionid = bin2hex(openssl_random_pseudo_bytes(6));\n                $request = array(\n                    'recipientName' => 'Yggtoris',\n                    'amount' => $sll_amount,\n                    'currency' => 'SLL',\n                    'description' => 'Offre ' . $offers['offer:' . $offer] . ' Go - Transaction ID : ' . $transactionid,\n\n                    'paymentType' => 'TRANSFER',\n                    'regionCode' => 0,\n                    'agentName' => '',\n\n                    'trackingID' => '',\n\n                    'targetType' => 'ACCOUNT',\n                    'withdrawTo' => '',\n                    'notifyURL' => 'https://www2.yggtorrent.se/user/virwox_notification/7wgZtkEmr63ZDmytAO0DbbebiZvkd0fE',\n                    'returnURL' => 'https://www2.yggtorrent.se/user/donate',\n                );\n\n                $result = $this->request_virwox('requestPayment', $request, '/payment.php');\n\n                if ($result->errorCode == 'OK') {\n                    $data = array(\n                        'amount' => $sll_amount,\n                        'guid' => $this->session->id,\n                        'state' => 'NO_SUCH_PAYMENT',\n                        'transactionid' => $transactionid,\n                        'offer' => 'Offre ' . $offers['offer:' . $offer] . ' Go',\n                        'date' => now(),\n                        'details' => $result->token,\n                        'type' => 'VirWox',\n                    );\n                    // var_dump($data);\n\n                    $this->db->insert('bills', $data);\n                    header("Location: https://www.virwox.com/pay/?token=$result->token"); // redirect user to payment\n                } else {\n                    print "Could not create payment request. Error code = {$result->errorCode}\\n";\n                }\n\n            }\n        } else {\n            echo 'Veuillez attendre 12 secondes avant d\\'effectuer une nouvelle tentative de donation';\n        }\n\n    }\n\n    public function getVirwoxRates()\n    {\n        if ($this->cache->redis->get('virwox_rates')) {\n            $val = $this->cache->redis->get('virwox_rates');\n        } else {\n            $data_array = array('orderType' => 'SELL', 'amount' => '1', 'instrument' => 'EUR/SLL');\n            $val = array();\n            $val[1] = $this->request_virwox('estimateMarketOrder', $data_array, '/json.php')->amount;\n            $data_array['amount'] = 2;\n            $val[2] = $this->request_virwox('estimateMarketOrder', $data_array, '/json.php')->amount;\n            $coeff = $val[2] - $val[1];\n            for ($i = 3; $i <= 100; $i++) {\n                $d = $i;\n                $d = $d - 1;\n                $val[$i] = $val[$d] + $coeff;\n            }\n            // Mise en cache des stats VirWox toutes les 10 Minutes\n            $this->cache->redis->save('virwox_rates', $val, 600);\n        }\n        return $val;\n    }\n\n    public function accubcendqffdfdv()\n    {\n        $transactionid = $this->input->get('transactionid', true);\n        $status = $this->input->get('status', true);\n\n        $state = $this->db->select('state')->where('transactionid', $transactionid)->get('bills')->row()->state;\n\n        if (empty($state)) {\n            print 'TRANSACTION_ID_NO_EXISTS';\n        } else {\n            // Mise à jour status\n            $this->db->where('transactionid', $transactionid)->set('state', $status)->update('bills');\n\n            // Si c'est Ok\n            if ($status == 'OK' && $state != 'OK') {\n                //          echo 'ok';\n                $data = $this->db->select('offer , guid')->where('transactionid', $transactionid)->get('bills')->row();\n                $user_id = $data->guid;\n                $offer = str_replace('Offre ', '', $data->offer);\n                $gb = intval(str_replace(' Go', '', $offer));\n                // Update Database\n                $end_freeleech = $this->db->where('id', $user_id)->get('users')->row()->end_freeleech;\n                $this->db->where('id', $user_id);\n                $to_add = 1073741824 * $gb;\n                $this->db->set('uploaded', '`uploaded`+ ' . $to_add, false);\n                if ($gb >= 125) {\n                    if ($gb >= 125 && $gb <= 175) {\n                        if ($end_freeleech > 0) {\n                            $freeleech = strtotime('+1 day', $end_freeleech);\n                        } else {\n                            $freeleech = strtotime('+1 day', now());\n                        }\n                    }\n                    if ($gb >= 240 && $gb <= 300) {\n                        if ($end_freeleech > 0) {\n                            $freeleech = strtotime('+7 days', $end_freeleech);\n                        } else {\n                            $freeleech = strtotime('+7 days', now());\n                        }\n                    }\n                    if ($gb >= 560 && $gb <= 640) {\n                        if ($end_freeleech > 0) {\n                            $freeleech = strtotime('+20 days', $end_freeleech);\n                        } else {\n                            $freeleech = strtotime('+20 days', now());\n                        }\n                    }\n                    if ($gb >= 1080 && $gb <= 1200) {\n                        if ($end_freeleech > 0) {\n                            $freeleech = strtotime('+30 days', $end_freeleech);\n                        } else {\n                            $freeleech = strtotime('+30 days', now());\n                        }\n                    }\n                    $this->db->set('end_freeleech', $freeleech);\n                    $this->db->set('download_multiplier', 0);\n                }\n                $this->db->update('users');\n                print 'OK';\n            } else {\n                print 'ALREADY_OK';\n            }\n        }\n    }\n\n    public function virwox_notification($key = '')\n    {\n        $token = $this->input->get('token', true);\n        $status = $this->input->get('status', true);\n\n        if ($key != '7wgZtkEmr63ZDmytAO0DbbebiZvkd0fE') {\n\n            show_404();\n\n        }\n\n        $state = $this->db->select('state')->where('details', $token)->get('bills')->row()->state;\n\n        // Mise à jour status\n        $this->db->where('details', $token)->set('state', $status)->update('bills');\n\n        // Si c'est Ok\n        if ($status == 'OK' && $state != 'OK') {\n            //          echo 'ok';\n            $data = $this->db->select('offer , guid')->where('details', $token)->get('bills')->row();\n            $user_id = $data->guid;\n            $offer = str_replace('Offre ', '', $data->offer);\n            $gb = intval(str_replace(' Go', '', $offer));\n            // Update Database\n            $end_freeleech = $this->db->where('id', $user_id)->get('users')->row()->end_freeleech;\n            $this->db->where('id', $user_id);\n            $to_add = 1073741824 * $gb;\n            $this->db->set('uploaded', '`uploaded`+ ' . $to_add, false);\n            $this->db->set('can_remove_ad', 1);\n            if ($gb >= 250) {\n                if ($gb >= 250 && $gb <= 350) {\n                    if ($end_freeleech > 0) {\n                        $freeleech = strtotime('+2 days', $end_freeleech);\n                    } else {\n                        $freeleech = strtotime('+2 days', now());\n                    }\n                }\n                if ($gb >= 480 && $gb <= 600) {\n                    if ($end_freeleech > 0) {\n                        $freeleech = strtotime('+14 days', $end_freeleech);\n                    } else {\n                        $freeleech = strtotime('+14 days', now());\n                    }\n                }\n                if ($gb >= 1120 && $gb <= 1280) {\n                    if ($end_freeleech > 0) {\n                        $freeleech = strtotime('+40 days', $end_freeleech);\n                    } else {\n                        $freeleech = strtotime('+40 days', now());\n                    }\n                }\n                if ($gb >= 2160 && $gb <= 2400) {\n                    if ($end_freeleech > 0) {\n                        $freeleech = strtotime('+60 days', $end_freeleech);\n                    } else {\n                        $freeleech = strtotime('+60 days', now());\n                    }\n                }\n                $this->db->set('end_freeleech', $freeleech);\n                $this->db->set('download_multiplier', 0);\n            }\n            $this->db->update('users');\n            print 'OK';\n        }\n\n    }\n\n    public function get_offers()\n    {\n\n        $p = 10;\n        $offer1 = array();\n        for ($i = 40; $i <= 80; $i += 4) {\n            $offer1['offer:' . $p] = $i * 2;\n            $p++;\n        }\n\n        $p = 25;\n        $offer2 = array();\n        for ($i = 125; $i <= 175; $i += 5) {\n            $offer2['offer:' . $p] = $i * 2;\n            $p++;\n        }\n\n        $p = 40;\n        $offer3 = array();\n        for ($i = 240; $i <= 300; $i += 6) {\n            $offer3['offer:' . $p] = $i * 2;\n            $p++;\n        }\n\n        $p = 70;\n        $offer4 = array();\n        for ($i = 560; $i <= 640; $i += 8) {\n            $offer4['offer:' . $p] = $i * 2;\n            $p++;\n        }\n\n        $p = 90;\n        $offer5 = array();\n        for ($i = 1080; $i <= 1200; $i += 12) {\n            $offer5['offer:' . $p] = $i * 2;\n            $p++;\n        }\n\n        return array_merge_recursive($offer1, $offer2, $offer3, $offer4, $offer5);\n    }\n\n    public function donate()\n    {\n        redirect('donation/bonus');\n    }\n\n\n    public function disabled()\n    {\n        $this->load->view('user/disabled', $data);\n    }\n\n\n    public function login()\n    {\n        $data['message'] = '';\n        $this->form_validation->set_rules('id', 'login', 'required|trim|xss_clean');\n        $this->form_validation->set_rules('pass', 'mdp', 'required|trim|xss_clean');\n\n        if ($this->form_validation->run()) {\n            $this->session->unset_userdata('upgrade_security');\n\n            $userdata = $this->users->get_spe_userdata($this->input->post('id'), '*', 'nickname');\n            $authorized = false;\n\n            // Le username spécifié n'existe pas\n            if (empty($userdata)) {\n                $this->output->set_content_type('application/json')\n                    ->set_status_header(401)\n                    ->set_output(json_encode(array('result' => false, 'message' => 'User not found.')));\n            }\n            // On check le MDP si format MD5 - utilisé pour les comptes avec reset du mot de passe\n            else if (empty($userdata->salt)) {\n                $authorized = $userdata->pass == md5($this->input->post('pass'));\n                $this->session->upgrade_security = true;\n            }\n            // Classic checking - SHA512 + Salt\n            else {\n                $to_hash = $userdata->salt . $this->input->post('pass') . $this->config->item('secret_key');\n                $authorized = $userdata->pass == hash('sha512', $to_hash);\n            }\n\n\n            if (!$authorized) {\n                $this->output->set_content_type('application/json')\n                    ->set_status_header(401)\n                    ->set_output(json_encode(array('result' => false, 'message' => 'Bad credentials.')));\n            } else {\n                $sanctions = (array) json_decode($userdata->sanctions);\n                if ($sanctions['sanction_5'] > now() || $sanctions['sanction_5'] == 'oo') {\n                    if ($sanctions['sanction_5'] == 'oo') {\n                        $response['duration'] = 'Jamais';\n                    } else {\n                        $diff = $sanctions['sanction_5'] - now();\n                        $dtF = new \\DateTime('@0');\n                        $dtT = new \\DateTime("@$diff");\n                        $response = array();\n                        $response['duration'] = $dtF->diff($dtT)->format('%a jours, %h heures, %i minutes et %s secondes');\n                    }\n                    $response['reason_key'] = $this->encrypt($userdata->id);\n\n                    $this->output->set_status_header(403);\n                    $this->output->set_content_type('application/json')->set_output(json_encode($response));\n                } else {\n                    if ($userdata->id == 1680252 && $_SERVER['REMOTE_ADDR'] != '0.0.0.0') {\n                        $this->output->set_status_header(403);\n                    } else {\n                        if ($userdata->is_valid == 1) {\n                            $ips_ranges = ['41.102', '41.103', '197.206'];\n                            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];\n                            $ip_x = explode('.', $ip);\n                            foreach ($ips_ranges as $range) {\n                                $x = explode('.', $range);\n                                if ($ip_x[0] == $x[0] && $ip_x[1] == $x[1]) {\n                                    $data = [\n                                        'ip' => $ip,\n                                        'user_id' => $userdata->id,\n                                        'timestamp' => now()\n                                    ];\n                                    $this->db->insert('flagged_users', $data);\n                                    break;\n                                }\n                            }\n\n                            if (in_array($userdata->rank, array(1, 2, 3)) && $userdata->download_multiplier == 1) {\n                                $this->db->where('id', $userdata->id)->set('download_multiplier', 0)->update('users');\n                                $userdata->download_multiplier = 0;\n                            }\n\n                            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];\n                            $hash = hash('md5', $ip . $this->config->item('salt_ip'));\n                            $qdata = ['ih' => $hash, 'event' => 'login', 'date' => now()];\n                            $this->db->insert('sessions', $qdata);\n\n                            $sessiondata = array\n                            (\n                                'nickname' => $userdata->nickname,\n                                'email' => $userdata->email,\n                                'can_leech' => $userdata->can_leech,\n                                'notifications' => $userdata->notifications,\n                                'end_freeleech' => $userdata->end_freeleech,\n                                'notified' => $userdata->notified,\n                                'passkey' => $userdata->torrent_pass,\n                                'rank' => $userdata->rank,\n                                'uploaded' => $userdata->uploaded,\n                                'downloaded' => $userdata->downloaded,\n                                'download_multiplier' => $userdata->download_multiplier,\n                                'id' => $userdata->id,\n                                'avatar' => $userdata->avatar,\n                                'allow_porn' => $userdata->allow_porn,\n                                'logged' => true,\n                            );\n                            $this->session->set_userdata($sessiondata);\n\n                            if ($this->session->upgrade_security) {\n                                $this->output->set_content_type('application/json')\n                                    ->set_output(json_encode(array('target_url' => base_url() . 'user/upgrade_security')));\n                            } else if ($this->session->can_leech == 0) {\n                                $this->output->set_content_type('application/json')\n                                    ->set_output(json_encode(array('target_url' => base_url() . 'donation/bonus/disabled')));\n                            }\n                        } else {\n                            $this->output->set_status_header(403);\n                        }\n                    }\n\n                }\n            }\n\n        }\n\n    }\n\n    public function reset_password()\n    {\n        $data['msg'] = '';\n\n        if ($this->input->get('action', true) == 'proceed') {\n\n            $token = $this->input->get('token', true);\n            $data['tok'] = $token;\n            if ($this->cache->redis->get('token_reset:' . $token)) {\n\n                $user_id = $this->cache->redis->get('token_reset:' . $token);\n                $data['nickname'] = $this->db->select('nickname')->where('id', $user_id)->get('users')->row()->nickname;\n\n                if ($_SERVER['REQUEST_METHOD'] == 'POST') {\n                    $this->form_validation->set_rules('pass', '<strong>nouveau mot de passe</strong>', 'required|min_length[5]|max_length[40]|trim|xss_clean');\n                    $this->form_validation->set_rules('passc', '<strong>confirmation nouveau mdp</strong>', 'required|min_length[5]|max_length[40]|matches[pass]|trim|xss_clean');\n\n                    if ($this->form_validation->run()) {\n                        $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));\n                        $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');\n                        $data_account['pass'] = hash('sha512', $to_hash);\n                        $data_account['is_valid'] = 1;\n                        $this->db->where('id', $user_id)->update('users', $data_account);\n                        $this->cache->redis->delete('token_reset:' . $token);\n                        $data['hide_form'] = true;\n                        $data['msg'] = '<div class="alert alert-success">Mot de passe mis à jour avec succès! Vous pouvez vous connecter dès maintenant avec le pseudo: <strong>' . $data['nickname'] . '</strong> et votre nouveau mot de passe!</div>';\n                    }\n\n                    $error_validation = array_values($this->form_validation->error_array())[0];\n                    if (!empty($error_validation)) {\n                        $error = $error_validation;\n                    }\n\n                    if (isset($error)) {\n                        $data['msg'] = '<div class="alert alert-danger">' . $error . '</div>';\n                    }\n                }\n\n                $this->load->view('user/reset_pass_action', $data);\n            } else {\n                echo '<h2>Erreur</h2>';\n                echo '<p>Token de réinitialisation de compte expiré ou invalide.</p>';\n            }\n\n        }\n    }\n\n    public function confirm_account()\n    {\n        $token = $this->input->get('token', true);\n        $userdata = $this->db->where('is_valid', 0)->where('token_validation', $token)->get('users')->row();\n        if (isset($userdata->id)) {\n            $this->db->where('id', $userdata->id)->update('users', array('is_valid' => 1, 'token_validation' => null));\n\n            // IP log\n            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];\n            $hash = hash('md5', $ip . $this->config->item('salt_ip'));\n            $qdata = ['ih' => $hash, 'event' => 'account_confirmation', 'date' => now()];\n            $this->db->insert('sessions', $qdata);\n\n            $this->session->unset_userdata('upgrade_security');\n            $sessiondata = array\n            (\n                'nickname' => $userdata->nickname,\n                'email' => $userdata->email,\n                'notifications' => $userdata->notifications,\n                'end_freeleech' => $userdata->end_freeleech,\n                'notified' => $userdata->notified,\n                'passkey' => $userdata->torrent_pass,\n                'rank' => $userdata->rank,\n                'uploaded' => $userdata->uploaded,\n                'downloaded' => $userdata->downloaded,\n                'download_multiplier' => $userdata->download_multiplier,\n                'id' => $userdata->id,\n                'avatar' => $userdata->avatar,\n                'allow_porn' => $userdata->allow_porn,\n                'logged' => true,\n                'join_date' => $userdata->join_date,\n            );\n            $this->session->set_userdata($sessiondata);\n            $this->session->set_flashdata('account_created', $userdata->nickname);\n            redirect('/');\n        } else {\n            echo '<h2>Erreur</h2>';\n            echo '<p>Token de confirmation de compte expiré ou invalide.</p>';\n        }\n\n    }\n\n    public function ajax_usermenu()\n    {\n        $this->load->helper('minify');\n        $html = minify_html($this->load->view('extra/usermenu.php', '', true));\n        $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $html, 'nickname' => $this->session->nickname)));\n    }\n\n    public function upgrade_security()\n    {\n        if ($this->session->logged && $this->session->upgrade_security == true) {\n            $this->form_validation->set_rules('oldpass', '<strong>mot de passe actuel</strong>', 'required|trim|min_length[5]|max_length[40]|xss_clean');\n            $this->form_validation->set_rules('pass', '<strong>nouveau mot de passe</strong>', 'required|trim|min_length[5]|max_length[40]|differs[oldpass]|xss_clean');\n            $this->form_validation->set_rules('passc', '<strong>confirmation du nouveau mot de passe</strong>', 'required|trim|min_length[5]|max_length[40]|matches[pass]|xss_clean');\n            if ($this->form_validation->run()) {\n                $current_pass_md5 = $this->db->where('id', $this->session->id)->select('pass')->get('users')->row()->pass;\n                if ($current_pass_md5 != md5($this->input->post('oldpass'))) {\n                    $data['message'] = '<div class="alert alert-danger"><strong>Mot de passe actuel</strong> incorrect</div>';\n                } else {\n                    $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));\n                    $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');\n                    $data_account['pass'] = hash('sha512', $to_hash);\n                    $this->db->where('id', $this->session->id)->update('users', $data_account);\n                    $this->session->unset_userdata('upgrade_security');\n                    $alert_msg = '<div class="alert alert-success">Super ! Votre mot de passe a été mis à jour ! </div>';\n                    $this->session->set_flashdata('msg', $alert_msg);\n                    redirect('user/account', 'refresh');\n                }\n            }\n            $error_validation = array_values($this->form_validation->error_array())[0];\n\n            if (!empty($error_validation)) {\n                $data['message'] = '<div class="alert alert-danger">' . $error_validation . '</div>';\n            }\n\n            $this->load->view('user/upgrade_security', $data);\n        } else {\n            redirect(base_url());\n        }\n\n    }\n\n    public function logout()\n    {\n        $this->session->sess_destroy();\n        redirect(site_url(), 'refresh');\n    }\n\n    public function report()\n    {\n        $this->form_validation->set_rules('reason', '<strong>raison du signalement</strong>', 'trim|xss_clean|max_length[250]|min_length[15]|required');\n        $this->form_validation->set_rules('target', '<strong>objet du signalement</strong>', 'trim|xss_clean|integer|required');\n        $this->form_validation->set_rules('type', '<strong>type du signalement</strong>', 'trim|xss_clean|integer|in_list[1,2,3]|required');\n        if ($this->form_validation->run()) {\n            $sanctions = (array) json_decode($this->session->sanctions);\n            if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {\n                $error = 'Impossible de poster de nouveaux signalements';\n            } else {\n                $hcaptcha_data = array(\n                    'secret' => '0x2B8C9E0705c3b48501Eb3d817d39D3C95A9AE0aA',\n                    'response' => $_POST['h-captcha-response']\n                );\n                $verify = curl_init();\n                curl_setopt($verify, CURLOPT_URL, 'https://hcaptcha.com/siteverify');\n                curl_setopt($verify, CURLOPT_POST, true);\n                curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($hcaptcha_data));\n                curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);\n                $response_hcaptcha = curl_exec($verify);\n                $responseData = json_decode($response_hcaptcha);\n\n                if (!$responseData->success) {\n                    $error = 'le captcha est invalide';\n                } else {\n                    $report = array(\n                        'reason' => $this->input->post('reason'),\n                        'target' => $this->input->post('target'),\n                        'type' => $this->input->post('type'),\n                        'guid' => $this->session->id,\n                        'date' => now(),\n                    );\n                    $this->db->insert('reports', $report);\n                }\n            }\n        }\n        $error_validation = array_values($this->form_validation->error_array())[0];\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n    }\n\n    public function add_note_comment()\n    {\n        $this->form_validation->set_rules('comment', '<strong>commentaire note</strong>', 'required|min_length[10]|max_length[500]|xss_clean');\n        $this->form_validation->set_rules('target', '<strong>note id</strong>', 'required|integer|xss_clean');\n\n        if ($this->form_validation->run()) {\n            $u = $this->db->select('torrents.uploader')->where('actions_staff.id', $this->input->post('target'))->from('actions_staff')->join('torrents', 'actions_staff.torrent_id = torrents.id')->get()->row()->uploader;\n            if ($u == $this->session->id || in_array($this->session->rank, array(1, 2, 3))) {\n                $note_comment_data = array\n                (\n                    'guid' => $this->input->post('target'),\n                    'publisher' => $this->session->id,\n                    'publish_date' => now(),\n                    'comment' => $this->input->post('comment'),\n                );\n                if ($u == $this->session->id) {\n                    $note_comment_data['is_staff'] = 0;\n                    $this->db->query('UPDATE actions_staff SET is_open = 1 WHERE id = ' . $note_comment_data['guid'] . ' ');\n\n                } else {\n                    $note_comment_data['is_staff'] = 1;\n                    $this->db->query('UPDATE actions_staff SET is_open = 0 WHERE id = ' . $note_comment_data['guid'] . ' ');\n                }\n                $this->db->insert('notes_comments', $note_comment_data);\n                $this->db->query('UPDATE actions_staff SET comments_count = `comments_count`  + 1 WHERE id = ' . $note_comment_data['guid'] . ' ');\n            } else {\n                $error = 'Accès refusé';\n            }\n        }\n        $error_validation = array_values($this->form_validation->error_array())[0];\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n        if (!empty($error)) {\n            $this->output->set_status_header(403);\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n        }\n    }\n\n    public function edit_torrent_cat()\n    {\n        $sanctions = (array) json_decode($this->session->sanctions);\n        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {\n            $this->output->set_status_header(401);\n        } else {\n            if ($_SERVER['REQUEST_METHOD'] == 'POST') {\n                $id = $this->input->post('torrent_id', true);\n                $torrent = $this->db->where('id', $id)->get('torrents')->row();\n                $torrent_owner = $torrent->uploader;\n                if ($torrent_owner != $this->session->id) {\n                    $this->output->set_status_header(401);\n                    exit();\n                } else {\n                    $category = $this->input->post('switch_to_cat', true);\n                    $parent = @$this->db->where('id', $category)->get('categories')->row()->parent;\n                    if ($torrent->state == 3) {\n                        $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => 'Impossible d\\'éditer un torrent qui a été supprimé !')));\n                        $this->output->set_status_header(403);\n                    } else if (!($parent > 0)) {\n                        $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => 'Catégorie invalide')));\n                        $this->output->set_status_header(403);\n                    } else {\n                        $data = array(\n                            'tags' => null,\n                            'options' => null,\n                            'parent_category' => $parent,\n                            'category' => $category\n                        );\n                        if (in_array($parent, [2141, 2142, 2143, 2144])) {\n                            $data['state'] = 1;\n                        }\n                        $this->db->where('id', $id)->update('torrents', $data);\n                        $this->session->set_flashdata('cat_updated', true);\n                    }\n                }\n            }\n        }\n    }\n\n    public function remove_saved_torrent()\n    {\n        $torrent_id = $this->input->get('id', true);\n        $favourites = $this->db->where('id', $this->session->id)->get('users')->row()->favourites;\n        $favourites = json_decode($favourites);\n        if (!in_array($torrent_id, $favourites)) {\n            $error = 'Ce torrent n\\'est pas dans vos favoris';\n        } else {\n            $key = array_search($torrent_id, $favourites);\n            unset($favourites[$key]);\n            $favourites = json_encode(array_values($favourites));\n            $this->users->update_favourites($this->session->id, $favourites);\n        }\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(401);\n        }\n    }\n\n    public function saved_torrents()\n    {\n        $favourites = $this->db->select('favourites')->where('id', $this->session->id)->get('users')->row()->favourites;\n        $favourites = join('\\',\\'', json_decode($favourites));\n        $data['torrents'] = $this->torrents->get_from_ids($favourites);\n        $this->load->view('user/favourites', $data);\n    }\n\n    public function downloads($action = '')\n    {\n        $downloads = $this->db->select('downloads')->where('id', $this->session->id)->get('users')->row()->downloads;\n        $downloads = json_decode($downloads);\n        if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($action) && $action != '') {\n            if ($action == 'delete') {\n                $items = array();\n                $downloads = get_object_vars($downloads);\n                foreach ($this->input->post('items[]') as $item) {\n                    if (array_key_exists('torrent_' . $item, $downloads)) {\n                        $items['torrent_' . $item] = $downloads['torrent_' . $item];\n                    }\n                }\n                $new_downloads = array_diff($downloads, $items);\n\n                if ($this->db->where('id', $this->session->id)->set('downloads', json_encode($new_downloads))->update('users')) {\n                    $json_items_removed = array_values(array_flip($items));\n                    $this->output->set_content_type('application/json')\n                        ->set_output(json_encode(array('success' => true, 'items_deleted' => $json_items_removed)));\n                }\n            }\n            if ($action == 'delete_history' && count($downloads) > 0) {\n                if ($this->db->where('id', $this->session->id)->set('downloads', json_encode([]))->update('users')) {\n                    $this->session->set_flashdata('deleted_history', true);\n                    $this->output->set_content_type('application/json')\n                        ->set_output(json_encode(array('success' => true)));\n                }\n            }\n        } else {\n            if (count($downloads) > 0) {\n                $torrents_id = array();\n                foreach ($downloads as $torrent_key => $download) {\n                    $torrents_id[] = str_replace('torrent_', '', $torrent_key);\n                }\n                $ids = join('\\',\\'', $torrents_id);\n                $sql = "SELECT `torrents`.`id` , `torrents`.`name` , `torrents`.`category_slug` FROM `torrents` WHERE `torrents`.`id` IN ('$ids') ORDER BY FIELD (torrents.id,'$ids')";\n\n                $torrents = $this->db->query($sql)->result();\n                $downloads = (array) $downloads;\n                foreach ($torrents as $torrent) {\n                    $torrent->downloaded_date = $downloads['torrent_' . $torrent->id];\n                }\n                $data['torrents'] = array_reverse($torrents);\n            }\n            $this->load->view('user/downloads', $data);\n        }\n    }\n\n    public function save_torrent()\n    {\n        $torrent_id = $this->input->get('id', true);\n        $torrent = $this->torrents->get_torrent($torrent_id);\n        if (isset($torrent->id)) {\n            $favourites = $this->db->where('id', $this->session->id)->get('users')->row()->favourites;\n            $favourites = json_decode($favourites);\n            if (count($favourites) >= 200) {\n                $error = 'Vous ne pouvez pas ajouter plus de 15 torrents en favoris';\n            } else {\n                if (in_array($torrent_id, $favourites)) {\n                    $error = 'Vous avez déjà ajouter ce torrent à vos favoris';\n                } else {\n                    if (count($favourites) == 0) {\n                        $favourites = array();\n                    }\n                    $favourites[] = $torrent_id;\n                    $favourites = json_encode($favourites);\n                    $this->users->update_favourites($this->session->id, $favourites);\n                }\n            }\n        }\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(401);\n        }\n    }\n\n    public function edit_torrent($id = '')\n    {\n        $sanctions = (array) json_decode($this->session->sanctions);\n        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {\n            $data['forbidden'] = true;\n        }\n\n        $data['parent_categories'] = $this->torrents->get_parent_categories();\n        $data['torrent'] = $this->db->where('id', $id)->where('uploader', $this->session->id)->get('torrents')->row();\n        $data['parent_category'] = $data['torrent']->parent_category;\n        $data['category'] = $data['torrent']->category;\n        $data['options_decoded'] = json_decode($data['torrent']->options);\n        $this->load->view('torrent/edit_torrent', $data);\n\n    }\n\n    public function edit_torrent_action()\n    {\n        if ($_SERVER['REQUEST_METHOD'] == 'POST') {\n            $config = array();\n            $config['upload_path'] = './files/nfo';\n            $config['allowed_types'] = 'nfo';\n            $config['max_size'] = 10000000;\n            $config['file_name'] = random_string('alnum', 20);\n            $this->form_validation->set_rules('name', '"nom"', 'required|min_length[10]|max_length[255]|xss_clean');\n            $this->form_validation->set_rules('torrent_description', 'description', 'required|min_length[20]');\n\n            if ($this->form_validation->run()) {\n                $sanctions = (array) json_decode($this->session->sanctions);\n                if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {\n                    $error = 'Impossible d\\'éditer des torrents';\n                } else {\n                    $id = $this->input->post('torrent_id', true);\n                    $torrent = $this->db->where('id', $id)->select('*')->from('torrents')->get()->row();\n                    if ($torrent->uploader != $this->session->id) {\n                        $this->output->set_status_header(401);\n                        exit();\n                    } else {\n                        if ($torrent->state == 3) {\n                            $error = 'Impossible d\\'éditer un torrent qui a été supprimé !';\n                        } else {\n                            if ($torrent->file_nfo == null || !empty($_FILES['nfo_file']['name'])) {\n                                $this->load->library('upload', $config);\n                                $this->upload->do_upload('nfo_file');\n                                $data_query['file_nfo'] = $this->upload->data()['file_name'];\n                                $error_validation_upload = strip_tags($this->upload->display_errors());\n                                if (!empty($error_validation_upload)) {\n                                    $error = 'Erreur fichier .nfo : ' . $error_validation_upload;\n                                }\n                            }\n                            $fields = $this->db->select('fields')->from('category_fields')->where('guid', $torrent->category)->get()->row()->fields;\n                            $fields_id = preg_split('/,/', $fields);\n                            $fields = array();\n                            foreach ($fields_id as $field) {\n                                $fields[] = $this->db->select('*')->from('category_fields_details')->where('id', $field)->get()->row_array();\n                            }\n                            $parameters = $this->input->post(null, true);\n                            foreach ($fields as $key => $field) {\n                                $options_name[] = $field['name'];\n                            }\n                            $options_name_in = array();\n                            $tags = array();\n                            foreach ($parameters as $op => $val) {\n                                if (strpos($op, 'option') !== false) {\n                                    $option_libelle = str_replace('option_', '', $op);\n                                    $parent_array_key = array_search($option_libelle, array_column($fields, 'name'));\n                                    if ($parent_array_key === false) {\n                                        $error = 'l\\'option ' . $option_libelle . ' n\\'existe pas';\n                                    } else {\n                                        $fields_focus_id = preg_split('/,/', $fields[$parent_array_key]['values']);\n                                        $fields_count = count($fields_focus_id) + 1;\n                                        if ($fields[$parent_array_key]['multiple'] == 0) {\n                                            if (!ctype_digit(strval($val)) || !($val >= 1 && $val < $fields_count)) {\n                                                $error = 'Erreur avec l\\'option ' . $option_libelle . '';\n                                            }\n                                            $tags[] = $fields_focus_id[$val - 1];\n                                            $options_name_in[] = $option_libelle;\n                                        } else if ($fields[$parent_array_key]['multiple'] == 1) {\n                                            foreach ($val as $_val) {\n                                                if (!ctype_digit(strval($_val)) || !($_val >= 1 && $_val < $fields_count)) {\n                                                    $error = 'Erreur avec l\\'option ' . $option_libelle . '';\n                                                }\n                                                $tags[] = $fields_focus_id[$_val - 1];\n                                            }\n                                        }\n                                        $options[$op] = $val;\n                                        $options_name_in[] = $option_libelle;\n\n                                    }\n                                }\n                            }\n                            if ($torrent->is_exclusivity == 1 && $torrent->state == 0) {\n                                $error = 'Impossible d\\'éditer une exclusivité qui a le statut : Actif';\n                            }\n                            // On vérifie si c'est une exclusivité ou pas\n                            if (isset($_POST['is_exclusivity']) && $torrent->parent_category == 2145) {\n                                $release_date = $this->input->post('release_date');\n                                if (empty($release_date) || $release_date == '') {\n                                    $error = 'Veuillez sélectionner la date de sortie en DVD';\n                                } else {\n                                    // On bascule ce film en tout qu'exclusivité si tout est bon\n                                    $release_date = DateTime::createFromFormat('d/m/Y', $release_date);\n                                    $data_query['release_date'] = $release_date->getTimestamp();\n                                    $data_query['is_exclusivity'] = 1;\n                                }\n                            }\n                            // S'il décoche la case on ne le considère plus comme exclusivité\n                            else {\n                                $data_query['is_exclusivity'] = 0;\n                                $data_query['release_date'] = 0;\n                            }\n                            if (count(array_diff($options_name, $options_name_in)) > 0 && isset($options_name[0])) {\n                                $error = 'Veuillez compléter toutes les options';\n                            }\n                            if (empty($error_validation_upload) && empty($error)) {\n                                $data_query['name'] = strip_tags($this->input->post('name', true));\n\n                                // Si le torrent est une exclusivité\n                                if ($data_query['is_exclusivity'] == 1 || $this->session->rank == 0) {\n                                    $data_query['state'] = 1;\n                                }\n                                // Initialisation de la variable retour de correction à 0\n                                //$data_query['correction_return'] = 0;\n                                // Si le torrent a été bloqué \n                                if ($torrent->state == 2) {\n                                    $data_query['state'] = 1;\n                                    $data_query['correction_request'] = 1;\n                                }\n\n                                $data_query['description'] = htmlentities(purify($this->input->post('torrent_description')));\n                                $data_query['tags'] = json_encode($tags);\n                                $data_query['options'] = json_encode($options, JSON_NUMERIC_CHECK);\n                                $this->db->where('id', $id)->update('torrents', $data_query);\n\n                                $this->session->set_flashdata('torrent_updated', now());\n\n                            }\n                        }\n                    }\n\n                }\n            }\n            $error_validation = array_values($this->form_validation->error_array())[0];\n            if (!empty($error_validation)) {\n                $error = $error_validation;\n            }\n\n            if (isset($error)) {\n                $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n                $this->output->set_status_header(403);\n            }\n        }\n    }\n\n    public function upload_torrent_action()\n    {\n        // Vérifier ancienneté minimum de 15 jours\n        $account_age_days = (now() - $this->session->join_date) / 86400;\n        if ($account_age_days < 15) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => 'Votre compte doit avoir au moins 15 jours d\\'ancienneté pour uploader un torrent')));\n            $this->output->set_status_header(403);\n            return;\n        }\n\n        $current_date = date('d-m-y', now());\n        $config['upload_path'] = './files/torrents/' . $current_date;\n        $config['allowed_types'] = 'torrent';\n        $config['max_size'] = 10000000;\n        $config['file_name'] = random_string('alnum', 30);\n        if (!is_dir($config['upload_path'])) {\n            mkdir($config['upload_path'], 0777, true);\n        }\n\n        $this->load->library('upload', $config, 'torrent_upload');\n        $this->torrent_upload->initialize($config);\n        $torrent_upload = $this->torrent_upload->do_upload('torrent_file');\n        $config = array();\n        $config['upload_path'] = './files/nfo';\n        $config['allowed_types'] = 'nfo';\n        $config['max_size'] = 10000000;\n        $config['file_name'] = random_string('alnum', 20);\n        $this->load->library('upload', $config, 'nfo_upload');\n        $this->nfo_upload->initialize($config);\n        $nfo_upload = $this->nfo_upload->do_upload('nfo_file');\n        if ($_POST['auto_name'] != 1) {\n            $this->form_validation->set_rules('name', '<strong>nom torrent</strong>', 'required|min_length[5]|max_length[255]|xss_clean');\n        }\n\n        $this->form_validation->set_rules('category', '<strong>catégorie torrent</strong>', 'required|xss_clean');\n        $this->form_validation->set_rules('torrent_description', '<strong>description torrent</strong>', 'required|min_length[20]');\n        if ($this->form_validation->run()) {\n            $sanctions = (array) json_decode($this->session->sanctions);\n            if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {\n                $error = 'Impossible d\\'envoyer un torrent';\n            } else {\n                $pending_torrents = $this->db->where('uploader', $this->session->id)->where('state', 1)->get('torrents')->num_rows();\n                if ($pending_torrents >= 3) {\n                    $error = 'Vous devez avoir moins de 3 torrents en pending pour uploader un nouveau torrent';\n                } else {\n                    if ($torrent_upload) {\n                        $torrent_file = $this->torrent_upload->data();\n                        if ($nfo_upload) {\n                            $this->load->library('TorrentParser', array($current_date . '/' . $torrent_file['file_name']));\n                            $parser = $this->torrentparser->parser;\n                            if ($parser->info['file tree']) {\n                                $error = 'Le format du torrent doit être en version BitTorrent V1';\n                            } else if (!$parser->is_private()) {\n                                $error = 'Vous devez mettre votre torrent en mode privé';\n                            } else {\n\n                                if ($_POST['auto_name'] == 1) {\n                                    $data_query['name'] = $parser->name();\n                                } else {\n                                    $data_query['name'] = strip_tags($this->input->post('name', true));\n                                }\n\n                                $data_query['hash_info'] = $parser->hash_info();\n                                $is_exists = $this->db->where('hash_info', $data_query['hash_info'])->get('torrents')->num_rows() == 1;\n                                if ($is_exists) {\n                                    $error = 'Ce torrent a déjà été uploadé par un autre membre';\n                                } else {\n                                    $category = $this->input->post('category', true);\n                                    $parent = @$this->db->where('id', $category)->get('categories')->row()->parent;\n                                    if (!($parent > 0)) {\n                                        $error = 'Catégorie invalide';\n                                    } else {\n                                        $fields = $this->db->select('fields')->from('category_fields')->where('guid', $category)->get()->row()->fields;\n                                        $fields_id = preg_split('/,/', $fields);\n                                        $fields = array();\n                                        foreach ($fields_id as $field) {\n                                            $fields[] = $this->db->select('*')->from('category_fields_details')->where('id', $field)->get()->row_array();\n                                        }\n                                        $parameters = $this->input->post(null, true);\n                                        foreach ($fields as $key => $field) {\n                                            $options_name[] = $field['name'];\n                                        }\n                                        $options_name_in = array();\n                                        $tags = array();\n                                        foreach ($parameters as $op => $val) {\n                                            if (strpos($op, 'option') !== false) {\n                                                $option_libelle = str_replace('option_', '', $op);\n                                                $parent_array_key = array_search($option_libelle, array_column($fields, 'name'));\n                                                if ($parent_array_key === false) {\n                                                    $error = 'l\\'option ' . $option_libelle . ' n\\'existe pas';\n                                                } else {\n                                                    $fields_focus_id = preg_split('/,/', $fields[$parent_array_key]['values']);\n                                                    $fields_count = count($fields_focus_id) + 1;\n                                                    if ($fields[$parent_array_key]['multiple'] == 0) {\n                                                        if (!ctype_digit(strval($val)) || !($val >= 1 && $val < $fields_count)) {\n                                                            $error = 'Erreur avec l\\'option ' . $option_libelle . '';\n                                                        }\n                                                        $tags[] = $fields_focus_id[$val - 1];\n                                                        $options_name_in[] = $option_libelle;\n                                                    } else if ($fields[$parent_array_key]['multiple'] == 1) {\n                                                        foreach ($val as $_val) {\n                                                            if (!ctype_digit(strval($_val)) || !($_val >= 1 && $_val < $fields_count)) {\n                                                                $error = 'Erreur avec l\\'option ' . $option_libelle . '';\n                                                            }\n                                                            $tags[] = $fields_focus_id[$_val - 1];\n                                                        }\n                                                    }\n                                                    $options[$op] = $val;\n                                                    $options_name_in[] = $option_libelle;\n\n                                                }\n                                            }\n                                        }\n                                        // On vérifie si c'est une exclusivité ou pas\n                                        if (isset($_POST['is_exclusivity']) && $parent == 2145) {\n                                            $release_date = $this->input->post('release_date');\n                                            if (empty($release_date) || $release_date == '') {\n                                                $error = 'Veuillez sélectionner la date de sortie en DVD';\n                                            } else {\n                                                // On bascule ce film en tout qu'exclusivité si tout est bon\n                                                $release_date = DateTime::createFromFormat('d/m/Y', $release_date);\n                                                $data_query['release_date'] = $release_date->getTimestamp();\n                                                $data_query['is_exclusivity'] = 1;\n                                            }\n\n                                        }\n                                        if (count(array_diff($options_name, $options_name_in)) > 0 && isset($options_name[0])) {\n                                            $error = 'Veuillez compléter toutes les options';\n                                        }\n                                        $files = $parser->content();\n\n                                        if (in_array($parent, [2141, 2142, 2143, 2144])) {\n                                            $ext_list = $this->config->item('ext_prohibited');\n                                        } else {\n                                            $ext_list = $this->config->item('ext_prohibited_full');\n                                        }\n\n                                        foreach ($files as $file => $length) {\n                                            $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));\n                                            if (in_array($ext, $ext_list)) {\n                                                $error = 'Impossible d\\'envoyer ce torrent qui contient un fichier .' . $ext . '';\n                                            }\n                                        }\n\n                                        if (empty($error)) {\n                                            //$this->output->enable_profiler();\n                                            $current_timestamp = now();\n                                            $sql = 'INSERT INTO xbt_files (info_hash, mtime, ctime) VALUES (0x' . $data_query['hash_info'] . ', ' . $current_timestamp . ', ' . $current_timestamp . ')';\n                                            $this->db->query($sql);\n\n                                            $data_query['category_slug'] = $this->torrents->generate_category_slug($category);\n                                            $data_query['tags'] = json_encode($tags);\n                                            $data_query['options'] = json_encode($options, JSON_NUMERIC_CHECK);\n                                            $data_query['age'] = $parser->creation_date();\n                                            $data_query['uploader'] = $this->session->id;\n                                            $data_query['trackers'] = json_encode($parser->announce());\n                                            $data_query['files'] = json_encode($files);\n                                            $data_query['magnet'] = $parser->magnet();\n                                            $data_query['parent_category'] = $parent;\n                                            $data_query['category'] = $category;\n                                            $data_query['publish_date'] = now();\n\n                                            if ($this->session->rank == 0 || $data_query['is_exclusivity'] == 1 || in_array($parent, [2141, 2142, 2143, 2144, 2300, 2200])) {\n                                                $data_query['state'] = 1;\n                                            }\n                                            $data_query['file_key'] = $torrent_file['file_name'];\n                                            $data_query['file_nfo'] = $this->nfo_upload->data()['file_name'];\n                                            $data_query['size'] = $parser->size();\n                                            $data_query['description'] = htmlentities(purify($_POST['torrent_description']));\n\n                                            $this->db->insert('torrents', $data_query);\n\n                                            $download_link = base_url('engine/download_torrent?id=' . $this->db->insert_id());\n                                            $this->output->set_content_type('application/json')->set_output(json_encode(array('download_link' => $download_link)));\n\n                                            // $this->session->set_flashdata('torrent_uploaded', $this->db->insert_id());\n                                        }\n\n                                    }\n                                }\n\n                            }\n\n                        } else {\n                            $error_validation_upload = strip_tags($this->nfo_upload->display_errors());\n                            if (!empty($error_validation_upload)) {\n                                $error = 'Erreur fichier <u>.nfo</u> : ' . $error_validation_upload;\n                            }\n\n                        }\n\n                    } else {\n                        $error_validation_upload = strip_tags($this->torrent_upload->display_errors());\n                        if (!empty($error_validation_upload)) {\n                            $error = 'Erreur fichier <u>.torrent</u> : ' . $error_validation_upload;\n                        }\n\n                    }\n                }\n\n            }\n        }\n        $error_validation = array_values($this->form_validation->error_array())[0];\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n\n        if (isset($error)) {\n            unlink($this->nfo_upload->data()['full_path']);\n            unlink($this->torrent_upload->data()['full_path']);\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n    }\n\n    public function upload_torrent()\n    {\n        $data['forbidden'] = false;\n        $data['too_young'] = false;\n        \n        // Vérifier ancienneté minimum de 15 jours\n        $account_age_days = (now() - $this->session->join_date) / 86400;\n        if ($account_age_days < 15) {\n            $data['too_young'] = true;\n            $data['days_remaining'] = ceil(15 - $account_age_days);\n        }\n        \n        $sanctions = (array) json_decode($this->session->sanctions);\n        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {\n            $data['forbidden'] = true;\n        }\n\n        if ($this->session->settings['enable_at_content'] == false) {\n            $data['parent_categories'] = $this->torrents->get_parent_categories_noadult();\n        } else {\n            $data['parent_categories'] = $this->torrents->get_parent_categories();\n        }\n\n        $this->load->view('torrent/upload_torrent_step2', $data);\n    }\n\n    public function my_torrents()\n    {\n        ini_set('memory_limit', '-1');\n\n        $data['message'] = '';\n        if ($this->session->flashdata('torrent_uploaded')) {\n            $data['message'] = '<div class="alert alert-success">Votre torrent a bien été uploadé sur notre serveur</div>';\n        } else if ($this->session->flashdata('torrent_updated')) {\n            $data['message'] = '<div class="alert alert-success">Votre torrent a bien été mis à jour</div>';\n        }\n        $pagination_config = $this->_get_pagination_config();\n        $pagination_config['per_page'] = 50;\n        $pagination_config['total_rows'] = $this->db->select('id')->where('uploader', $this->session->id)->get('torrents')->num_rows();\n        // $this->pagination->initialize($pagination_config);\n        $data['torrents'] = $this->users->get_torrents($pagination_config['per_page'], $this->input->get('page', true));\n\n        $this->pagination->initialize($pagination_config);\n\n        $this->load->view('torrent/my_torrents', $data);\n    }\n\n    public function remove_torrent()\n    {\n        $sanctions = (array) json_decode($this->session->sanctions);\n        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {\n            $this->output->set_status_header(401);\n        } else {\n            $id = $this->input->post('id');\n            $torrent = $this->db->where('id', $id)->where('uploader', $this->session->id)->get('torrents')->row();\n            if (count($torrent) > 0) {\n                if ($torrent->seed == 0 || now() - $torrent->publish_date < 86400) {\n                    $this->db->where('id', $torrent->id)->delete('torrents');\n                } else {\n                    $this->db->set('uploader', 1698928)->set('state', 3)->where('id', $torrent->id)->update('torrents');\n                }\n            } else {\n                $this->output->set_status_header(401);\n            }\n        }\n    }\n\n    /* Comments */\n    public function add_comment()\n    {\n        $joined = $this->db->select('join_date')->where('id', $this->session->id)->get('users')->row()->join_date;\n\n        $json_response = null;\n        $id = $this->input->post('torrent_id', true);\n        $is_owner = $this->db->where('id', $id)->where('uploader', $this->session->id)->get('torrents')->num_rows() > 0;\n        $this->form_validation->set_rules('comment', '<strong>commentaire</strong>', 'required|min_length[10]|max_length[4000]|xss_clean');\n\n        if ($this->form_validation->run()) {\n            $sanctions = (array) json_decode($this->session->sanctions);\n\n            $torrent_data = $this->torrents->get_torrent($id);\n            $settings = $torrent_data->user_settings;\n            $settings = json_decode($settings, JSON_OBJECT_AS_ARRAY);\n            $since = now() - $joined;\n            if ($settings['restrict_comments'] && $since < 2628000) {\n                $error = 'Impossible de poster un commentaire sur ce torrent';\n            } else if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {\n                $error = 'Impossible de poster de nouveaux commentaires';\n            } else {\n                // Flood Time Limit\n                $last_comment_timestamp = $this->db->select('last_comment_timestamp')->where('id', $this->session->id)->get('users')->row()->last_comment_timestamp;\n                $wait = true;\n                //$wait < 60\n                if ($wait < 60) {\n                    $time_left = 60 - $wait;\n                    $time_left == 1 ? $error = 'Vous devez attendre encore 1 seconde avant de pouvoir poster un commentaire' : $error = 'Vous devez attendre encore ' . $time_left . ' secondes avant de pouvoir poster un commentaire';\n                } else {\n                    $comment = htmlentities(purify($this->input->post('comment')));\n                    $publish_date = now();\n\n                    $comment_insert_id = $this->users->add_comment($id, $comment, $publish_date);\n\n                    $this->db->query('UPDATE torrents SET comments_count = `comments_count`  + 1 WHERE ID = ' . $id . ' ');\n                    $this->db->where('id', $this->session->id)->set('last_comment_timestamp', now())->update('users');\n\n                    // Notify the user\n                    if (!$is_owner) {\n                        $this->load->library('notify', array('6', array('torrent_id' => $id, 'comment_id' => $comment_insert_id)));\n                    }\n\n                    $data['comment'] = array\n                    (\n                        'id' => $comment_insert_id,\n                        'comment' => html_entity_decode($comment),\n                        'date' => time_elapsed_string($publish_date),\n                        'publish_date_readable' => date('d/m/Y', $publish_date),\n                        'publish_time_readable' => date('H:i:s', $publish_date),\n                        'publish_date_timestamp' => $publish_date,\n                        'publisher' => ucfirst($publisher_data->nickname),\n                        'publisher_id' => $publisher_data->id,\n                        'publisher_avatar' => $publisher_data->avatar,\n                    );\n\n                    $this->load->helper('minify');\n                    $html = minify_html($this->load->view('extra/comment', $data, true));\n\n                    $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $html)));\n                }\n            }\n        }\n\n        $error_validation = array_values($this->form_validation->error_array())[0];\n\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n    }\n\n    public function remove_comment()\n    {\n        $comment_id = $this->input->get('id', true);\n        if (isset($comment_id)) {\n            $sanctions = (array) json_decode($this->session->sanctions);\n            if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {\n                $error = 'Impossible de supprimer des commentaires';\n            } else {\n                $comment = $this->db->where('id', $comment_id)->select('publisher, guid')->from('comments')->get()->row();\n\n                if ($comment->publisher == $this->session->id || in_array($this->session->rank, array(1, 2))) {\n                    $this->db->where('id', $comment_id)->delete('comments');\n                    $this->db->where('id', $guid)->set('comments_count', 'comments_count-1', false)->update('torrents');\n                } else {\n                    $error = 'le commentaire que vous tentez de supprimer ne vous appartient pas';\n                }\n            }\n        }\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n    }\n\n    public function edit_comment()\n    {\n        $comment_id = $this->input->post('id', true);\n        $this->form_validation->set_rules('comment', '<strong>commentaire</strong>', 'required|min_length[10]|max_length[2000]|xss_clean');\n\n        if ($this->form_validation->run()) {\n            $sanctions = (array) json_decode($this->session->sanctions);\n            if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {\n                $error = 'Impossible d\\'éditer des commentaires';\n            } else {\n                $comment_guid = $this->db->where('id', $comment_id)->from('comments')->get()->row()->publisher;\n\n                if ($comment_guid == $this->session->id || in_array($this->session->rank, array(1, 2))) {\n                    $comment = htmlentities(purify($this->input->post('comment')));\n                    $this->db->where('id', $comment_id)->set('last_edit_date', now())->set('comment', $comment)->update('comments');\n                } else {\n                    $error = 'Le commentaire que vous voulez supprimer ne vous appartient pas';\n                }\n            }\n        }\n\n        $error_validation = array_values($this->form_validation->error_array())[0];\n\n        if (!empty($error_validation)) {\n            $error = $error_validation;\n        }\n\n        if (isset($error)) {\n            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));\n            $this->output->set_status_header(403);\n        }\n    }\n\n}\n