<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Support\Facades\Log;

use App\Http\Controllers\AuthController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\PermissionController; // Remove permission controller soon.

class BoardController extends Controller {
  private $objAuth;
  private $objUser;
  private $objPermission;

  public function __construct() {
    $this->objAuth = new AuthController();
    $this->objUser = new UserController();
    $this->objPermission = new PermissionController();
  }

  public function getCategories() { // /api/rpc/board/category/getcategories
    return DB::table('for_category')
      ->select('*')
      ->orderBy('order', 'asc')
      ->get();
  }

  public function getCategory($id) { // /api/rpc/board/category/getcategory/id
    return DB::table('for_category')
      ->select('*')
      ->where('id', $id)
      ->get();
  }

  public function getCategoryName($id) { // /api/rpc/board/category/getcategoryname/id
    return DB::table('for_category')
      ->select('title')
      ->where('id', $id)
      ->get();
  }

  public function checkRead($for, $top, $kero_token) {
    $check = $this->objAuth->checkLegit($kero_token);

    if ($check == 0) {
      $yetToRead = false;
    }
    else {
      $valid = $this->objAuth->getPermissions($kero_token);
      $yetToRead = false;

      if ($valid['for_canview']) {
        $isRead = array();

        if ($for != 0) {
          $isRead = DB::table('for_threads')
            ->select('id')
            ->where('for_id', $for)
            ->get();
        }
        else {
          $isRead[] = array('id' => $top);
        }
        
        foreach ($isRead as $read) {
          $rid = 0;
          
          if ($for != 0) {
            $rid = $read->id;
          }
          else {
            $rid = $read['id'];
          }

          $get = DB::table('for_read')
            ->join('for_posts', 'for_posts.top_id', 'for_read.top_id')
            ->where('for_read.user_id', $check)
            ->where('for_read.top_id', $rid)
            ->get(array(
              'for_posts.id',
              'for_posts.user_id',
              'for_posts.top_id',
              'for_posts.post_date',
              'for_read.view_time',
            ));

          if (!$get->count()) {
            $yetToRead = true;
          }
          else {
            foreach($get as $g) {
              if ($g->post_date > $g->view_time) {
                $yetToRead = true;
              }
            }
          }
        }
      }
    }

    return $yetToRead;
  }

  public function markReadAll (Request $r) {
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Guests can\'t read';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_canview']) {
        $tid = DB::table('for_threads')
          ->select('id')
          ->get();

        foreach ($tid as $t) {
          $chk = DB::table('for_read')
            ->where('user_id', $check)
            ->where('top_id', $t->id)
            ->count();

          if ($chk) {
            $r->top_id = $t->id;
            $this->readTopic($r);
          }
          else {
            $getPost = DB::table('for_posts')
              ->select('post_date')
              ->where('top_id', $t->id)
              ->orderBy('post_date', 'desc')
              ->limit(1)
              ->first();

            DB::table('for_read')
              ->insert([
                'user_id' => $check,
                'top_id' => $t->id,
                'view_time' => $getPost->post_date
              ]);
          }
        }

        return 'Done.';
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function markReadCat (Request $r) {
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Guests can\'t read';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_canview']) {
        $fid = DB::table('for_forums')
          ->select('id')
          ->where('cat_id', $r->cat_id)
          ->get();

        foreach ($fid as $f) {
          $tid = DB::table('for_threads')
            ->select('id')
            ->where('for_id', $f->id)
            ->get();

          foreach ($tid as $t) {
            $chk = DB::table('for_read')
              ->where('user_id', $check)
              ->where('top_id', $t->id)
              ->count();

            if ($chk) {
              $r->top_id = $t->id;
              $this->readTopic($r);
            }
            else {
              $getPost = DB::table('for_posts')
                ->select('post_date')
                ->where('top_id', $t->id)
                ->orderBy('post_date', 'desc')
                ->limit(1)
                ->first();

              DB::table('for_read')
                ->insert([
                  'user_id' => $check,
                  'top_id' => $t->id,
                  'view_time' => $getPost->post_date
                ]);
            }
          }
        }

        return 'Done.';
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function markRead (Request $r) {
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Guests can\'t read';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_canview']) {
        $tid = DB::table('for_threads')
          ->select('id')
          ->where('for_id', $r->for_id)
          ->get();

        foreach ($tid as $t) {
          $chk = DB::table('for_read')
            ->where('user_id', $check)
            ->where('top_id', $t->id)
            ->count();

          if ($chk) {
            $r->top_id = $t->id;
            $this->readTopic($r);
          }
          else {
            $getPost = DB::table('for_posts')
              ->select('post_date')
              ->where('top_id', $t->id)
              ->orderBy('post_date', 'desc')
              ->limit(1)
              ->first();

            DB::table('for_read')
              ->insert([
                'user_id' => $check,
                'top_id' => $t->id,
                'view_time' => $getPost->post_date
              ]);
          }
        }

        return 'Done.';
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function readTopic(Request $r) { // /api/rpc/board/topic/read
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Guests can\'t read';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_canview']) {
        $getRead = DB::table('for_read')
          ->select('view_time')
          ->where('user_id', $check)
          ->where('top_id', $r->top_id)
          ->first();

        $getPost = DB::table('for_posts')
          ->select('post_date')
          ->where('top_id', $r->top_id)
          ->orderBy('post_date', 'desc')
          ->limit(1)
          ->first();

        if ($getRead->view_time < $getPost->post_date) {
          DB::table('for_read')
            ->where('user_id', $check)
            ->where('top_id', $r->top_id)
            ->update([
              'view_time' => $getPost->post_date
            ]);

          return 'Read.';
        }

        return '';
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function addCategory(Request $r) { // /api/rpc/board/category/add
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_catmod'] == 1) {
        $add = DB::table('for_category')
          ->insertGetId([
            'title' => $r->title,
            'order' => $r->order
          ]);

        return $add;
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function editCategory(Request $r) { // /api/rpc/board/category/edit
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_catmod'] == 1) {
        return DB::table('for_category')
          ->where('id', $r->id)
          ->update([
            'id' => $r->id,
            'title' => $r->title
          ]);
      }
    }
  }

  public function deleteCategory(Request $r) { // /api/rpc/board/category/delete
    $check = $this->objAuth->checkLegit($r->kero_token);
    
    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_catmod'] == 1) {
        return DB::table('for_category')->where('id', $r->id)->delete();
      }
    }
  }

  public function getForums($id) { // /api/rpc/board/forum/getforums/id
    if ($id == 0) {
      $get = DB::table('for_forums')
        ->select('id', 'last_uid', 'cat_id', 'title', 'description', 'threads', 'posts', 'last_date')
        ->orderBy('order', 'asc')
        ->get();
    }
    else {
      $get = DB::table('for_forums')
        ->select('id', 'last_uid', 'cat_id', 'title', 'description', 'threads', 'posts', 'last_date')
        ->where('cat_id', $id)
        ->orderBy('order', 'asc')
        ->get();
    }

    $res = array();
    $key = 0;
    setlocale(LC_ALL, 'ja_JP.utf8');

    foreach ($get as $i) {
      array_push($res, [
        'key' => $key,
        'id' => $i->id,
        'last_uid' => $i->last_uid,
        'cat_id' => $i->cat_id,
        'title' => $i->title,
        'description' => $i->description,
        'threads' => $i->threads,
        'posts' => $i->posts,
        'last_date' => strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $i->last_date)
      ]);
      $key++;
    }

    return $res;
  }

  public function getForum($id) { // /api/rpc/board/forum/getforum/id
    return DB::table('for_forums')
      ->select('*')
      ->where('id', $id)
      ->orderBy('order', 'asc')
      ->get();
  }

  public function addForum(Request $r) { // /api/rpc/board/forum/add
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_formod'] == 1) {
        $add = DB::table('for_forums')
          ->insertGetId([
            'last_uid' => 0,
            'cat_id' => $r->cat_id,
            'title' => $r->title,
            'description' => $r->description,
            'threads' => 0,
            'posts' => 0,
            'last_date' => 0,
            'min_power' => 0,
            'permission' => 0,
            'readonly' => $r->ro,
            'post_count_freeze' => $r->pcf,
            'order' => $r->order,
            'parent' => 0
          ]);

        return $add;
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function editForum(Request $r) { // /api/rpc/board/forum/edit
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_formod'] == 1) {
        return DB::table('for_forums')
          ->where('id', $r->id)
          ->update([
            'cat_id' => $r->cat_id,
            'title' => $r->title,
            'description' => $r->description,
            'readonly' => $r->ro,
            'post_count_freeze' => $r->pcf
          ]);
      }
    }
  }

  public function deleteForum(Request $r) { // /api/rpc/board/forum/delete
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_formod'] == 1) {
        return DB::table('for_forums')->where('id', $r->id)->delete();
      }
    }
  }

  public function getForumIdFromTopic($id) { // /api/rpc/board/topic/getforumidfromtopic/id
    return DB::table('for_threads')
      ->select('for_id')
      ->where('id', $id)
      ->first()->for_id;
  }

  public function getTopicIdFromPost($id) { // /api/rpc/board/post/gettopicidfrompost/id
    return DB::table('for_posts')
      ->select('top_id')
      ->where('id', $id)
      ->first()->top_id;
  }

  public function getForumIdFromPost($id) { // /api/rpc/board/post/getforumidfrompost/id
    $top_id = $this->getTopicIdFromPost($id);

    return $this->getForumIdFromTopic($top_id);
  }

  public function getForumName($id) { // /api/rpc/board/forum/getforumname/id
    return DB::table('for_forums')
      ->select('cat_id', 'title', 'description')
      ->where('id', $id)
      ->orderBy('order', 'asc')
      ->get();
  }

  public function getPostCountFreeze($id) { // /api/rpc/board/forum/getpostcountfreeze/id
    return DB::table('for_forums')
      ->select('post_count_freeze')
      ->where('id', $id)
      ->first()->post_count_freeze;
  }

  public function getReadOnly($id) { // /api/rpc/board/forum/getreadonly/id
    return DB::table('for_forums')
      ->select('readonly')
      ->where('id', $id)
      ->first()->readonly;
  }

  public function getForumsInCategory($cat_id) { // /api/rpc/board/forum/getforumsincategory/cat_id
    $get = DB::table('for_forums')
      ->select('id', 'last_uid', 'cat_id', 'title', 'description', 'threads', 'posts', 'last_date')
      ->where('cat_id', $cat_id)
      ->orderBy('order', 'asc')
      ->get();

    $res = array();
    $key = 0;

    setlocale(LC_ALL, 'ja_JP.utf8');

    foreach ($get as $i) {
      array_push($res, [
        'key' => $key,
        'id' => $i->id,
        'last_uid' => $i->last_uid,
        'cat_id' => $i->cat_id,
        'title' => $i->title,
        'description' => $i->description,
        'threads' => $i->threads,
        'posts' => $i->posts,
        'last_date' => strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $i->last_date)
      ]);
      $key++;
    }

    return $res;
  }

  public function getTopics($for, $from, $to) { // /api/rpc/board/topic/gettopics/for/from/to
    return DB::table('for_threads')
      ->select('*')
      ->where('for_id', $for)
      ->offset($from)
      ->limit($to)
      ->orderBy('last_date', 'desc')
      ->get();
  }

  public function getTopicsUnpinned($for, $from, $to) { // /api/rpc/board/topic/gettopicsunpinned/for/from/to
    return DB::table('for_threads')
      ->select('*')
      ->where('for_id', $for)
      ->where('sticky', 0)
      ->offset($from)
      ->limit($to)
      ->orderBy('last_date', 'desc')
      ->get();
  }

  public function getTopicsPinned($for, $from, $to) { // /api/rpc/board/topic/gettopicspinned/for/from/to
    return DB::table('for_threads')
      ->select('*')
      ->where('for_id', $for)
      ->where('sticky', 1)
      ->orderBy('last_date', 'desc')
      ->get();
  }

  public function getTopicsUser($user, $from, $to) { // /api/rpc/board/topic/gettopicsuser/user/from/to
    return DB::table('for_threads')
      ->select('*')
      ->where('started_by', $user)
      ->orderBy('last_date', 'desc')
      ->get();
  }

  public function getTopicStart($top_id) { // /api/rpc/board/post/gettopicstart/top_id
    $uid = DB::table('for_posts')
      ->where('top_id', $top_id)
      ->orderBy('post_date', 'asc')
      ->value('user_id');

    $pdt = DB::table('for_posts')
      ->where('top_id', $top_id)
      ->orderBy('post_date', 'asc')
      ->value('post_date');

    return array(
      'uid' => $uid,
      'date' => $pdt
    );
  }

  public function getLastPost($top_id) { // /api/rpc/board/post/getlastpost/top_id
    $uid = DB::table('for_posts')
      ->where('top_id', $top_id)
      ->orderBy('post_date', 'desc')
      ->value('user_id');

    $pdt = DB::table('for_posts')
      ->where('top_id', $top_id)
      ->orderBy('post_date', 'desc')
      ->value('post_date');

    return array(
      'uid' => $uid,
      'date' => $pdt
    );
  }

  public function getLastPostOfForum($for_id) {
    setlocale(LC_ALL, 'ja_JP.utf8');

    $tid = DB::table('for_threads')
      ->join('for_posts', 'for_posts.top_id', 'for_threads.id')
      ->where('for_id', $for_id)
      ->orderBy('for_posts.post_date', 'desc')
      ->first(array(
        'for_threads.id as tid',
        'for_posts.user_id as uid',
        'for_posts.post_date as date'
      ));

    return array(
      'tid' => ($tid ? $tid->tid : 0),
      'uid' => ($tid ? $tid->uid : 0),
      'date' => ($tid ? strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $tid->date) : 'まだ')
    );
  }

  public function getFirstAndLastPosts($top_id) { // /api/rpc/board/post/getfirstandlastposts/top_id
    $first = $this->getTopicStart($top_id);
    $last = $this->getLastPost($top_id);

    return array(
      'first' => $first,
      'last' => $last
    );
  }

  public function countUnpinnedTopicsInForum($for_id) { // /api/rpc/board/topic/countunpinnedtopicsinforum/for_id
    return DB::table('for_threads')
      ->where('for_id', $for_id)
      ->where('sticky', 0)
      ->count();
  }

  public function getTopic($id, $from, $to) { // /api/rpc/board/topic/gettopic/id/from/to
    return DB::table('for_threads')
      ->select('*')
      ->where('id', $id)
      ->offset($from)
      ->limit($to)
      ->orderBy('last_date', 'desc')
      ->get();
  }

  public function getTopicLock($id) { // /api/rpc/board/topic/gettopiclock/id
    return DB::table('for_threads')
      ->select('lock')
      ->where('id', $id)
      ->get();
  }

  public function getTopicPin($id) { // /api/rpc/board/topic/gettopicpin/id
    return DB::table('for_threads')
      ->select('sticky')
      ->where('id', $id)
      ->get();
  }

  public function getTopicName($id) { // /api/rpc/board/topic/gettopicname/id
    return DB::table('for_threads')
      ->select('for_id', 'title')
      ->where('id', $id)
      ->get();
  }

  public function getPostsInTopic($top_id, $from, $to) { // /api/rpc/board/post/getpostsintopic/top_id/from/to
    return DB::table('for_posts')
      ->select('*')
      ->where('top_id', $top_id)
      ->offset($from)
      ->limit($to)
      ->orderBy('post_date', 'asc')
      ->get();
  }

  public function countPostsInTopic($top_id) { // /api/rpc/board/post/countpostsintopic/top_id
    return DB::table('for_posts')
      ->where('top_id', $top_id)
      ->count();
  }

  public function getPost($id) { // /api/rpc/board/post/getpost/id
    return DB::table('for_posts')
      ->select('*')
      ->where('id', $id)
      ->get();
  }

  public function getCurrentPostCount($user_id) { // /api/rpc/board/post/getcurrentpostcount/user_id
    return DB::table('for_posts')->where('user_id', $user_id)->max('postcount');
  }

  public function getNextPostCount($user_id) { // /api/rpc/board/post/getnextpostcount/user_id
    $get = DB::table('for_posts')->where('user_id', $user_id)->max('postcount');
    $get++;
    
    return $get;
  }

  public function getPostsofUser($user_id, $from, $to, Request $r) {
    $getting = array(
      'for_posts.id',
      'top_id',
      'for_posts.user_id',
      'post_date',
      'message',
      'delete',
      'lastedit',
      'ipaddress',
      'delreason',
      'nolayout',
      'postcount',
      'username',
      'perm_id',
      'total_posts',
      'header',
      'footer',
      'member_title',
      'gender',
      'avatar',
      'name_style',
      'display_name',
      'country'
    );

    // $valid = $this->objAuth->getPermissions($r->kero_token);

    return DB::table('for_posts')
      ->join('users', 'for_posts.user_id', '=', 'users.id')
      ->join('usr_details', 'usr_details.user_id', '=', 'for_posts.user_id')
      ->join('usr_profile', 'usr_profile.user_id', '=', 'for_posts.user_id')
      ->join('usr_perm_id', 'usr_perm_id.user_id', '=', 'for_posts.user_id')
      ->where('users.id', $user_id)
      ->offset($from)
      ->limit($to)
      ->orderBy('for_posts.post_date', 'asc')
      ->get($getting);
  }

  public function getUserPosts($top_id, $from, $to, Request $r) { // /api/rpc/board/post/getuserposts/top/from/to
    $getting = array(
      'for_posts.id',
      'top_id',
      'for_posts.user_id',
      'post_date',
      'message',
      'delete',
      'lastedit',
      'ipaddress',
      'delreason',
      'nolayout',
      'post_style',
      'postcount',
      'username',
      'perm_id',
      'total_posts',
      'header',
      'footer',
      'member_title',
      'gender',
      'avatar',
      'name_style',
      'display_name',
      'country'
    );

    $valid = $this->objAuth->getPermissions($r->kero_token);

    return DB::table('for_posts')
      ->join('users', 'for_posts.user_id', '=', 'users.id')
      ->join('usr_details', 'usr_details.user_id', '=', 'for_posts.user_id')
      ->join('usr_profile', 'usr_profile.user_id', '=', 'for_posts.user_id')
      ->join('usr_perm_id', 'usr_perm_id.user_id', '=', 'for_posts.user_id')
      ->where('for_posts.top_id', $top_id)
      ->offset($from)
      ->limit($to)
      ->orderBy('for_posts.post_date', 'asc')
      ->get($getting);
  }

  public function getUserPost($id, Request $r) { // /api/rpc/board/post/getuserpost/id
    $getting = array(
      'for_posts.id',
      'top_id',
      'for_posts.user_id',
      'post_date',
      'message',
      'delete',
      'lastedit',
      'ipaddress',
      'delreason',
      'nolayout',
      'post_style',
      'postcount',
      'username',
      'perm_id',
      'total_posts',
      'header',
      'footer',
      'member_title',
      'gender',
      'avatar',
      'name_style',
      'display_name',
      'country'
    );

    $valid = $this->objAuth->getPermissions($r->kero_token);

    return DB::table('for_posts')
      ->join('users', 'for_posts.user_id', '=', 'users.id')
      ->join('usr_details', 'usr_details.user_id', '=', 'for_posts.user_id')
      ->join('usr_profile', 'usr_profile.user_id', '=', 'for_posts.user_id')
      ->join('usr_perm_id', 'usr_perm_id.user_id', '=', 'for_posts.user_id')
      ->where('for_posts.id', $id)
      ->orderBy('for_posts.post_date', 'asc')
      ->get($getting);
  }

  public function addTopic(Request $r) { // /api/rpc/board/topic/add
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_post'] == 1) {
        $fpc = $this->getPostCountFreeze($r->for_id);

        if ($fpc === 0) {
          $next = $this->getNextPostCount($check);
        }
        else {
          $next = 0;
        }
        $addTopic = DB::table('for_threads')
          ->insertGetId([
            'for_id' => $r->for_id,
            'title' => $r->title,
            'started_by' => $check,
            'replies' => 0,
            'views' => 0,
            'last_date' => time(),
            'last_uid' => $check,
            'sticky' => 0,
            'lock' => 0,
            'poll' => 0,
            'read' => '',
            'lang_id' => 1
          ]);

        DB::table('for_posts')
          ->insert([
            'top_id' => $addTopic,
            'user_id' => $check,
            'post_date' => time(),
            'message' => $r->message,
            'delete' => 0,
            'lastedit' => 0,
            'ipaddress' => $r->ipaddress,
            'delreason' => '',
            'nolayout' => $r->nolayout,
            'postcount' => $next
          ]);

        return $addTopic;
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function addPost(Request $r) { // /api/rpc/board/post/add
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_post'] == 1) {
        $fid = $this->getForumIdFromTopic($r->top_id);
        $fpc = $this->getPostCountFreeze($fid);

        if ($fpc === 0) {
          $next = $this->getNextPostCount($check);
        }
        else {
          $next = 0;
        }
        $add = DB::table('for_posts')
          ->insertGetId([
            'top_id' => $r->top_id,
            'user_id' => $check,
            'post_date' => time(),
            'message' => $r->message,
            'delete' => 0,
            'lastedit' => 0,
            'ipaddress' => $r->ipaddress,
            'delreason' => '',
            'nolayout' => $r->nolayout,
            'postcount' => $next
          ]);

        return $this->browseTopicPosts('p', $add, 0, 15, $r);
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function editPost(Request $r) { // /api/rpc/board/post/edit
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_editother'] == 1 || $valid['for_editown'] == 1) { // TODO: differenciate own from other.
        return DB::table('for_posts')
          ->where('id', $r->id)
          ->update([
            'lastedit' => time(),
            'message' => $r->message,
            'nolayout' => $r->nolayout
          ]);
      }
    }
  }

  public function deletePost(Request $r) { // /api/rpc/board/post/delete
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_del'] == 1) {
        $s = db::table('for_posts')
          ->select('delete')
          ->where('id', $r->id)
          ->first()->delete;

        if ($s === 1) {
          $r->delreason = '';
        }

        DB::table('for_posts')
          ->where('id', $r->id)
          ->update([
            'delete' => ($s == 0 ? 1 : 0),
            'delreason' => $r->delreason
          ]);

        return array(
          'delete' => ($s == 0 ? 1 : 0),
          'delreason' => $r->delreason
        );
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function lockTopic(Request $r) { // /api/rpc/board/topic/lock
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_locky'] == 1) {
        $s = db::table('for_threads')
          ->select('lock')
          ->where('id', $r->id)
          ->first()->lock;

        DB::table('for_threads')
          ->where('id', $r->id)
          ->update([
            'lock' => ($s == 0 ? 1 : 0)
          ]);

        return ($s == 0 ? 1 : 0);
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function unlockTopic(Request $r) { // /api/rpc/board/topic/unlock
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_locky'] == 1) {
        return DB::table('for_threads')
          ->where('id', $r->id)
          ->update([
            'lock' => 0
          ]);
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function moveTopic(Request $r) { // /api/rpc/board/topic/move
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_move'] == 1) {
        $res = DB::table('for_threads')
          ->where('id', $r->id)
          ->update([
            'for_id' => $r->new_id
          ]);

        $for = DB::table('for_forums')
          ->select('title', 'cat_id')
          ->where('id', $r->new_id)
          ->first();

        $cat = DB::table('for_category')
          ->select('title')
          ->where('id', $for->cat_id)
          ->first();

        return array([
          'fid' => $r->new_id,
          'ftit' => $for->title,
          'cid' => $for->cat_id,
          'ctit' => $cat->title
        ]);
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function splitPost(Request $r) { // /api/rpc/board/post/split
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_split'] == 1) {
        $uid = DB::table('for_posts')
          ->select('user_id')
          ->where('id', $r->id)
          ->first();

        $add = DB::table('for_threads')
          ->insertGetId([
            'for_id' => $r->forId,
            'title' => $r->title,
            'started_by' => $uid->user_id,
            'replies' => 0,
            'views' => 0,
            'last_date' => 0,
            'last_uid' => 0,
            'sticky' => $r->sticky,
            'poll' => 0,
            'read' => '',
            'lock' => $r->lock
          ]);

        DB::table('for_posts')
          ->where('id', $r->id)
          ->update([
            'top_id' => $add,
          ]);

        return $add;
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function mergeTopic(Request $r) { // /api/rpc/board/topic/merge
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_mergepost'] == 1) {
        DB::table('for_posts')
          ->where('top_id', $r->id)
          ->update([
            'top_id' => $r->alt_id
          ]);

        DB::table('for_threads')
          ->where('id', $r->id)
          ->delete();

        return 'Success!';
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function pinTopic(Request $r) { // /api/rpc/board/topic/pin
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_sticky'] == 1) {
        $s = DB::table('for_threads')
          ->select('sticky')
          ->where('id', $r->id)
          ->first();

        DB::table('for_threads')
          ->where('id', $r->id)
          ->update([
            'sticky' => ($s->sticky == 0 ? 1 : 0)
          ]);

        return ($s->sticky == 0 ? 1 : 0);
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function unpinTopic(Request $r) { // /api/rpc/board/topic/unpin
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_sticky'] == 1) {
        return DB::table('for_threads')
          ->where('id', $r->id)
          ->update([
            'sticky' => 0
          ]);
      }
    }
  }

  public function getReadCategories (Request $r) { // /api/rpc/board/topic/getreadcategories
  }

  public function getReadForums (Request $r) { // /api/rpc/board/topic/getreadforums
  }

  public function getReadTopics (Request $r) { // /api/rpc/board/topic/getreadtopics
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $i = 0;
      $getTopIdAll = DB::table('for_readposts')
        ->select('top_id', 'last_read')
        ->where('user_id', $check)
        ->get();

      $res = array();

      foreach($getTopIdAll as $t) {
        $res[] = array(
          'key' => $i,
          'uid' => $check,
          'tid' => $t->top_id,
          'read' => $t->last_read
        );

        $i++;
      }

      return $res;
    }
  }

  public function markForumRead ($id, Request $r) { // /api/rpc/board/topic/markforumread/fid
  }

  public function markTopicRead ($id, Request $r) { // /api/rpc/board/topic/marktopicread/tid
  }

  public function undeletePost(Request $r) { // /api/rpc/board/post/undelete
    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($check == 0) {
      return 'Err!';
    }
    else {
      $valid = $this->objAuth->getPermissions($r->kero_token);

      if ($valid['for_del'] == 1) {
        return DB::table('for_posts')
          ->where('id', $r->id)
          ->update([
            'delete' => 0,
            'delreason' => ''
          ]);
      }
      else {
        return 'Permission denied.';
      }
    }
  }

  public function countPostsInForum($id) {
    return DB::table('for_threads')
      ->join('for_posts', 'for_posts.top_id', 'for_threads.id')
      ->where('for_threads.for_id', $id)
      ->count();
  }

  public function browseCategories(Request $r) { // /api/rpc/board/browse/browsecategories
    $cats = $this->getCategories()->toArray();
    $cols = $this->objUser->getGroupColours()->toArray();

    $res = array();
    $resC = array();

    foreach($cats as $c) {
      $cid = $c->id;
      $ctitle = $c->title;
      $fors = $this->getForumsInCategory($cid);
      $resF = array();

      foreach($fors as $f) {
        $read = $this->checkRead($f['id'], 0, $r->kero_token);
        $ldet = $this->getLastPostOfForum($f['id']);
        $topicsuu = DB::table('for_threads')->where('for_id', $f['id'])->count();
        $replysuu = $this->countPostsInForum($f['id']);

        if ($ldet['uid'] != 0) {
          $user = $this->objUser->getUser($ldet['uid'], $r)->toArray();
          $showName = "";
          $showCol = "";

          if ($user[0]->display_name !== '') {
            $showName = $user[0]->display_name;
          }
          else {
            $showName = $user[0]->username;
          }

          if ($user[0]->name_style !== '') {
            $showCol = $user[0]->name_style;
          }
          else {
            foreach($cols as $cl) {
              if ($cl->id === $user[0]->perm_id) {
                if ($user[0]->gender === 1) $showCol = $cl->colour_m;
                else if ($user[0]->gender === 2) $showCol = $cl->colour_f;
                else $showCol = $cl->colour_u;
              }
            }
          }
        }
        else {
          $showName = "";
          $showCol = "";
        }

        // Compile.
        $resF[] = array(
          'c_id' => $c->id,
          'c_name' => $c->title,
          'f_id' => $f['id'],
          'u_name' => $showName,
          'u_col' => $showCol,
          'f_cat' => $f['cat_id'],
          'f_last_uid' => $ldet['uid'],
          'f_name' => $f['title'],
          'f_desc' => $f['description'],
          'f_topics' => $topicsuu,
          'f_posts' => $replysuu,
          'f_last' => $ldet['date'],
          'f_read' => $read
        );
      }

      $res[] = array(
        'cats' => array(
          'id' => $c->id,
          'name' => $c->title
        ),
        'fors' => $resF
      );
    }

    return $res;
  }

  public function browseForums($id, $from, $to, Request $r) { // /api/rpc/board/browse/browseforums/id/from/to
    $fors = $this->getForums($id);
    $cols = $this->objUser->getGroupColours()->toArray();

    $res = array();

    foreach($fors as $f) {
      $read = $this->checkRead($f['id'], 0, $r->kero_token);
      $ldet = $this->getLastPostOfForum($f['id']);
      $topicsuu = DB::table('for_threads')->where('for_id', $f['id'])->count();
      $replysuu = $this->countPostsInForum($f['id']);

      if ($f['last_uid'] != 0) {
        $user = $this->objUser->getUser($ldet['uid'], $r)->toArray();

        $showName = "";
        $showCol = "";

        if ($user[0]->display_name !== '') {
          $showName = $user[0]->display_name;
        }
        else {
          $showName = $user[0]->username;
        }

        if ($user[0]->name_style !== '') {
          $showCol = $user[0]->name_style;
        }
        else {
          foreach($cols as $cl) {
            if ($cl->id === $user[0]->perm_id) {
              if ($user[0]->gender === 1) $showCol = $cl->colour_m;
              else if ($user[0]->gender === 2) $showCol = $cl->colour_f;
              else $showCol = $cl->colour_u;
            }
          }
        }
      }
      else {
        $showName = "";
        $showCol = "";
      }

      $catname = $this->getCategoryName($id);

      // Compile.
      $res[] = array(
        'f_id' => $f['id'],
        'f_last_uid' => $ldet['uid'],
        'f_cat' => $f['cat_id'],
        'f_name' => $f['title'],
        'f_desc' => $f['description'],
        'f_topics' => $topicsuu,
        'f_posts' => $replysuu,
        'f_last' => $ldet['date'],
        'f_read' => $read,
        'c_name' => $catname[0]->title,
        'u_name' => $showName,
        'u_col' => $showCol
      );
    }

    return $res;
  }

  public function browseForumInfo($id, $to) { // /api/rpc/board/browse/browseforuminfo/id/to
    $finfo = $this->getForum($id);

    return array(
      'ftit' => $finfo[0]->title,
      'ro' => $finfo[0]->readonly,
      'pcf' => $finfo[0]->post_count_freeze
    );
  }

  public function browseTopics($mode, $id, $from, $to, Request $r) { // /api/rpc/board/browse/browsetopicsmode/id/from/to
    $topsUP = $this->getTopicsUnpinned($id, $from, $to);
    $topsPN = $this->getTopicsPinned($id, $from, $to);
    $topsUS = $this->getTopicsUser($id, $from, $to);
    $cols = $this->objUser->getGroupColours()->toArray();

    $tops = null;

    if ($mode === 'unpinned') {
      $tops = $topsUP;
    }
    else if ($mode === 'pinned') {
      $tops = $topsPN;
    }
    else if ($mode === 'user') {
      $tops = $topsUS;
    }
    else {
      return array(
        'error' => 'Invalid mode.'
      );
    }

    $res = array();
    $i = 0;

    foreach($tops as $t) {
      $read = $this->checkRead(0, $t->id, $r->kero_token);
      $replysuu = DB::table('for_posts')->where('top_id', $t->id)->count();

      $fplp = $this->getFirstAndLastPosts($t->id);
      $userFD = $fplp['first']['date'];
      $userLD = $fplp['last']['date'];
      $userFirst = $this->objUser->getUser($fplp['first']['uid'], $r)->toArray();
      $userLast = $this->objUser->getUser($fplp['last']['uid'], $r)->toArray();
      $showNameF = "";
      $showColF = "";
      $showNameL = "";
      $showColL = "";

      if ($userFirst[0]->display_name !== '') {
        $showNameF = $userFirst[0]->display_name;
      }
      else {
        $showNameF = $userFirst[0]->username;
      }

      if ($userFirst[0]->name_style !== '') {
        $showColF = $userFirst[0]->name_style;
      }
      else {
        foreach($cols as $cl) {
          if ($cl->id === $userFirst[0]->perm_id) {
            if ($userFirst[0]->gender === 1) $showColF = $cl->colour_m;
            else if ($userFirst[0]->gender === 2) $showColF = $cl->colour_f;
            else $showColF = $cl->colour_u;
          }
        }
      }

      if ($userLast[0]->display_name !== '') {
        $showNameL = $userLast[0]->display_name;
      }
      else {
        $showNameL = $userLast[0]->username;
      }

      if ($userLast[0]->name_style !== '') {
        $showColL = $userLast[0]->name_style;
      }
      else {
        foreach($cols as $cl) {
          if ($cl->id === $userLast[0]->perm_id) {
            if ($userLast[0]->gender === 1) $showColL = $cl->colour_m;
            else if ($userLast[0]->gender === 2) $showColL = $cl->colour_f;
            else $showColL = $cl->colour_u;
          }
        }
      }

      setlocale(LC_ALL, 'ja_JP.utf8');
      $catname = $this->getCategoryName($id);

      // Compile.
      $res[] = array(
        'key' => $i,
        't_id' => $t->id,
        't_for_id' => $t->for_id,
        't_title' => $t->title,
        't_replies' => $replysuu,
        't_views' => $t->views,
        't_first_date' => strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $userFD),
        't_last_date' => strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $userLD),
        't_sticky' => $t->sticky,
        't_lock' => $t->lock,
        't_poll' => $t->poll,
        't_read' => $read,
        't_lang_id' => $t->lang_id,
        'u_first_uid' => $t->started_by,
        'u_last_uid' => $t->last_uid,
        'u_first_name' => $showNameF,
        'u_last_name' => $showNameL,
        'u_first_col' => $showColF,
        'u_last_col' => $showColL
      );

      $i++;
    }

    return $res;
  }

  public function browseTopicInfo($tp, $id, $to) { // /api/rpc/board/browse/browsetopicinfo/tp/id/to
    if ($tp == 'p') {
      // Get information for the navigation.
      $tid = $this->getTopicIdFromPost($id);
      $tinfo = $this->getTopicName($tid);
    }
    else {
      // Get information for the navigation.
      $tinfo = $this->getTopicName($id);
    }

    $finfo = $this->getForumName($tinfo[0]->for_id);
    $cinfo = $this->getCategoryName($finfo[0]->cat_id);

    // Count posts for navigation.
    if ($tp == 't') $pcount = $this->countPostsInTopic($id);

    // Is this topic locked?
    if ($tp == 't') $tlock = $this->getTopicLock($id);
    else $tlock = $this->getTopicLock($tid);
    $glock = false;
    if ($tlock[0]->lock == 1) $glock = true;

    // Is this topic read only?
    $fro = $this->getReadOnly($tinfo[0]->for_id);
    $gro = false;
    if ($fro == 1) $gro = true;

    // Is this topic pinned?
    if ($tp == 't') $tpin = $this->getTopicPin($id);
    else $tpin = $this->getTopicPin($tid);
    $gpin = false;
    if ($tpin[0]->sticky == 1) $gpin = true;

    if ($tp == 'p') {
      // Compile.
      return array(
        'topId' => $tid,
        'forId' => $tinfo[0]->for_id,
        'topName' => $tinfo[0]->title,
        'catId' => $finfo[0]->cat_id,
        'forName' => $finfo[0]->title,
        'catName' => $cinfo[0]->title,
        'lock' => $glock,
        'pin' => $gpin,
        'ro' => $gro
      );
    }
    else {
      // Compile.
      return array(
        'forId' => $tinfo[0]->for_id,
        'topName' => $tinfo[0]->title,
        'catId' => $finfo[0]->cat_id,
        'forName' => $finfo[0]->title,
        'catName' => $cinfo[0]->title,
        'maxPage' => ceil($pcount / $to),
        'posts' => $pcount,
        'lock' => $glock,
        'pin' => $gpin,
        'ro' => $gro
      );
    }
  }

  public function stripBR($string) {
    return preg_replace('/\<br(\s*)?\/?\>/i', '', $string);
  }

  public function autoLink($s) {
    if (strpos($s, '[link=') !== false || strpos($s, '[/link]') !== false) {
      return $s;
    }
    else if (strpos($s, '<a href=') !== false || strpos($s, '</a>') !== false) {
      return $s;
    }
    else if (strpos($s, '[img]') !== false || strpos($s, '[/img]') !== false) {
      return $s;
    }
    else {
      return preg_replace('!(\s|^)((https?://|www\.)+[a-z0-9_%./#?=;&-]+)!i', ' <a href="$2" target="_blank">$2</a> ',$s);
    }
  }

  function getSmilies() {
    $protocol = isset($_SERVER["HTTPS"]) ? 'https' : 'http';
    $domain = $protocol.'://'.$_SERVER['SERVER_NAME'];
    $kusa = '/assets/smileys/';

    $get = DB::table('for_smileys')
    ->select('text', 'image')
    ->get();

    $res = array();

    foreach ($get as $g) {
      $res[] = array(
        'val' => $g->text,
        'url' => $domain.$kusa.$g->image
      );
    }

    return $res;
  }

  function getSmile($text) {
    $protocol = isset($_SERVER["HTTPS"]) ? 'https' : 'http';
    $domain = $protocol.'://'.$_SERVER['SERVER_NAME'];
    $kusa = '/assets/smileys/';

    $get = DB::table('for_smileys')
    ->select('text', 'image')
    ->get();

    foreach ($get as $g) {
      $text = str_replace( $g->text, "<img src='".$domain.$kusa.$g->image."' width='20px' height='20px' />", $text);
    }

    return $text;
  }

  function getBBCode($text) {
    $find = array(
      '~\[b\](.*?)\[/b\]~s',
      '~\[i\](.*?)\[/i\]~s',
      '~\[u\](.*?)\[/u\]~s',
      '~\[s\](.*?)\[/s\]~s',
      '~\[o\](.*?)\[/o\]~s',
      '~\[centre\](.*?)\[/centre\]~s',
      '~\[img width=(.*?) height=(.*?)\](https?://.*?\.(?:jpg|jpeg|gif|png|JPG|JPEG|GIF|PNG))\[/img\]~s',
      '~\[img height=(.*?) width=(.*?)\](https?://.*?\.(?:jpg|jpeg|gif|png|JPG|JPEG|GIF|PNG))\[/img\]~s',
      '~\[img width=(.*?)\](https?://.*?\.(?:jpg|jpeg|gif|png|JPG|JPEG|GIF|PNG))\[/img\]~s',
      '~\[img height=(.*?)\](https?://.*?\.(?:jpg|jpeg|gif|png|JPG|JPEG|GIF|PNG))\[/img\]~s',
      '~\[img\](https?://.*?\.(?:jpg|jpeg|gif|png|JPG|JPEG|GIF|PNG))\[/img\]~s',
      '~\[yt\](.*?)\[/yt\]~s',
      '~\[link=((?:ftp|https?)://.*?)\](.*?)\[/link\]~s',
      '~\[sound\](https?://.*?\.(?:mp3))\[/sound\]~s',
      '~\[size=(.*?)\](.*?)\[/size\]~s',
      '~\[colour=(.*?)\](.*?)\[/colour\]~s',
      '~\[quote="(.*?)" id="(.*?)"](.*?)\[/quote]~s',
      '~\[quote="(.*?)"](.*?)\[/quote]~s',
      '~\[quote](.*?)\[/quote]~s',
      '~\[code](.*?)\[/code]~s',
      '~\[spoiler=(.*?)](.*?)\[/spoiler]~s',
      '~\[spoiler](.*?)\[/spoiler]~s',
      '~\[rtl](.*?)\[/rtl]~s',
      '~\[gcn](.*?)\[/gcn]~s',
      '~\[miiverse](.*?)\[/miiverse]~s',
      '~\[smb](.*?)\[/smb]~s',
      '~\[video](.*?)\[/video]~s',
      '~\[nico](.*?)\[/nico]~s',
    );

    $replace = array(
      '<b>$1</b>',
      '<i>$1</i>',
      '<span style="text-decoration:underline;">$1</span>',
      '<span style="text-decoration:line-through;">$1</span>',
      '<span style="text-decoration:overline;">$1</span>',
      '<span align="center">$1</span>',
      '<img src="$3" alt="" width="$1px" height="$2px" border="0" />',
      '<img src="$3" alt="" width="$2px" height="$1px" border="0" />',
      '<img src="$2" alt="" width="$1px" border="0" />',
      '<img src="$2" alt="" height="$1px" border="0" />',
      '<img src="$1" alt="" class="img-responsive" border="0" />',
      '<div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" src="https://www.youtube.com/embed/$1" allowfullscreen></iframe></div>',
      '<a href="$1" target="_blank">$2</a>',
      '<audio controls><source src="$1" type="audio/mpeg">Your browser does not support the audio tag.</audio>',
      '<span style="font-size:$1px;">$2</span>',
      '<span style="color:$1;">$2</span>',
      '<blockquote><span class=\'quotedby\'><a href=forum.php?page=thread&tid=$threadid&pid=$2#$2><i>Posted by \'$1\'</i></a></span><hr>$3<hr></blockquote>',
      '<blockquote><span class=\'quotedby\'><i>Posted by \'$1\'</i></span><hr>$2<hr></blockquote>',
      '<blockquote><hr>$1<hr></blockquote>',
      '<table cellspacing="0" style="width: 90%; min-width: 90%;"><tr><td class="b n3"><code class="codeblock" style="font-size: 9pt;"><xmp>$1</xmp></code></tr></table><br />',
      '<div class="spoiler"><button onclick="var s=this.parentNode.getElementsByClassName(\'spoilercontents\')[0].style;s.display=(s.display==\'none\')?\'\':\'none\';">$1</button><br /><div class="spoilercontents" style="display:none;">$2</div></div>',
      '<div class="spoiler"><button onclick="var s=this.parentNode.getElementsByClassName(\'spoilercontents\')[0].style;s.display=(s.display==\'none\')?\'\':\'none\';">Spoiler</button><br /><div class="spoilercontents" style="display:none;">$1</div></div>',
      '<div dir="rtl">$1</div>',
      '<span class="GameCube">$1</span>',
      '<span class="MiiverseSymbols">$1</span>',
      '<span class="MarioBros">$1</span>',
      '<video width="600" controls><source src="$1" type="video/mp4">Your browser does not support MP4, or HTML5 videos.</video>',
      '<script type="application/javascript" src="https://embed.nicovideo.jp/watch/$1/script?w=640&h=360"></script><noscript><a href="http://www.nicovideo.jp/watch/$1">title</noscript>',
    );

    return preg_replace($find, $replace, $text);
  }

  public function packageMessage($string) {
    $string = $this->stripBR($string);
    $string = $this->autoLink($string);
    $string = $this->getBBCode($string);
    $string = $this->getSmile($string);

    return $string;
  }

  public function browseTopicPosts($tp, $id, $from, $to, Request $r) { // /api/rpc/board/browse/browsetopicposts/tp/id/from/to
    // Load group colours.
    $ucol = $this->objUser->getGroupColours();

    // All the user posts' user IDs.
    if ($tp == 't') $uid = $this->getUserPosts($id, $from, $to, $r);
    else if ($tp == 'p') $uid = $this->getUserPost($id, $r);
    else $uid = $this->getPostsOfUser($id, $from, $to, $r);
    $udat = array();
    $key = 0;
    $ldate = 0;

    foreach ($uid as $i) {
      $showName = '';
      $showCol = '';
      $showGroupName = '';

      // Display name or username?
      if (!empty($i->display_name)) {
        $showName = $i->display_name;
      }
      else {
        $showName = $i->username;
      }

      // Custom name styling or default?
      if (!empty($i->name_style)) {
        $showCol = $i->name_style;
      }
      else {
        foreach ($ucol as $j) {
          if ($j->id == $i->perm_id) {
            if ($i->gender == 1) $showCol = $j->colour_m;
            else if ($i->gender == 2) $showCol = $j->colour_f;
            else $showCol = $j->colour_u;
          }
        }
      }

      // Group names.
      $gname = $this->objUser->getGroupName($i->user_id);
      $showGroupName = $gname[0]->name;

      $mess = $this->packageMessage($i->message);

      setlocale(LC_ALL, 'ja_JP.utf8');

      array_push($udat, [
        'key' => $key,
        'id' => $i->id,
        'tid' => $i->top_id,
        'uid' => $i->user_id,
        'post_date' => strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $i->post_date),
        'message' => ($i->post_style ? '<style scoped>.post-'.$i->user_id.' { '.$i->post_style.' }</style>' : '').$mess,
        'delete' => $i->delete,
        'delreason' => $i->delreason,
        'lastedit' => strftime('%Y/%m/%d(%a) %H:%M:%S %Z', $i->lastedit),
        'lasteditUnix' => $i->lastedit,
        'ipaddress' => $i->ipaddress,
        'nolayout' => $i->nolayout,
        'postcount' => $i->postcount,
        'total_posts' => $i->total_posts,
        'header' => $i->header,
        'footer' => $i->footer,
        'member_title' => $i->member_title,
        'gender' => $i->gender,
        'avatar' => ($i->avatar ? $i->avatar : '/img/noicon.webp'),
        'showcol' => $showCol,
        'showname' => $showName,
        'showgroup' => $showGroupName,
        'country' => $i->country,
      ]);

      $ldate = $i->post_date;
      $key++;
    }

    $check = $this->objAuth->checkLegit($r->kero_token);

    if ($tp == 't' && $check != 0) {
      $view = DB::table('for_threads')
        ->select('views')
        ->where('id', $id)
        ->first();

      DB::table('for_threads')
        ->where('id', $id)
        ->update(['views' => $view->views+1]);

      $checkTime = DB::table('for_read')
      ->select('view_time')
      ->where('user_id', $check)
      ->where('top_id', $id)
      ->first();

      if (empty($checkTime)) {
        DB::table('for_read')
          ->insert([
            'user_id' => $check,
            'top_id' => $id,
            'view_time' => $ldate
          ]);
      }
      else if ($ldate > $checkTime->view_time) {
        DB::table('for_read')
          ->where('user_id', $check)
          ->where('top_id', $id)
          ->update(['view_time' => $ldate]);
      }
    }

    // Assign group names.
    return $udat;
  }

  public function browsePermissions($uid, Request $r) { // /api/rpc/board/browse/browsepermissions/uid
    // Get user ID.
    $perm = $this->objUser->getUser($uid, $r);

    // Does the user ID exist? Grand the appropriate rights. Otherwise, use guest.
    if ($uid != 0) {
      // Forum permissions.
      $grouppermfor = $this->objPermission->getPermissionGroup('for', $perm[0]->perm_id);
      $userpermfor = $this->objPermission->getPermissionUser('for', $uid);

      // User permissions.
      $grouppermusr = $this->objPermission->getPermissionGroup('usr', $perm[0]->perm_id);
      $userpermusr = $this->objPermission->getPermissionUser('usr', $uid);

      // Now provide an array of user overwritten permissions if it exists. Otherwise, give its group permissions.
      $forarr = array();
      $usrarr = array();

      if (!empty($userpermfor[0])) {
        $forarr = (array)$userpermfor[0];
      }
      else {
        $forarr = (array)$grouppermfor[0];
      }

      if (!empty($userpermusr[0])) {
        $usrarr = (array)$userpermusr[0];
      }
      else {
        $usrarr = (array)$grouppermusr[0];
      }

      $merge = array();
      $merge = array_merge($forarr, $usrarr);

      return $merge;
    }
    else {
      // Forum permissions.
      $grouppermfor = $this->objPermission->getPermissionGroup('for', 6);

      // User permissions.
      $grouppermusr = $this->objPermission->getPermissionGroup('usr', 6);

      // Since guests don't have user overwritten permissions, simply return the group permissions.
      $merge = array();
      $merge = array_merge((array)$grouppermfor[0], (array)$grouppermusr[0]);

      return $merge;
    }
  }
}
