<?php

defined('BASEPATH') or exit('No direct script access allowed');

class User extends MY_Controller
{

    public function __construct()
    {
        parent::__construct();

        $no_logged_methods = array('login', 'membership', 'register', 'reset_password', 'confirm_account', 'ban_reason', 'mail_test', 'virwox_notification', 'accubcendqffdfdv');

        if (empty($this->session->logged) && !in_array($this->router->fetch_method(), $no_logged_methods)) {
            $this->session->set_flashdata('show_login_form', true);
            redirect('engine/error?http_code=403');
        }

        if ($this->router->fetch_method() == 'openssl_e' || $this->router->fetch_method() == 'opensll_d') {
            $this->config->load('config');
        }

    }

    public function account()
    {
        $this->load->helper('countries');
        $data = array(
            'countries' => get_countries(),
            'user' => $this->db->where('id', $this->session->id)->get('users')->row(),
            'torrents_count' => $this->db->select('id')->where('uploader', $this->session->id)->get('torrents')->num_rows(),
            'comments_count' => $this->db->select('id')->where('publisher', $this->session->id)->get('comments')->num_rows(),
        );
        $this->load->view('user/account', $data);
    }

    public function turbo()
    {
        // Vérifier si l'utilisateur est soumis aux restrictions (même conditions que le timer)
        $this->config->load('yggconfig');
        $min_user_id = $this->config->item('download_timer_min_user_id');
        $exempt_ranks = $this->config->item('download_timer_exempt_ranks') ?: [];
        
        $is_restricted = ($this->session->id >= $min_user_id && !in_array($this->session->rank, $exempt_ranks));
        
        // Si l'utilisateur n'est pas restreint, rediriger vers la page compte
        if (!$is_restricted) {
            redirect('user/account');
        }
        
        // Récupérer premium_until depuis la session (Turbo = téléchargements sans attente ni limites)
        $premium_until = isset($this->session->premium_until) ? (int)$this->session->premium_until : 0;
        
        if ($premium_until == -1) {
            // Turbo à vie
            $is_turbo = true;
            $turbo_end = null;
            $days_remaining = -1;
            $is_lifetime = true;
        } elseif ($premium_until > 0 && $premium_until > now()) {
            // Turbo actif avec date de fin
            $is_turbo = true;
            $turbo_end = $premium_until;
            $days_remaining = floor(($premium_until - now()) / 86400);
            $is_lifetime = false;
        } else {
            // Pas de Turbo ou expiré
            $is_turbo = false;
            $turbo_end = null;
            $days_remaining = 0;
            $is_lifetime = false;
        }
        
        $data = array(
            'is_turbo' => $is_turbo,
            'is_lifetime' => $is_lifetime,
            'turbo_end' => $turbo_end,
            'days_remaining' => $days_remaining,
        );
        
        $this->load->view('user/turbo', $data);
    }

    public function allow_porn()
    {
        $this->form_validation->set_rules('allow_porn', 'allow_porn option', 'trim|xss_clean');
        if ($this->form_validation->run()) {
            if ($this->input->post('allow_porn') == 1) {
                $porn_val = 1;
                $this->session->set_flashdata('options_msg', '<strong style="color:green;">Section XXX activée !</strong>');
            } else {
                $porn_val = 0;
                $this->session->set_flashdata('options_msg', '<strong style="color:red;">Section XXX désactivée !</strong>');
            }
            $this->db->set('allow_porn', $porn_val)->where('id', $this->session->id)->update('users');
            $this->session->allow_porn = $porn_val;
            $this->session->set_flashdata('settings_update', true);
            redirect($this->agent->referrer());
        }

    }

    public function notifications()
    {
        $this->load->library('notify', array());
        $data['notifications'] = $this->db->where('guid', $this->session->id)->order_by('id', 'desc')->get('notifications')->result();
        $this->db->query('UPDATE users SET notified = notifications WHERE id = ' . $this->session->id . ' ');
        $this->load->view('user/notifications', $data);
    }

    public function blacklist()
    {
        // $this->output->enable_profiler();
        $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;
        $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);
        $ignoredList = array_flip($ignoredList);
        //  print_r($ignoredList);
        $ids = join('\\',\\'', $ignoredList);

        $sql = "SELECT id, avatar, rank, uploaded, downloaded, last_activity_date, nickname, country FROM users WHERE id IN ('$ids') ORDER BY FIELD (users.id,'$ids')";

        $data['users'] = $this->db->query($sql)->result();

        $this->load->view('user/ignored', $data);
    }

    public function ignore()
    {
        $action = $this->input->get('action');
        $user_id = $this->input->post('user_id');

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            // S'il s'agit d'un ajout
            if ($action == 'add') {
                $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;
                $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);

                if (array_key_exists($user_id, $ignoredList)) {
                    $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'false')));
                } else {
                    $isUserExists = $this->db->select('id')->where('id', $user_id)->get('users')->num_rows() > 0;

                    if (!$isUserExists) {
                        $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'false')));
                    } else {
                        // On ajoute l'utilisateur à la liste avec la date d'ajout
                        if (!is_array($ignoredList)) {
                            $ignoredList = array();
                            $ignoredList[$user_id] = now();
                        } else {
                            $ignoredList[$user_id] = now();
                        }

                        $ignoredList = json_encode($ignoredList);
                        $this->db->where('id', $this->session->id)->set('ignored', $ignoredList)->update('users');

                        $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'true')));
                    }
                }
            }

            if ($action == 'del') {
                // Aussi court que ça...
                $ignoredList = $this->db->select('ignored')->where('id', $this->session->id)->get('users')->row()->ignored;
                $ignoredList = json_decode($ignoredList, JSON_OBJECT_AS_ARRAY);

                if (array_key_exists($user_id, $ignoredList)) {
                    unset($ignoredList[$user_id]);
                    $ignoredList = json_encode($ignoredList);
                    $this->db->where('id', $this->session->id)->set('ignored', $ignoredList)->update('users');

                    $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'true')));
                } else {

                    $this->output->set_content_type('application/json')->set_output(json_encode(array('result' => 'false')));

                }
            }
        }
    }

    public function settings()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $this->form_validation->set_rules('sender_age', '<strong>ancienneté de l\\'expéditeur</strong>', 'required|in_list[24hours,4days,1week,2weeks,1month,3months,nocondition]');
            $this->form_validation->set_rules('tracker_id', '<strong>adresse du tracker</strong>', 'required|in_list[1,2]');

            if ($this->form_validation->run()) {
                // Init parameters to False
                $settings['pm']['enable'] = false;
                $settings['enable_at_content'] = false;
                $settings['anonymous_upload'] = false;
                $settings['disable_history'] = false;
                $settings['restrict_comments'] = false;

                $tracker_id = $this->input->post('tracker_id');

                if (isset($_POST['restrict_comments'])) {
                    $settings['restrict_comments'] = true;
                }

                if (isset($_POST['anonymous_upload'])) {
                    $settings['anonymous_upload'] = true;
                }

                if (isset($_POST['disable_history'])) {
                    $settings['disable_history'] = true;
                    $this->db->where('id', $this->session->id)->set('downloads', json_encode([]))->update('users');
                }

                if (isset($_POST['enable_pm'])) {
                    $settings['pm']['enable'] = true;
                }

                $settings['pm']['condition_sender_age'] = $this->input->post('sender_age', true);

                if (isset($_POST['enable_at_content'])) {
                    $settings['enable_at_content'] = true;
                }

                $settings = json_encode($settings);

                $this->db->where('id', $this->session->id)->set('settings', $settings)->set('tracker_id', $tracker_id)->update('users');

                $this->output->set_content_type('application/json')->set_output(json_encode($settings));
            }

            sizeof($this->form_validation->error_array()) > 0 ? $this->show_error(array_values($this->form_validation->error_array())[0]) : '';

        } else {

            $sender_age = $this->session->settings['pm']['condition_sender_age'];

            switch ($sender_age) {
                case '24hours':
                    $alias = '24 heures';
                    break;
                case '4days':
                    $alias = '4 jours';
                    break;
                case '1week':
                    $alias = '1 semaine';
                    break;
                case '2weeks':
                    $alias = '2 semaines';
                    break;
                case '1month':
                    $alias = '1 mois';
                    break;
                case '3months':
                    $alias = '3 mois';
                    break;
            }

            $data['pretty_alias'] = $alias;

            if ($this->session->tracker_id == 1) {
                $tracker_host = $this->config->item('secondary_tracker_host');
            } else {
                $tracker_host = $this->config->item('first_tracker_host');
            }
            $data['tracker_announce'] = 'http://' . $tracker_host . ':8080/' . $this->session->torrent_pass . '/announce';
            $this->load->view('user/settings', $data);
        }
    }

    public function ajax_notifications()
    {
        if ($this->session->notified < $this->session->notifications) {
            $notifs = $this->db->select('id')->where('guid', $this->session->id)->where('state', 0)->from('notifications')->order_by('id', 'asc')->limit(5)->get()->result_array();
            $notifs_id = array_map(function ($i) {
                return $i['id'];
            }, $notifs);
            $this->load->library('notify', array());

            $n = array();
            foreach ($notifs as $notif) {
                $n[] = $this->notify->getNotificationTPL($notif['id']);
            }
            $this->db->where_in('id', $notifs_id)->set('state', 1)->update('notifications');
            $this->db->where('id', $this->session->id)->set('notified', 'notified+' . count($notifs_id), false)->update('users');

            $this->output->set_content_type('application/json')->set_output(json_encode(array('new_notifications' => count($notifs_id), 'list' => json_encode($n))));
        } else {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('new_notifications' => 0)));
        }
    }

    public function support()
    {
        $show = $this->input->get('show', true);
        if ($show == 'donation') {
            $data['type'] = 'donation';
            $data['donations'] = $this->db->where('guid', $this->session->id)->order_by('id', 'desc')->get('bills')->result();
            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                $donation_id = $this->input->post('donation_id', true);
                $donations_id = array();

                foreach ($data['donations'] as $donation) {
                    $donations_id[] = $donation->id;
                }
                //print_r($donations_id);
                if (!in_array($donation_id, $donations_id)) {
                    $error = 'L\\'id de transaction est invalide';
                }
                $donation_details = $this->db->where('id', $donation_id)->get('bills')->row();
                $message_body = htmlentities(purify($this->input->post('message_body')));
                $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>';
                $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>';

                if (strlen($message_body) < 20) {
                    $error = 'Le champs <strong>message</strong> est invalide';
                }
                $this->load->model(array('users_inbox_model' => 'inbox_model'));

                $recipients_list = $this->inbox_model->get_recipients_list(array('84423'));
                // Add the current session user to recipients list
                $recipient_self->id = $this->session->id;
                $recipient_self->nickname = $this->session->nickname;
                $recipient_self->is_expeditor = true;
                $recipients_list[] = $recipient_self;

                $recipients_list_id = array();

                foreach ($recipients_list as $recipient) {
                    $ignoredList = json_decode($recipient->ignored, JSON_OBJECT_AS_ARRAY);

                    if (array_key_exists($this->session->id, $ignoredList)) {
                        $this->show_error('Le statut de votre compte ne vous permet pas de communiquer avec l\\'utilisateur :' . $recipient->nickname);
                    }

                    if ($recipient->id != $this->session->id) {
                        $recipients_list_id[] = $recipient->id;
                    }
                }

                // Create private message
                $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);

                // Add reply
                $this->inbox_model->new_reply($private_message_id, $message_body);

                $this->session->set_flashdata('pm_sent', true);

                $this->output->set_content_type('application/json')->set_output(json_encode(array('message_id' => $private_message_id)));
                isset($error) ? $this->show_error($error) : '';
            } else {
                $this->load->view('user/support', $data);
            }
        } else {
            redirect(base_url());
        }
    }

    public function statusTransaction()
    {
        $token = $this->input->get('token', true);
        $ch = curl_init();
        $options = array(
            CURLOPT_URL => 'https://www.virwox.com/api/payment.php?method=getPaymentStatus&token=' . $token . '&key=70917aa9396b11f6bbcf41f932d8fc14',
            CURLOPT_RETURNTRANSFER => true,
        );
        curl_setopt_array($ch, $options);
        echo curl_exec($ch);
    }

    public function update_informations()
    {
        $this->form_validation->set_rules('email', 'email', 'valid_email|trim|xss_clean');
        $this->form_validation->set_rules('age', 'age', 'trim|xss_clean');
        $this->form_validation->set_rules('gender', 'sexe', 'trim|xss_clean');
        $this->form_validation->set_rules('country', 'pays', 'trim|xss_clean');

        if ($this->form_validation->run()) {
            $user = $this->db->where('id', $this->session->id)->get('users')->row();
            $email = $this->input->post('email');
            $check_email = $this->db->where('email', $this->input->post('email'))->get('users')->num_rows() == 0;

            if (!$check_email && $user->email != $email) {
                $error = 'Cet email est déjà utilisé';
            } else {
                //  $data_update['email'] = $email;
            }

            $age = $this->input->post('age');
            if ($_POST['age']) {

                if (!filter_var($age, FILTER_VALIDATE_INT)) {
                    $error = 'Votre age n\\'est pas un nombre entier';
                } else if ((int) $age > 140 || (int) $age < 8) {
                    $error = 'Votre age n\\'est pas valide';
                } else {
                    $data_update['age'] = $age;
                }

            }

            $gender = $this->input->post('gender');
            if ($_POST['gender']) {
                if ($gender == 'male') {
                    $data_update['gender'] = 1;
                } else if ($gender == 'female') {
                    $data_update['gender'] = 2;
                } else {
                    $error = 'Sexe invalide';
                }
            }

            $country = $this->input->post('country');
            if ($_POST['country']) {

                $this->load->helper('countries');
                $countries = get_countries();

                if (!array_key_exists($country, $countries)) {
                    $error = 'Pays invalide';
                } else {
                    $data_update['country'] = $countries[$country];
                }

            }

            $profile_desc = $this->input->post('profile_description');

            $purified_desc = purify($profile_desc);

            if (strlen(strip_tags($purified_desc)) > 1500) {
                $error = 'Votre description ne doit pas dépassé 1500 caractères';
            } else {
                $data_update['profile_desc'] = htmlentities($purified_desc);
            }

            if (empty($error)) {
                $this->db->where('id', $this->session->id)->update('users', $data_update);

            }

        }

        $error_validation = array_values($this->form_validation->error_array())[0];
        if (!empty($error_validation)) {
            $error = $error_validation;
        }

        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }

    }

    public function update_password()
    {
        $this->form_validation->set_rules('currentpass', 'mdp actuel', 'required|trim|xss_clean');
        $this->form_validation->set_rules('pass', 'mdp', 'required|min_length[5]|max_length[40]|trim|xss_clean');
        $this->form_validation->set_rules('passc', 'confirmation mdp', 'required|min_length[5]|max_length[40]|matches[pass]|trim|xss_clean');

        if ($this->form_validation->run()) {
            $user_sd = $this->db->select('pass, salt')->where('id', $this->session->id)->get('users')->row();
            $to_hash = $user_sd->salt . $this->input->post('currentpass') . $this->config->item('secret_key');
            if ($user_sd->pass != hash('sha512', $to_hash)) {
                $error = 'mdp actuel invalide';
            } else {
                $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));
                $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');
                $data_account['pass'] = hash('sha512', $to_hash);
                $this->db->where('id', $this->session->id)->update('users', $data_account);
            }

        }

        $error_validation = array_values($this->form_validation->error_array())[0];
        if (!empty($error_validation)) {
            $error = $error_validation;
        }

        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }

    }

    public function update_avatar()
    {
        $config['upload_path'] = './files/avatars';
        $config['allowed_types'] = 'png|gif|jpg|jpeg';
        $config['max_size'] = 512000;
        $config['max_width'] = 600;
        $config['max_height'] = 600;
        $config['file_name'] = random_string('alnum', 30);

        if ($this->input->post('url_avatar', true)) {
            /**$url_image = $this->input->post('url_avatar', true);

            $image_informations = getimagesize($url_image);
            if (is_array($image_informations)) {
                if ($image_informations[0] > $config['max_width']) {
                    $flash_err_msg = 'Votre image a une largeur supérieur à ' . $config['max_width'] . 'px';
                } else if ($image_informations[1] > $config['max_height']) {
                    $flash_err_msg = 'Votre image a une hauteur supérieur à ' . $config['max_height'];
                } else {
                    $avatar = $this->users->get_userdata($this->session->id)->avatar;
                    unlink($config['upload_path'] . '/' . $avatar);
                    $ext         = explode('/', $image_informations['mime']);
                    $ext         = $ext[1];
                    $image_name  = $config['file_name'] . '.' . $ext;
                    $saved_image = $config['upload_path'] . '/' . $image_name;
                    file_put_contents($saved_image, file_get_contents($url_image));

                    if (filesize($saved_image) > $config['max_size']) {
                        $flash_err_msg = 'Cette image est trop lourde';
                        unlink($saved_image);
                    } else {
                        $this->session->avatar = $image_name;
                        $this->db->where('id', $this->session->id)->update('users', array('avatar' => $image_name));
                    }

                }
            } else {
                $flash_err_msg = 'Le lien indiqué ne pointe pas vers image';
            }
            **/
        } else {
            $this->load->library('upload', $config);
            if ($this->upload->do_upload('user_avatar')) {
                $avatar = $this->users->get_userdata($this->session->id)->avatar;
                unlink($config['upload_path'] . '/' . $avatar);
                $torrent_file = $this->upload->data();
                $this->session->avatar = $torrent_file['file_name'];
                $this->db->where('id', $this->session->id)->update('users', array('avatar' => $torrent_file['file_name']));
            } else {
                $flash_err_msg = strip_tags($this->upload->display_errors());
            }

        }
        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');

        redirect(site_url('user/account'));

    }

    public function review_torrent($torrent_id = '', $review = '')
    {
        if (!filter_var($review, FILTER_VALIDATE_INT) || !in_array($review, array('1', '2'))) {
            $error = 'Invalide choix de vote';
        } else {
            $tdata = $this->db->where('id', $torrent_id)->select('approves, disapproves, uploader')->from('torrents')->get()->row();
            if ($tdata->approves >= 25 || $tdata->disapproves >= 25) {
                $error = 'Les votes sont clos pour ce torrent';
                $reload = true;
            } else {
                $uploader = $tdata->uploader;
                if (is_null($uploader)) {
                    $error = 'Torrent non existant';
                } else {
                    if ($uploader == $this->session->id) {
                        $error = 'Impossible de voter pour son propre torrent';
                    } else {
                        $validations = $this->db->select('validations')->where('id', $this->session->id)->get('users')->row()->validations;
                        $validations = (array) json_decode($validations);
                        if (!is_array($validations)) {
                            $validations = array();
                        }
                        $key = 'torrent_' . $torrent_id;
                        if (!array_key_exists($key, $validations) || $validations[$key] != $review) {
                            if (array_key_exists($key, $validations)) {
                                $validations[$key] == 1 ? $field = 'approves' : $field = 'disapproves';
                                $this->db->where('id', $torrent_id)->set($field, $field . '-1', false)->update('torrents');
                                $json_res = array();
                                $json_res['decr'] = $field;
                            }
                            $validations[$key] = $review;
                            $this->db->where('id', $this->session->id)->set('validations', json_encode($validations))->update('users');
                            $review == 1 ? $field = 'approves' : $field = 'disapproves';
                            $this->db->where('id', $torrent_id)->set($field, $field . '+1', false)->update('torrents');
                            $json_res['incr'] = $field;
                            $json_res['success'] = true;
                            $a = $tdata->approves += 1;
                            $d = $tdata->disapproves += 1;
                            if ($a >= 25 && $field == 'approves') {
                                $json_res['reload'] = true;
                            }
                            if ($d >= 25 && $field == 'disapproves') {
                                $this->db->where('id', $torrent_id)->set('state', 2)->update('torrents');
                                $flagged = $this->db->select('flagged')->where('id', $uploader)->from('users')->get()->row()->flagged;
                                if ($flagged >= 2) {
                                    $this->db->where('id', $uploader)->set('rank', 0)->set('flagged', 'flagged+1', false)->update('users');
                                } else {
                                    $this->db->where('id', $uploader)->set('flagged', 'flagged+1', false)->update('users');
                                }
                                $json_res['reload'] = true;
                            }
                            if ($reload) {
                                $json_res['reload'] = true;
                            }

                            $this->output->set_content_type('application/json')->set_output(json_encode($json_res));
                        } else {
                            $error = 'Vous avez déjà voté pour ce choix';
                        }
                    }
                }
            }
        }
        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }
    }

    public function ban_reason()
    {
        $h = $this->input->get('h');
        if (!empty($h)) {
            $h = urldecode($h);
            $h = $this->encrypt($h, 'decrypt');
            $details = $this->db->select('details')->where('guid', $h)->where('event', 15)->order_by('id', 'desc')->limit(1)->from('notifications')->get()->row()->details;
            $reason = json_decode($details)->reason;
            if (empty($details) || $details == '') {
                $reason = 'Triche';
            }

            echo '<center style="margin-top: 50px;"><strong style="font-size: 20px; font-weight:bold; font-family: verdana;">Motif : <mark>' . $reason . '</mark></strong></center>';
        }
    }

    public function request_virwox($method, $parameters, $api)
    {
        $params = array_merge($parameters, array('key' => '70917aa9396b11f6bbcf41f932d8fc14'));
        $request = array(
            'method' => $method,
            'params' => $params,
            'id' => $this->id_virwox_api++,
        );
        if ($this->debug) {
            print "<pre>Request: " . print_r($request, true);
        }

        $context = stream_context_create(
            array(
                'http' => array(
                    'method' => 'POST',
                    'header' => 'Content-Type: application/json\\r\
',
                    'content' => json_encode($request),
                ),
            )
        );
        $response = file_get_contents('https://www.virwox.com/api' . $api, false, $context);
        if ($response === false) {
            die('Could not connect to VirWoX MicroPayment API');
        }

        $JSON = json_decode($response);
        if (!$JSON->result) {
            die('API error: $JSON->error');
        }

        if ($this->debug) {
            print 'Response: ' . print_r($JSON, true) . '</pre>';
        }

        return $JSON->result;
    }


    public function create_donation_bill()
    {
        $offer = $this->input->get('offer');

        $b = $this->db->select('date')->where('guid', $this->session->id)->order_by('id', 'desc')->get('bills')->row()->date;
        $interval = now() - $b;

        if ($interval > 12) {
            $offers = $this->get_offers();

            if (in_array('offer:' . $offer, array_flip($offers))) {

                $data_array = array('orderType' => 'SELL', 'amount' => $offer, 'instrument' => 'EUR/SLL');
                $sll_amount = floor($this->request_virwox('estimateMarketOrder', $data_array, '/json.php')->amount);
                $transactionid = bin2hex(openssl_random_pseudo_bytes(6));
                $request = array(
                    'recipientName' => 'Yggtoris',
                    'amount' => $sll_amount,
                    'currency' => 'SLL',
                    'description' => 'Offre ' . $offers['offer:' . $offer] . ' Go - Transaction ID : ' . $transactionid,

                    'paymentType' => 'TRANSFER',
                    'regionCode' => 0,
                    'agentName' => '',

                    'trackingID' => '',

                    'targetType' => 'ACCOUNT',
                    'withdrawTo' => '',
                    'notifyURL' => 'https://www2.yggtorrent.se/user/virwox_notification/7wgZtkEmr63ZDmytAO0DbbebiZvkd0fE',
                    'returnURL' => 'https://www2.yggtorrent.se/user/donate',
                );

                $result = $this->request_virwox('requestPayment', $request, '/payment.php');

                if ($result->errorCode == 'OK') {
                    $data = array(
                        'amount' => $sll_amount,
                        'guid' => $this->session->id,
                        'state' => 'NO_SUCH_PAYMENT',
                        'transactionid' => $transactionid,
                        'offer' => 'Offre ' . $offers['offer:' . $offer] . ' Go',
                        'date' => now(),
                        'details' => $result->token,
                        'type' => 'VirWox',
                    );
                    // var_dump($data);

                    $this->db->insert('bills', $data);
                    header("Location: https://www.virwox.com/pay/?token=$result->token"); // redirect user to payment
                } else {
                    print "Could not create payment request. Error code = {$result->errorCode}\
";
                }

            }
        } else {
            echo 'Veuillez attendre 12 secondes avant d\\'effectuer une nouvelle tentative de donation';
        }

    }

    public function getVirwoxRates()
    {
        if ($this->cache->redis->get('virwox_rates')) {
            $val = $this->cache->redis->get('virwox_rates');
        } else {
            $data_array = array('orderType' => 'SELL', 'amount' => '1', 'instrument' => 'EUR/SLL');
            $val = array();
            $val[1] = $this->request_virwox('estimateMarketOrder', $data_array, '/json.php')->amount;
            $data_array['amount'] = 2;
            $val[2] = $this->request_virwox('estimateMarketOrder', $data_array, '/json.php')->amount;
            $coeff = $val[2] - $val[1];
            for ($i = 3; $i <= 100; $i++) {
                $d = $i;
                $d = $d - 1;
                $val[$i] = $val[$d] + $coeff;
            }
            // Mise en cache des stats VirWox toutes les 10 Minutes
            $this->cache->redis->save('virwox_rates', $val, 600);
        }
        return $val;
    }

    public function accubcendqffdfdv()
    {
        $transactionid = $this->input->get('transactionid', true);
        $status = $this->input->get('status', true);

        $state = $this->db->select('state')->where('transactionid', $transactionid)->get('bills')->row()->state;

        if (empty($state)) {
            print 'TRANSACTION_ID_NO_EXISTS';
        } else {
            // Mise à jour status
            $this->db->where('transactionid', $transactionid)->set('state', $status)->update('bills');

            // Si c'est Ok
            if ($status == 'OK' && $state != 'OK') {
                //          echo 'ok';
                $data = $this->db->select('offer , guid')->where('transactionid', $transactionid)->get('bills')->row();
                $user_id = $data->guid;
                $offer = str_replace('Offre ', '', $data->offer);
                $gb = intval(str_replace(' Go', '', $offer));
                // Update Database
                $end_freeleech = $this->db->where('id', $user_id)->get('users')->row()->end_freeleech;
                $this->db->where('id', $user_id);
                $to_add = 1073741824 * $gb;
                $this->db->set('uploaded', '`uploaded`+ ' . $to_add, false);
                if ($gb >= 125) {
                    if ($gb >= 125 && $gb <= 175) {
                        if ($end_freeleech > 0) {
                            $freeleech = strtotime('+1 day', $end_freeleech);
                        } else {
                            $freeleech = strtotime('+1 day', now());
                        }
                    }
                    if ($gb >= 240 && $gb <= 300) {
                        if ($end_freeleech > 0) {
                            $freeleech = strtotime('+7 days', $end_freeleech);
                        } else {
                            $freeleech = strtotime('+7 days', now());
                        }
                    }
                    if ($gb >= 560 && $gb <= 640) {
                        if ($end_freeleech > 0) {
                            $freeleech = strtotime('+20 days', $end_freeleech);
                        } else {
                            $freeleech = strtotime('+20 days', now());
                        }
                    }
                    if ($gb >= 1080 && $gb <= 1200) {
                        if ($end_freeleech > 0) {
                            $freeleech = strtotime('+30 days', $end_freeleech);
                        } else {
                            $freeleech = strtotime('+30 days', now());
                        }
                    }
                    $this->db->set('end_freeleech', $freeleech);
                    $this->db->set('download_multiplier', 0);
                }
                $this->db->update('users');
                print 'OK';
            } else {
                print 'ALREADY_OK';
            }
        }
    }

    public function virwox_notification($key = '')
    {
        $token = $this->input->get('token', true);
        $status = $this->input->get('status', true);

        if ($key != '7wgZtkEmr63ZDmytAO0DbbebiZvkd0fE') {

            show_404();

        }

        $state = $this->db->select('state')->where('details', $token)->get('bills')->row()->state;

        // Mise à jour status
        $this->db->where('details', $token)->set('state', $status)->update('bills');

        // Si c'est Ok
        if ($status == 'OK' && $state != 'OK') {
            //          echo 'ok';
            $data = $this->db->select('offer , guid')->where('details', $token)->get('bills')->row();
            $user_id = $data->guid;
            $offer = str_replace('Offre ', '', $data->offer);
            $gb = intval(str_replace(' Go', '', $offer));
            // Update Database
            $end_freeleech = $this->db->where('id', $user_id)->get('users')->row()->end_freeleech;
            $this->db->where('id', $user_id);
            $to_add = 1073741824 * $gb;
            $this->db->set('uploaded', '`uploaded`+ ' . $to_add, false);
            $this->db->set('can_remove_ad', 1);
            if ($gb >= 250) {
                if ($gb >= 250 && $gb <= 350) {
                    if ($end_freeleech > 0) {
                        $freeleech = strtotime('+2 days', $end_freeleech);
                    } else {
                        $freeleech = strtotime('+2 days', now());
                    }
                }
                if ($gb >= 480 && $gb <= 600) {
                    if ($end_freeleech > 0) {
                        $freeleech = strtotime('+14 days', $end_freeleech);
                    } else {
                        $freeleech = strtotime('+14 days', now());
                    }
                }
                if ($gb >= 1120 && $gb <= 1280) {
                    if ($end_freeleech > 0) {
                        $freeleech = strtotime('+40 days', $end_freeleech);
                    } else {
                        $freeleech = strtotime('+40 days', now());
                    }
                }
                if ($gb >= 2160 && $gb <= 2400) {
                    if ($end_freeleech > 0) {
                        $freeleech = strtotime('+60 days', $end_freeleech);
                    } else {
                        $freeleech = strtotime('+60 days', now());
                    }
                }
                $this->db->set('end_freeleech', $freeleech);
                $this->db->set('download_multiplier', 0);
            }
            $this->db->update('users');
            print 'OK';
        }

    }

    public function get_offers()
    {

        $p = 10;
        $offer1 = array();
        for ($i = 40; $i <= 80; $i += 4) {
            $offer1['offer:' . $p] = $i * 2;
            $p++;
        }

        $p = 25;
        $offer2 = array();
        for ($i = 125; $i <= 175; $i += 5) {
            $offer2['offer:' . $p] = $i * 2;
            $p++;
        }

        $p = 40;
        $offer3 = array();
        for ($i = 240; $i <= 300; $i += 6) {
            $offer3['offer:' . $p] = $i * 2;
            $p++;
        }

        $p = 70;
        $offer4 = array();
        for ($i = 560; $i <= 640; $i += 8) {
            $offer4['offer:' . $p] = $i * 2;
            $p++;
        }

        $p = 90;
        $offer5 = array();
        for ($i = 1080; $i <= 1200; $i += 12) {
            $offer5['offer:' . $p] = $i * 2;
            $p++;
        }

        return array_merge_recursive($offer1, $offer2, $offer3, $offer4, $offer5);
    }

    public function donate()
    {
        redirect('donation/bonus');
    }


    public function disabled()
    {
        $this->load->view('user/disabled', $data);
    }


    public function login()
    {
        $data['message'] = '';
        $this->form_validation->set_rules('id', 'login', 'required|trim|xss_clean');
        $this->form_validation->set_rules('pass', 'mdp', 'required|trim|xss_clean');

        if ($this->form_validation->run()) {
            $this->session->unset_userdata('upgrade_security');

            $userdata = $this->users->get_spe_userdata($this->input->post('id'), '*', 'nickname');
            $authorized = false;

            // Le username spécifié n'existe pas
            if (empty($userdata)) {
                $this->output->set_content_type('application/json')
                    ->set_status_header(401)
                    ->set_output(json_encode(array('result' => false, 'message' => 'User not found.')));
            }
            // On check le MDP si format MD5 - utilisé pour les comptes avec reset du mot de passe
            else if (empty($userdata->salt)) {
                $authorized = $userdata->pass == md5($this->input->post('pass'));
                $this->session->upgrade_security = true;
            }
            // Classic checking - SHA512 + Salt
            else {
                $to_hash = $userdata->salt . $this->input->post('pass') . $this->config->item('secret_key');
                $authorized = $userdata->pass == hash('sha512', $to_hash);
            }


            if (!$authorized) {
                $this->output->set_content_type('application/json')
                    ->set_status_header(401)
                    ->set_output(json_encode(array('result' => false, 'message' => 'Bad credentials.')));
            } else {
                $sanctions = (array) json_decode($userdata->sanctions);
                if ($sanctions['sanction_5'] > now() || $sanctions['sanction_5'] == 'oo') {
                    if ($sanctions['sanction_5'] == 'oo') {
                        $response['duration'] = 'Jamais';
                    } else {
                        $diff = $sanctions['sanction_5'] - now();
                        $dtF = new \\DateTime('@0');
                        $dtT = new \\DateTime("@$diff");
                        $response = array();
                        $response['duration'] = $dtF->diff($dtT)->format('%a jours, %h heures, %i minutes et %s secondes');
                    }
                    $response['reason_key'] = $this->encrypt($userdata->id);

                    $this->output->set_status_header(403);
                    $this->output->set_content_type('application/json')->set_output(json_encode($response));
                } else {
                    if ($userdata->id == 1680252 && $_SERVER['REMOTE_ADDR'] != '0.0.0.0') {
                        $this->output->set_status_header(403);
                    } else {
                        if ($userdata->is_valid == 1) {
                            $ips_ranges = ['41.102', '41.103', '197.206'];
                            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                            $ip_x = explode('.', $ip);
                            foreach ($ips_ranges as $range) {
                                $x = explode('.', $range);
                                if ($ip_x[0] == $x[0] && $ip_x[1] == $x[1]) {
                                    $data = [
                                        'ip' => $ip,
                                        'user_id' => $userdata->id,
                                        'timestamp' => now()
                                    ];
                                    $this->db->insert('flagged_users', $data);
                                    break;
                                }
                            }

                            if (in_array($userdata->rank, array(1, 2, 3)) && $userdata->download_multiplier == 1) {
                                $this->db->where('id', $userdata->id)->set('download_multiplier', 0)->update('users');
                                $userdata->download_multiplier = 0;
                            }

                            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                            $hash = hash('md5', $ip . $this->config->item('salt_ip'));
                            $qdata = ['ih' => $hash, 'event' => 'login', 'date' => now()];
                            $this->db->insert('sessions', $qdata);

                            $sessiondata = array
                            (
                                'nickname' => $userdata->nickname,
                                'email' => $userdata->email,
                                'can_leech' => $userdata->can_leech,
                                'notifications' => $userdata->notifications,
                                'end_freeleech' => $userdata->end_freeleech,
                                'notified' => $userdata->notified,
                                'passkey' => $userdata->torrent_pass,
                                'rank' => $userdata->rank,
                                'uploaded' => $userdata->uploaded,
                                'downloaded' => $userdata->downloaded,
                                'download_multiplier' => $userdata->download_multiplier,
                                'id' => $userdata->id,
                                'avatar' => $userdata->avatar,
                                'allow_porn' => $userdata->allow_porn,
                                'logged' => true,
                            );
                            $this->session->set_userdata($sessiondata);

                            if ($this->session->upgrade_security) {
                                $this->output->set_content_type('application/json')
                                    ->set_output(json_encode(array('target_url' => base_url() . 'user/upgrade_security')));
                            } else if ($this->session->can_leech == 0) {
                                $this->output->set_content_type('application/json')
                                    ->set_output(json_encode(array('target_url' => base_url() . 'donation/bonus/disabled')));
                            }
                        } else {
                            $this->output->set_status_header(403);
                        }
                    }

                }
            }

        }

    }

    public function reset_password()
    {
        $data['msg'] = '';

        if ($this->input->get('action', true) == 'proceed') {

            $token = $this->input->get('token', true);
            $data['tok'] = $token;
            if ($this->cache->redis->get('token_reset:' . $token)) {

                $user_id = $this->cache->redis->get('token_reset:' . $token);
                $data['nickname'] = $this->db->select('nickname')->where('id', $user_id)->get('users')->row()->nickname;

                if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                    $this->form_validation->set_rules('pass', '<strong>nouveau mot de passe</strong>', 'required|min_length[5]|max_length[40]|trim|xss_clean');
                    $this->form_validation->set_rules('passc', '<strong>confirmation nouveau mdp</strong>', 'required|min_length[5]|max_length[40]|matches[pass]|trim|xss_clean');

                    if ($this->form_validation->run()) {
                        $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));
                        $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');
                        $data_account['pass'] = hash('sha512', $to_hash);
                        $data_account['is_valid'] = 1;
                        $this->db->where('id', $user_id)->update('users', $data_account);
                        $this->cache->redis->delete('token_reset:' . $token);
                        $data['hide_form'] = true;
                        $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>';
                    }

                    $error_validation = array_values($this->form_validation->error_array())[0];
                    if (!empty($error_validation)) {
                        $error = $error_validation;
                    }

                    if (isset($error)) {
                        $data['msg'] = '<div class="alert alert-danger">' . $error . '</div>';
                    }
                }

                $this->load->view('user/reset_pass_action', $data);
            } else {
                echo '<h2>Erreur</h2>';
                echo '<p>Token de réinitialisation de compte expiré ou invalide.</p>';
            }

        }
    }

    public function confirm_account()
    {
        $token = $this->input->get('token', true);
        $userdata = $this->db->where('is_valid', 0)->where('token_validation', $token)->get('users')->row();
        if (isset($userdata->id)) {
            $this->db->where('id', $userdata->id)->update('users', array('is_valid' => 1, 'token_validation' => null));

            // IP log
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            $hash = hash('md5', $ip . $this->config->item('salt_ip'));
            $qdata = ['ih' => $hash, 'event' => 'account_confirmation', 'date' => now()];
            $this->db->insert('sessions', $qdata);

            $this->session->unset_userdata('upgrade_security');
            $sessiondata = array
            (
                'nickname' => $userdata->nickname,
                'email' => $userdata->email,
                'notifications' => $userdata->notifications,
                'end_freeleech' => $userdata->end_freeleech,
                'notified' => $userdata->notified,
                'passkey' => $userdata->torrent_pass,
                'rank' => $userdata->rank,
                'uploaded' => $userdata->uploaded,
                'downloaded' => $userdata->downloaded,
                'download_multiplier' => $userdata->download_multiplier,
                'id' => $userdata->id,
                'avatar' => $userdata->avatar,
                'allow_porn' => $userdata->allow_porn,
                'logged' => true,
                'join_date' => $userdata->join_date,
            );
            $this->session->set_userdata($sessiondata);
            $this->session->set_flashdata('account_created', $userdata->nickname);
            redirect('/');
        } else {
            echo '<h2>Erreur</h2>';
            echo '<p>Token de confirmation de compte expiré ou invalide.</p>';
        }

    }

    public function ajax_usermenu()
    {
        $this->load->helper('minify');
        $html = minify_html($this->load->view('extra/usermenu.php', '', true));
        $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $html, 'nickname' => $this->session->nickname)));
    }

    public function upgrade_security()
    {
        if ($this->session->logged && $this->session->upgrade_security == true) {
            $this->form_validation->set_rules('oldpass', '<strong>mot de passe actuel</strong>', 'required|trim|min_length[5]|max_length[40]|xss_clean');
            $this->form_validation->set_rules('pass', '<strong>nouveau mot de passe</strong>', 'required|trim|min_length[5]|max_length[40]|differs[oldpass]|xss_clean');
            $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');
            if ($this->form_validation->run()) {
                $current_pass_md5 = $this->db->where('id', $this->session->id)->select('pass')->get('users')->row()->pass;
                if ($current_pass_md5 != md5($this->input->post('oldpass'))) {
                    $data['message'] = '<div class="alert alert-danger"><strong>Mot de passe actuel</strong> incorrect</div>';
                } else {
                    $data_account['salt'] = hash('sha512', uniqid(mt_rand(), true));
                    $to_hash = $data_account['salt'] . $this->input->post('pass') . $this->config->item('secret_key');
                    $data_account['pass'] = hash('sha512', $to_hash);
                    $this->db->where('id', $this->session->id)->update('users', $data_account);
                    $this->session->unset_userdata('upgrade_security');
                    $alert_msg = '<div class="alert alert-success">Super ! Votre mot de passe a été mis à jour ! </div>';
                    $this->session->set_flashdata('msg', $alert_msg);
                    redirect('user/account', 'refresh');
                }
            }
            $error_validation = array_values($this->form_validation->error_array())[0];

            if (!empty($error_validation)) {
                $data['message'] = '<div class="alert alert-danger">' . $error_validation . '</div>';
            }

            $this->load->view('user/upgrade_security', $data);
        } else {
            redirect(base_url());
        }

    }

    public function logout()
    {
        $this->session->sess_destroy();
        redirect(site_url(), 'refresh');
    }

    public function report()
    {
        $this->form_validation->set_rules('reason', '<strong>raison du signalement</strong>', 'trim|xss_clean|max_length[250]|min_length[15]|required');
        $this->form_validation->set_rules('target', '<strong>objet du signalement</strong>', 'trim|xss_clean|integer|required');
        $this->form_validation->set_rules('type', '<strong>type du signalement</strong>', 'trim|xss_clean|integer|in_list[1,2,3]|required');
        if ($this->form_validation->run()) {
            $sanctions = (array) json_decode($this->session->sanctions);
            if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {
                $error = 'Impossible de poster de nouveaux signalements';
            } else {
                $hcaptcha_data = array(
                    'secret' => '0x2B8C9E0705c3b48501Eb3d817d39D3C95A9AE0aA',
                    'response' => $_POST['h-captcha-response']
                );
                $verify = curl_init();
                curl_setopt($verify, CURLOPT_URL, 'https://hcaptcha.com/siteverify');
                curl_setopt($verify, CURLOPT_POST, true);
                curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($hcaptcha_data));
                curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
                $response_hcaptcha = curl_exec($verify);
                $responseData = json_decode($response_hcaptcha);

                if (!$responseData->success) {
                    $error = 'le captcha est invalide';
                } else {
                    $report = array(
                        'reason' => $this->input->post('reason'),
                        'target' => $this->input->post('target'),
                        'type' => $this->input->post('type'),
                        'guid' => $this->session->id,
                        'date' => now(),
                    );
                    $this->db->insert('reports', $report);
                }
            }
        }
        $error_validation = array_values($this->form_validation->error_array())[0];
        if (!empty($error_validation)) {
            $error = $error_validation;
        }

        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }
    }

    public function add_note_comment()
    {
        $this->form_validation->set_rules('comment', '<strong>commentaire note</strong>', 'required|min_length[10]|max_length[500]|xss_clean');
        $this->form_validation->set_rules('target', '<strong>note id</strong>', 'required|integer|xss_clean');

        if ($this->form_validation->run()) {
            $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;
            if ($u == $this->session->id || in_array($this->session->rank, array(1, 2, 3))) {
                $note_comment_data = array
                (
                    'guid' => $this->input->post('target'),
                    'publisher' => $this->session->id,
                    'publish_date' => now(),
                    'comment' => $this->input->post('comment'),
                );
                if ($u == $this->session->id) {
                    $note_comment_data['is_staff'] = 0;
                    $this->db->query('UPDATE actions_staff SET is_open = 1 WHERE id = ' . $note_comment_data['guid'] . ' ');

                } else {
                    $note_comment_data['is_staff'] = 1;
                    $this->db->query('UPDATE actions_staff SET is_open = 0 WHERE id = ' . $note_comment_data['guid'] . ' ');
                }
                $this->db->insert('notes_comments', $note_comment_data);
                $this->db->query('UPDATE actions_staff SET comments_count = `comments_count`  + 1 WHERE id = ' . $note_comment_data['guid'] . ' ');
            } else {
                $error = 'Accès refusé';
            }
        }
        $error_validation = array_values($this->form_validation->error_array())[0];
        if (!empty($error_validation)) {
            $error = $error_validation;
        }
        if (!empty($error)) {
            $this->output->set_status_header(403);
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
        }
    }

    public function edit_torrent_cat()
    {
        $sanctions = (array) json_decode($this->session->sanctions);
        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {
            $this->output->set_status_header(401);
        } else {
            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                $id = $this->input->post('torrent_id', true);
                $torrent = $this->db->where('id', $id)->get('torrents')->row();
                $torrent_owner = $torrent->uploader;
                if ($torrent_owner != $this->session->id) {
                    $this->output->set_status_header(401);
                    exit();
                } else {
                    $category = $this->input->post('switch_to_cat', true);
                    $parent = @$this->db->where('id', $category)->get('categories')->row()->parent;
                    if ($torrent->state == 3) {
                        $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => 'Impossible d\\'éditer un torrent qui a été supprimé !')));
                        $this->output->set_status_header(403);
                    } else if (!($parent > 0)) {
                        $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => 'Catégorie invalide')));
                        $this->output->set_status_header(403);
                    } else {
                        $data = array(
                            'tags' => null,
                            'options' => null,
                            'parent_category' => $parent,
                            'category' => $category
                        );
                        if (in_array($parent, [2141, 2142, 2143, 2144])) {
                            $data['state'] = 1;
                        }
                        $this->db->where('id', $id)->update('torrents', $data);
                        $this->session->set_flashdata('cat_updated', true);
                    }
                }
            }
        }
    }

    public function remove_saved_torrent()
    {
        $torrent_id = $this->input->get('id', true);
        $favourites = $this->db->where('id', $this->session->id)->get('users')->row()->favourites;
        $favourites = json_decode($favourites);
        if (!in_array($torrent_id, $favourites)) {
            $error = 'Ce torrent n\\'est pas dans vos favoris';
        } else {
            $key = array_search($torrent_id, $favourites);
            unset($favourites[$key]);
            $favourites = json_encode(array_values($favourites));
            $this->users->update_favourites($this->session->id, $favourites);
        }
        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(401);
        }
    }

    public function saved_torrents()
    {
        $favourites = $this->db->select('favourites')->where('id', $this->session->id)->get('users')->row()->favourites;
        $favourites = join('\\',\\'', json_decode($favourites));
        $data['torrents'] = $this->torrents->get_from_ids($favourites);
        $this->load->view('user/favourites', $data);
    }

    public function downloads($action = '')
    {
        $downloads = $this->db->select('downloads')->where('id', $this->session->id)->get('users')->row()->downloads;
        $downloads = json_decode($downloads);
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($action) && $action != '') {
            if ($action == 'delete') {
                $items = array();
                $downloads = get_object_vars($downloads);
                foreach ($this->input->post('items[]') as $item) {
                    if (array_key_exists('torrent_' . $item, $downloads)) {
                        $items['torrent_' . $item] = $downloads['torrent_' . $item];
                    }
                }
                $new_downloads = array_diff($downloads, $items);

                if ($this->db->where('id', $this->session->id)->set('downloads', json_encode($new_downloads))->update('users')) {
                    $json_items_removed = array_values(array_flip($items));
                    $this->output->set_content_type('application/json')
                        ->set_output(json_encode(array('success' => true, 'items_deleted' => $json_items_removed)));
                }
            }
            if ($action == 'delete_history' && count($downloads) > 0) {
                if ($this->db->where('id', $this->session->id)->set('downloads', json_encode([]))->update('users')) {
                    $this->session->set_flashdata('deleted_history', true);
                    $this->output->set_content_type('application/json')
                        ->set_output(json_encode(array('success' => true)));
                }
            }
        } else {
            if (count($downloads) > 0) {
                $torrents_id = array();
                foreach ($downloads as $torrent_key => $download) {
                    $torrents_id[] = str_replace('torrent_', '', $torrent_key);
                }
                $ids = join('\\',\\'', $torrents_id);
                $sql = "SELECT `torrents`.`id` , `torrents`.`name` , `torrents`.`category_slug` FROM `torrents` WHERE `torrents`.`id` IN ('$ids') ORDER BY FIELD (torrents.id,'$ids')";

                $torrents = $this->db->query($sql)->result();
                $downloads = (array) $downloads;
                foreach ($torrents as $torrent) {
                    $torrent->downloaded_date = $downloads['torrent_' . $torrent->id];
                }
                $data['torrents'] = array_reverse($torrents);
            }
            $this->load->view('user/downloads', $data);
        }
    }

    public function save_torrent()
    {
        $torrent_id = $this->input->get('id', true);
        $torrent = $this->torrents->get_torrent($torrent_id);
        if (isset($torrent->id)) {
            $favourites = $this->db->where('id', $this->session->id)->get('users')->row()->favourites;
            $favourites = json_decode($favourites);
            if (count($favourites) >= 200) {
                $error = 'Vous ne pouvez pas ajouter plus de 15 torrents en favoris';
            } else {
                if (in_array($torrent_id, $favourites)) {
                    $error = 'Vous avez déjà ajouter ce torrent à vos favoris';
                } else {
                    if (count($favourites) == 0) {
                        $favourites = array();
                    }
                    $favourites[] = $torrent_id;
                    $favourites = json_encode($favourites);
                    $this->users->update_favourites($this->session->id, $favourites);
                }
            }
        }
        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(401);
        }
    }

    public function edit_torrent($id = '')
    {
        $sanctions = (array) json_decode($this->session->sanctions);
        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {
            $data['forbidden'] = true;
        }

        $data['parent_categories'] = $this->torrents->get_parent_categories();
        $data['torrent'] = $this->db->where('id', $id)->where('uploader', $this->session->id)->get('torrents')->row();
        $data['parent_category'] = $data['torrent']->parent_category;
        $data['category'] = $data['torrent']->category;
        $data['options_decoded'] = json_decode($data['torrent']->options);
        $this->load->view('torrent/edit_torrent', $data);

    }

    public function edit_torrent_action()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $config = array();
            $config['upload_path'] = './files/nfo';
            $config['allowed_types'] = 'nfo';
            $config['max_size'] = 10000000;
            $config['file_name'] = random_string('alnum', 20);
            $this->form_validation->set_rules('name', '"nom"', 'required|min_length[10]|max_length[255]|xss_clean');
            $this->form_validation->set_rules('torrent_description', 'description', 'required|min_length[20]');

            if ($this->form_validation->run()) {
                $sanctions = (array) json_decode($this->session->sanctions);
                if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {
                    $error = 'Impossible d\\'éditer des torrents';
                } else {
                    $id = $this->input->post('torrent_id', true);
                    $torrent = $this->db->where('id', $id)->select('*')->from('torrents')->get()->row();
                    if ($torrent->uploader != $this->session->id) {
                        $this->output->set_status_header(401);
                        exit();
                    } else {
                        if ($torrent->state == 3) {
                            $error = 'Impossible d\\'éditer un torrent qui a été supprimé !';
                        } else {
                            if ($torrent->file_nfo == null || !empty($_FILES['nfo_file']['name'])) {
                                $this->load->library('upload', $config);
                                $this->upload->do_upload('nfo_file');
                                $data_query['file_nfo'] = $this->upload->data()['file_name'];
                                $error_validation_upload = strip_tags($this->upload->display_errors());
                                if (!empty($error_validation_upload)) {
                                    $error = 'Erreur fichier .nfo : ' . $error_validation_upload;
                                }
                            }
                            $fields = $this->db->select('fields')->from('category_fields')->where('guid', $torrent->category)->get()->row()->fields;
                            $fields_id = preg_split('/,/', $fields);
                            $fields = array();
                            foreach ($fields_id as $field) {
                                $fields[] = $this->db->select('*')->from('category_fields_details')->where('id', $field)->get()->row_array();
                            }
                            $parameters = $this->input->post(null, true);
                            foreach ($fields as $key => $field) {
                                $options_name[] = $field['name'];
                            }
                            $options_name_in = array();
                            $tags = array();
                            foreach ($parameters as $op => $val) {
                                if (strpos($op, 'option') !== false) {
                                    $option_libelle = str_replace('option_', '', $op);
                                    $parent_array_key = array_search($option_libelle, array_column($fields, 'name'));
                                    if ($parent_array_key === false) {
                                        $error = 'l\\'option ' . $option_libelle . ' n\\'existe pas';
                                    } else {
                                        $fields_focus_id = preg_split('/,/', $fields[$parent_array_key]['values']);
                                        $fields_count = count($fields_focus_id) + 1;
                                        if ($fields[$parent_array_key]['multiple'] == 0) {
                                            if (!ctype_digit(strval($val)) || !($val >= 1 && $val < $fields_count)) {
                                                $error = 'Erreur avec l\\'option ' . $option_libelle . '';
                                            }
                                            $tags[] = $fields_focus_id[$val - 1];
                                            $options_name_in[] = $option_libelle;
                                        } else if ($fields[$parent_array_key]['multiple'] == 1) {
                                            foreach ($val as $_val) {
                                                if (!ctype_digit(strval($_val)) || !($_val >= 1 && $_val < $fields_count)) {
                                                    $error = 'Erreur avec l\\'option ' . $option_libelle . '';
                                                }
                                                $tags[] = $fields_focus_id[$_val - 1];
                                            }
                                        }
                                        $options[$op] = $val;
                                        $options_name_in[] = $option_libelle;

                                    }
                                }
                            }
                            if ($torrent->is_exclusivity == 1 && $torrent->state == 0) {
                                $error = 'Impossible d\\'éditer une exclusivité qui a le statut : Actif';
                            }
                            // On vérifie si c'est une exclusivité ou pas
                            if (isset($_POST['is_exclusivity']) && $torrent->parent_category == 2145) {
                                $release_date = $this->input->post('release_date');
                                if (empty($release_date) || $release_date == '') {
                                    $error = 'Veuillez sélectionner la date de sortie en DVD';
                                } else {
                                    // On bascule ce film en tout qu'exclusivité si tout est bon
                                    $release_date = DateTime::createFromFormat('d/m/Y', $release_date);
                                    $data_query['release_date'] = $release_date->getTimestamp();
                                    $data_query['is_exclusivity'] = 1;
                                }
                            }
                            // S'il décoche la case on ne le considère plus comme exclusivité
                            else {
                                $data_query['is_exclusivity'] = 0;
                                $data_query['release_date'] = 0;
                            }
                            if (count(array_diff($options_name, $options_name_in)) > 0 && isset($options_name[0])) {
                                $error = 'Veuillez compléter toutes les options';
                            }
                            if (empty($error_validation_upload) && empty($error)) {
                                $data_query['name'] = strip_tags($this->input->post('name', true));

                                // Si le torrent est une exclusivité
                                if ($data_query['is_exclusivity'] == 1 || $this->session->rank == 0) {
                                    $data_query['state'] = 1;
                                }
                                // Initialisation de la variable retour de correction à 0
                                //$data_query['correction_return'] = 0;
                                // Si le torrent a été bloqué 
                                if ($torrent->state == 2) {
                                    $data_query['state'] = 1;
                                    $data_query['correction_request'] = 1;
                                }

                                $data_query['description'] = htmlentities(purify($this->input->post('torrent_description')));
                                $data_query['tags'] = json_encode($tags);
                                $data_query['options'] = json_encode($options, JSON_NUMERIC_CHECK);
                                $this->db->where('id', $id)->update('torrents', $data_query);

                                $this->session->set_flashdata('torrent_updated', now());

                            }
                        }
                    }

                }
            }
            $error_validation = array_values($this->form_validation->error_array())[0];
            if (!empty($error_validation)) {
                $error = $error_validation;
            }

            if (isset($error)) {
                $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
                $this->output->set_status_header(403);
            }
        }
    }

    public function upload_torrent_action()
    {
        // Vérifier ancienneté minimum de 15 jours
        $account_age_days = (now() - $this->session->join_date) / 86400;
        if ($account_age_days < 15) {
            $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')));
            $this->output->set_status_header(403);
            return;
        }

        $current_date = date('d-m-y', now());
        $config['upload_path'] = './files/torrents/' . $current_date;
        $config['allowed_types'] = 'torrent';
        $config['max_size'] = 10000000;
        $config['file_name'] = random_string('alnum', 30);
        if (!is_dir($config['upload_path'])) {
            mkdir($config['upload_path'], 0777, true);
        }

        $this->load->library('upload', $config, 'torrent_upload');
        $this->torrent_upload->initialize($config);
        $torrent_upload = $this->torrent_upload->do_upload('torrent_file');
        $config = array();
        $config['upload_path'] = './files/nfo';
        $config['allowed_types'] = 'nfo';
        $config['max_size'] = 10000000;
        $config['file_name'] = random_string('alnum', 20);
        $this->load->library('upload', $config, 'nfo_upload');
        $this->nfo_upload->initialize($config);
        $nfo_upload = $this->nfo_upload->do_upload('nfo_file');
        if ($_POST['auto_name'] != 1) {
            $this->form_validation->set_rules('name', '<strong>nom torrent</strong>', 'required|min_length[5]|max_length[255]|xss_clean');
        }

        $this->form_validation->set_rules('category', '<strong>catégorie torrent</strong>', 'required|xss_clean');
        $this->form_validation->set_rules('torrent_description', '<strong>description torrent</strong>', 'required|min_length[20]');
        if ($this->form_validation->run()) {
            $sanctions = (array) json_decode($this->session->sanctions);
            if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {
                $error = 'Impossible d\\'envoyer un torrent';
            } else {
                $pending_torrents = $this->db->where('uploader', $this->session->id)->where('state', 1)->get('torrents')->num_rows();
                if ($pending_torrents >= 3) {
                    $error = 'Vous devez avoir moins de 3 torrents en pending pour uploader un nouveau torrent';
                } else {
                    if ($torrent_upload) {
                        $torrent_file = $this->torrent_upload->data();
                        if ($nfo_upload) {
                            $this->load->library('TorrentParser', array($current_date . '/' . $torrent_file['file_name']));
                            $parser = $this->torrentparser->parser;
                            if ($parser->info['file tree']) {
                                $error = 'Le format du torrent doit être en version BitTorrent V1';
                            } else if (!$parser->is_private()) {
                                $error = 'Vous devez mettre votre torrent en mode privé';
                            } else {

                                if ($_POST['auto_name'] == 1) {
                                    $data_query['name'] = $parser->name();
                                } else {
                                    $data_query['name'] = strip_tags($this->input->post('name', true));
                                }

                                $data_query['hash_info'] = $parser->hash_info();
                                $is_exists = $this->db->where('hash_info', $data_query['hash_info'])->get('torrents')->num_rows() == 1;
                                if ($is_exists) {
                                    $error = 'Ce torrent a déjà été uploadé par un autre membre';
                                } else {
                                    $category = $this->input->post('category', true);
                                    $parent = @$this->db->where('id', $category)->get('categories')->row()->parent;
                                    if (!($parent > 0)) {
                                        $error = 'Catégorie invalide';
                                    } else {
                                        $fields = $this->db->select('fields')->from('category_fields')->where('guid', $category)->get()->row()->fields;
                                        $fields_id = preg_split('/,/', $fields);
                                        $fields = array();
                                        foreach ($fields_id as $field) {
                                            $fields[] = $this->db->select('*')->from('category_fields_details')->where('id', $field)->get()->row_array();
                                        }
                                        $parameters = $this->input->post(null, true);
                                        foreach ($fields as $key => $field) {
                                            $options_name[] = $field['name'];
                                        }
                                        $options_name_in = array();
                                        $tags = array();
                                        foreach ($parameters as $op => $val) {
                                            if (strpos($op, 'option') !== false) {
                                                $option_libelle = str_replace('option_', '', $op);
                                                $parent_array_key = array_search($option_libelle, array_column($fields, 'name'));
                                                if ($parent_array_key === false) {
                                                    $error = 'l\\'option ' . $option_libelle . ' n\\'existe pas';
                                                } else {
                                                    $fields_focus_id = preg_split('/,/', $fields[$parent_array_key]['values']);
                                                    $fields_count = count($fields_focus_id) + 1;
                                                    if ($fields[$parent_array_key]['multiple'] == 0) {
                                                        if (!ctype_digit(strval($val)) || !($val >= 1 && $val < $fields_count)) {
                                                            $error = 'Erreur avec l\\'option ' . $option_libelle . '';
                                                        }
                                                        $tags[] = $fields_focus_id[$val - 1];
                                                        $options_name_in[] = $option_libelle;
                                                    } else if ($fields[$parent_array_key]['multiple'] == 1) {
                                                        foreach ($val as $_val) {
                                                            if (!ctype_digit(strval($_val)) || !($_val >= 1 && $_val < $fields_count)) {
                                                                $error = 'Erreur avec l\\'option ' . $option_libelle . '';
                                                            }
                                                            $tags[] = $fields_focus_id[$_val - 1];
                                                        }
                                                    }
                                                    $options[$op] = $val;
                                                    $options_name_in[] = $option_libelle;

                                                }
                                            }
                                        }
                                        // On vérifie si c'est une exclusivité ou pas
                                        if (isset($_POST['is_exclusivity']) && $parent == 2145) {
                                            $release_date = $this->input->post('release_date');
                                            if (empty($release_date) || $release_date == '') {
                                                $error = 'Veuillez sélectionner la date de sortie en DVD';
                                            } else {
                                                // On bascule ce film en tout qu'exclusivité si tout est bon
                                                $release_date = DateTime::createFromFormat('d/m/Y', $release_date);
                                                $data_query['release_date'] = $release_date->getTimestamp();
                                                $data_query['is_exclusivity'] = 1;
                                            }

                                        }
                                        if (count(array_diff($options_name, $options_name_in)) > 0 && isset($options_name[0])) {
                                            $error = 'Veuillez compléter toutes les options';
                                        }
                                        $files = $parser->content();

                                        if (in_array($parent, [2141, 2142, 2143, 2144])) {
                                            $ext_list = $this->config->item('ext_prohibited');
                                        } else {
                                            $ext_list = $this->config->item('ext_prohibited_full');
                                        }

                                        foreach ($files as $file => $length) {
                                            $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
                                            if (in_array($ext, $ext_list)) {
                                                $error = 'Impossible d\\'envoyer ce torrent qui contient un fichier .' . $ext . '';
                                            }
                                        }

                                        if (empty($error)) {
                                            //$this->output->enable_profiler();
                                            $current_timestamp = now();
                                            $sql = 'INSERT INTO xbt_files (info_hash, mtime, ctime) VALUES (0x' . $data_query['hash_info'] . ', ' . $current_timestamp . ', ' . $current_timestamp . ')';
                                            $this->db->query($sql);

                                            $data_query['category_slug'] = $this->torrents->generate_category_slug($category);
                                            $data_query['tags'] = json_encode($tags);
                                            $data_query['options'] = json_encode($options, JSON_NUMERIC_CHECK);
                                            $data_query['age'] = $parser->creation_date();
                                            $data_query['uploader'] = $this->session->id;
                                            $data_query['trackers'] = json_encode($parser->announce());
                                            $data_query['files'] = json_encode($files);
                                            $data_query['magnet'] = $parser->magnet();
                                            $data_query['parent_category'] = $parent;
                                            $data_query['category'] = $category;
                                            $data_query['publish_date'] = now();

                                            if ($this->session->rank == 0 || $data_query['is_exclusivity'] == 1 || in_array($parent, [2141, 2142, 2143, 2144, 2300, 2200])) {
                                                $data_query['state'] = 1;
                                            }
                                            $data_query['file_key'] = $torrent_file['file_name'];
                                            $data_query['file_nfo'] = $this->nfo_upload->data()['file_name'];
                                            $data_query['size'] = $parser->size();
                                            $data_query['description'] = htmlentities(purify($_POST['torrent_description']));

                                            $this->db->insert('torrents', $data_query);

                                            $download_link = base_url('engine/download_torrent?id=' . $this->db->insert_id());
                                            $this->output->set_content_type('application/json')->set_output(json_encode(array('download_link' => $download_link)));

                                            // $this->session->set_flashdata('torrent_uploaded', $this->db->insert_id());
                                        }

                                    }
                                }

                            }

                        } else {
                            $error_validation_upload = strip_tags($this->nfo_upload->display_errors());
                            if (!empty($error_validation_upload)) {
                                $error = 'Erreur fichier <u>.nfo</u> : ' . $error_validation_upload;
                            }

                        }

                    } else {
                        $error_validation_upload = strip_tags($this->torrent_upload->display_errors());
                        if (!empty($error_validation_upload)) {
                            $error = 'Erreur fichier <u>.torrent</u> : ' . $error_validation_upload;
                        }

                    }
                }

            }
        }
        $error_validation = array_values($this->form_validation->error_array())[0];
        if (!empty($error_validation)) {
            $error = $error_validation;
        }

        if (isset($error)) {
            unlink($this->nfo_upload->data()['full_path']);
            unlink($this->torrent_upload->data()['full_path']);
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }
    }

    public function upload_torrent()
    {
        $data['forbidden'] = false;
        $data['too_young'] = false;
        
        // Vérifier ancienneté minimum de 15 jours
        $account_age_days = (now() - $this->session->join_date) / 86400;
        if ($account_age_days < 15) {
            $data['too_young'] = true;
            $data['days_remaining'] = ceil(15 - $account_age_days);
        }
        
        $sanctions = (array) json_decode($this->session->sanctions);
        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {
            $data['forbidden'] = true;
        }

        if ($this->session->settings['enable_at_content'] == false) {
            $data['parent_categories'] = $this->torrents->get_parent_categories_noadult();
        } else {
            $data['parent_categories'] = $this->torrents->get_parent_categories();
        }

        $this->load->view('torrent/upload_torrent_step2', $data);
    }

    public function my_torrents()
    {
        ini_set('memory_limit', '-1');

        $data['message'] = '';
        if ($this->session->flashdata('torrent_uploaded')) {
            $data['message'] = '<div class="alert alert-success">Votre torrent a bien été uploadé sur notre serveur</div>';
        } else if ($this->session->flashdata('torrent_updated')) {
            $data['message'] = '<div class="alert alert-success">Votre torrent a bien été mis à jour</div>';
        }
        $pagination_config = $this->_get_pagination_config();
        $pagination_config['per_page'] = 50;
        $pagination_config['total_rows'] = $this->db->select('id')->where('uploader', $this->session->id)->get('torrents')->num_rows();
        // $this->pagination->initialize($pagination_config);
        $data['torrents'] = $this->users->get_torrents($pagination_config['per_page'], $this->input->get('page', true));

        $this->pagination->initialize($pagination_config);

        $this->load->view('torrent/my_torrents', $data);
    }

    public function remove_torrent()
    {
        $sanctions = (array) json_decode($this->session->sanctions);
        if (array_key_exists('sanction_4', $sanctions) && ($sanctions['sanction_4'] > now() || $sanctions['sanction_4'] == 'oo')) {
            $this->output->set_status_header(401);
        } else {
            $id = $this->input->post('id');
            $torrent = $this->db->where('id', $id)->where('uploader', $this->session->id)->get('torrents')->row();
            if (count($torrent) > 0) {
                if ($torrent->seed == 0 || now() - $torrent->publish_date < 86400) {
                    $this->db->where('id', $torrent->id)->delete('torrents');
                } else {
                    $this->db->set('uploader', 1698928)->set('state', 3)->where('id', $torrent->id)->update('torrents');
                }
            } else {
                $this->output->set_status_header(401);
            }
        }
    }

    /* Comments */
    public function add_comment()
    {
        $joined = $this->db->select('join_date')->where('id', $this->session->id)->get('users')->row()->join_date;

        $json_response = null;
        $id = $this->input->post('torrent_id', true);
        $is_owner = $this->db->where('id', $id)->where('uploader', $this->session->id)->get('torrents')->num_rows() > 0;
        $this->form_validation->set_rules('comment', '<strong>commentaire</strong>', 'required|min_length[10]|max_length[4000]|xss_clean');

        if ($this->form_validation->run()) {
            $sanctions = (array) json_decode($this->session->sanctions);

            $torrent_data = $this->torrents->get_torrent($id);
            $settings = $torrent_data->user_settings;
            $settings = json_decode($settings, JSON_OBJECT_AS_ARRAY);
            $since = now() - $joined;
            if ($settings['restrict_comments'] && $since < 2628000) {
                $error = 'Impossible de poster un commentaire sur ce torrent';
            } else if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {
                $error = 'Impossible de poster de nouveaux commentaires';
            } else {
                // Flood Time Limit
                $last_comment_timestamp = $this->db->select('last_comment_timestamp')->where('id', $this->session->id)->get('users')->row()->last_comment_timestamp;
                $wait = true;
                //$wait < 60
                if ($wait < 60) {
                    $time_left = 60 - $wait;
                    $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';
                } else {
                    $comment = htmlentities(purify($this->input->post('comment')));
                    $publish_date = now();

                    $comment_insert_id = $this->users->add_comment($id, $comment, $publish_date);

                    $this->db->query('UPDATE torrents SET comments_count = `comments_count`  + 1 WHERE ID = ' . $id . ' ');
                    $this->db->where('id', $this->session->id)->set('last_comment_timestamp', now())->update('users');

                    // Notify the user
                    if (!$is_owner) {
                        $this->load->library('notify', array('6', array('torrent_id' => $id, 'comment_id' => $comment_insert_id)));
                    }

                    $data['comment'] = array
                    (
                        'id' => $comment_insert_id,
                        'comment' => html_entity_decode($comment),
                        'date' => time_elapsed_string($publish_date),
                        'publish_date_readable' => date('d/m/Y', $publish_date),
                        'publish_time_readable' => date('H:i:s', $publish_date),
                        'publish_date_timestamp' => $publish_date,
                        'publisher' => ucfirst($publisher_data->nickname),
                        'publisher_id' => $publisher_data->id,
                        'publisher_avatar' => $publisher_data->avatar,
                    );

                    $this->load->helper('minify');
                    $html = minify_html($this->load->view('extra/comment', $data, true));

                    $this->output->set_content_type('application/json')->set_output(json_encode(array('html' => $html)));
                }
            }
        }

        $error_validation = array_values($this->form_validation->error_array())[0];

        if (!empty($error_validation)) {
            $error = $error_validation;
        }

        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }
    }

    public function remove_comment()
    {
        $comment_id = $this->input->get('id', true);
        if (isset($comment_id)) {
            $sanctions = (array) json_decode($this->session->sanctions);
            if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {
                $error = 'Impossible de supprimer des commentaires';
            } else {
                $comment = $this->db->where('id', $comment_id)->select('publisher, guid')->from('comments')->get()->row();

                if ($comment->publisher == $this->session->id || in_array($this->session->rank, array(1, 2))) {
                    $this->db->where('id', $comment_id)->delete('comments');
                    $this->db->where('id', $guid)->set('comments_count', 'comments_count-1', false)->update('torrents');
                } else {
                    $error = 'le commentaire que vous tentez de supprimer ne vous appartient pas';
                }
            }
        }
        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }
    }

    public function edit_comment()
    {
        $comment_id = $this->input->post('id', true);
        $this->form_validation->set_rules('comment', '<strong>commentaire</strong>', 'required|min_length[10]|max_length[2000]|xss_clean');

        if ($this->form_validation->run()) {
            $sanctions = (array) json_decode($this->session->sanctions);
            if (array_key_exists('sanction_3', $sanctions) && ($sanctions['sanction_3'] > now() || $sanctions['sanction_3'] == 'oo')) {
                $error = 'Impossible d\\'éditer des commentaires';
            } else {
                $comment_guid = $this->db->where('id', $comment_id)->from('comments')->get()->row()->publisher;

                if ($comment_guid == $this->session->id || in_array($this->session->rank, array(1, 2))) {
                    $comment = htmlentities(purify($this->input->post('comment')));
                    $this->db->where('id', $comment_id)->set('last_edit_date', now())->set('comment', $comment)->update('comments');
                } else {
                    $error = 'Le commentaire que vous voulez supprimer ne vous appartient pas';
                }
            }
        }

        $error_validation = array_values($this->form_validation->error_array())[0];

        if (!empty($error_validation)) {
            $error = $error_validation;
        }

        if (isset($error)) {
            $this->output->set_content_type('application/json')->set_output(json_encode(array('error' => $error)));
            $this->output->set_status_header(403);
        }
    }

}
