public function getBoardHistory(Board $board, Post $post)
 {
     $posts = $board->posts()->with('op')->withEverything()->where('author_ip', $post->author_ip)->orderBy('post_id', 'desc')->paginate(15);
     foreach ($posts as $item) {
         $item->setRelation('board', $board);
     }
     return $this->view(static::VIEW_HISTORY, ['posts' => $posts, 'multiboard' => false]);
 }
 /**
  * Returns a post to the client. 
  *
  * @var Board $board
  * @var Post  $post
  * @return Response
  */
 public function getPost(Board $board, Post $post)
 {
     // Pull the post.
     $post = $board->posts()->where('board_id', $post)->withEverything()->firstOrFail();
     if (!$post) {
         return abort(404);
     }
     return $post;
 }
 public function getBoardHistory(Board $board, Post $post)
 {
     if (!$this->user->canViewHistory($post)) {
         return abort(403);
     }
     $posts = $board->posts()->with('op')->withEverything()->where('author_ip', $post->author_ip)->orderBy('post_id', 'desc')->paginate(15);
     foreach ($posts as $item) {
         $item->setRelation('board', $board);
     }
     return $this->view(static::VIEW_HISTORY, ['posts' => $posts, 'multiboard' => false, 'ip' => ip_less($post->author_ip->toText())]);
 }
示例#4
0
 /**
  * Automatically adds a R9K ban to the specified board.
  *
  * @static
  * @param  \App\Board  $board  The board the ban is to be added in.
  * @param  binary|string|null  $ip  Optional. The IP to ban. Defaults to client IP.
  * @return static
  */
 public static function addRobotBan(Board $board, $ip = null)
 {
     $ip = new IP($ip);
     // Default time is 2 seconds.
     $time = 2;
     // Pull the ban that expires the latest.
     $ban = $board->bans()->whereIpInBan($ip)->whereRobot()->orderBy('expires_at', 'desc')->first();
     if ($ban instanceof static) {
         if (!$ban->isExpired()) {
             return $ban;
         }
         $time = $ban->created_at->diffInSeconds($ban->expires_at) * 2;
     }
     return static::create(['ban_ip_start' => $ip, 'ban_ip_end' => $ip, 'expires_at' => Carbon::now()->addSeconds($time), 'board_uri' => $board->board_uri, 'is_robot' => true, 'justification' => trans('validation.custom.unoriginal_content')]);
 }
 /**
  * Returns a thread and its replies. 
  *
  * @param  \App\Board $board
  * @return Response
  */
 public function getThreads(Board $board)
 {
     // Determine what page we are on.
     $pages = $board->getPageCount();
     $response = [];
     for ($i = 0; $i < $pages; ++$i) {
         $pageArray = ['page' => $i, 'threads' => []];
         $threads = $board->getThreadsForIndex($i);
         foreach ($threads as $thread) {
             $pageArray['threads'][] = ['no' => (int) $thread->board_id, 'last_modified' => (int) $thread->bumped_last->timestamp];
         }
         $response[] = $pageArray;
     }
     return response()->json($response);
 }
示例#6
0
 /**
  * Returns the information specified by boardStats
  *
  * @return array (indexes and vales based on $boardStats)
  */
 protected function boardStats()
 {
     $controller =& $this;
     $stats = Cache::remember('index.boardstats', 60, function () use($controller) {
         $stats = [];
         foreach ($controller->boardStats as $boardStat) {
             switch ($boardStat) {
                 case "boardIndexedCount":
                     $stats[$boardStat] = Board::whereIndexed()->count();
                     break;
                 case "startDate":
                     $stats[$boardStat] = Board::orderBy('created_at', 'desc')->take(1)->pluck('created_at')->format("M jS, Y");
                     break;
                 case "boardTotalCount":
                     $stats[$boardStat] = Board::count();
                     break;
                 case "postCount":
                     $stats[$boardStat] = Board::sum('posts_total');
                     break;
                 case "postRecentCount":
                     $stats[$boardStat] = Post::recent()->count();
                     break;
             }
         }
         return $stats;
     });
     return $stats;
 }
 /**
  * Get all form input.
  *
  * @return array
  */
 public function all()
 {
     $input = parent::all();
     $this->dropzone = isset($input['dropzone']);
     if (isset($input['files']) && is_array($input['files'])) {
         // Having an [null] file array passes validation.
         $input['files'] = array_filter($input['files']);
     }
     if (isset($input['capcode']) && $input['capcode']) {
         $user = $this->user;
         if ($user && !$user->isAnonymous()) {
             $role = $user->roles->where('role_id', (int) $input['capcode'])->first();
             if ($role && $role->capcode != "") {
                 $input['capcode_id'] = (int) $role->role_id;
                 // $input['author']     = $user->username;
             } else {
                 $this->failedAuthorization();
             }
         } else {
             unset($input['capcode']);
         }
     }
     if (!$this->board->canPostWithAuthor($this->user, !!$this->thread)) {
         unset($input['author']);
     }
     if (!$this->board->canPostWithSubject($this->user, !!$this->thread)) {
         unset($input['subject']);
     }
     return $input;
 }
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
     Schema::create('board_adventures', function (Blueprint $table) {
         $table->increments('adventure_id');
         $table->binary('adventurer_ip');
         $table->string('board_uri', 32);
         $table->integer('post_id')->unsigned()->nullable()->default(NULL);
         $table->timestamps();
         $table->timestamp('expires_at');
         $table->timestamp('expended_at')->nullable()->default(NULL);
         $table->foreign('board_uri')->references('board_uri')->on('boards')->onDelete('cascade')->onUpdate('cascade');
     });
     Schema::table('posts', function (Blueprint $table) {
         $table->integer('adventure_id')->unsigned()->nullable()->default(NULL)->after('locked_at');
         $table->foreign('adventure_id')->references('adventure_id')->on('board_adventures')->onDelete('set null')->onUpdate('cascade');
     });
     Schema::table('boards', function (Blueprint $table) {
         $table->timestamp('last_post_at')->nullable()->default(NULL)->after('updated_at');
     });
     Board::chunk(100, function ($boards) {
         foreach ($boards as $board) {
             $lastPost = $board->posts()->orderBy('created_at', 'desc')->limit(1)->get()->last();
             if ($lastPost) {
                 $board->last_post_at = $lastPost->created_at;
                 $board->save();
             }
         }
     });
 }
示例#9
0
 /**
  * Returns the information specified by boardStats
  *
  * @return array (indexes and vales based on $boardStats)
  */
 protected function boardStats()
 {
     $controller =& $this;
     $stats = Cache::remember('index.boardstats', 60, function () use($controller) {
         $stats = [];
         foreach ($controller->boardStats as $boardStat) {
             switch ($boardStat) {
                 case "boardCount":
                     $stats[$boardStat] = Board::whereIndexed()->count();
                     break;
                 case "boardIndexedCount":
                     $stats[$boardStat] = Board::count();
                     break;
                 case "postCount":
                     $stats[$boardStat] = Board::sum('posts_total');
                     break;
                 case "postRecentCount":
                     $stats[$boardStat] = Post::recent()->count();
                     break;
             }
         }
         return $stats;
     });
     return $stats;
 }
示例#10
0
 /**
  * Returns a thread and its replies to the client. 
  *
  * @var Board $board
  * @var integer|null $thread
  * @return Response
  */
 public function getThread(Request $request, Board $board, $thread)
 {
     if (is_null($thread)) {
         return abort(404);
     }
     $input = $request->only('updatesOnly', 'updateHtml', 'updatedSince');
     if (isset($input['updatesOnly'])) {
         $updatedSince = Carbon::createFromTimestamp($request->input('updatedSince', 0));
         $posts = Post::where('posts.board_uri', $board->board_uri)->withEverything()->where(function ($query) use($thread) {
             $query->where('posts.reply_to_board_id', $thread);
             $query->orWhere('posts.board_id', $thread);
         })->where(function ($query) use($updatedSince) {
             $query->where('posts.updated_at', '>=', $updatedSince);
             $query->orWhere('posts.deleted_at', '>=', $updatedSince);
         })->withTrashed()->orderBy('posts.created_at', 'asc')->get();
         if (isset($input['updateHtml'])) {
             foreach ($posts as $post) {
                 $appends = $post->getAppends();
                 $appends[] = "html";
                 $post->setAppends($appends);
             }
         }
         return $posts;
     } else {
         // Pull the thread.
         $thread = $board->getThreadByBoardId($thread);
         if (!$thread) {
             return abort(404);
         }
     }
     return $thread;
 }
示例#11
0
 public function createBoard()
 {
     $table = json_encode([[['state' => 0], ['state' => 0], ['state' => 0]], [['state' => 0], ['state' => 0], ['state' => 0]], [['state' => 0], ['state' => 0], ['state' => 0]]]);
     $board = Board::create(['table' => $table, 'moves' => 0, 'finished' => false]);
     $player1 = Player::create(['user_id' => 1, 'board_id' => $board->id, 'winner' => null]);
     $player2 = Player::create(['user_id' => 1, 'board_id' => $board->id, 'winner' => null]);
     return redirect('/');
 }
示例#12
0
 /**
  * Display the specified resource.
  *
  * @param  int  $id
  * @return \Illuminate\Http\Response
  */
 public function show($id)
 {
     $board = Board::find($id);
     if (!$board) {
         return \Response::json(['error' => ['message' => 'Board does not exist']], 404);
     }
     return \Response::json(['data' => $board->toArray()], 200);
 }
 /**
  * Create a new user instance after a valid registration.
  *
  * @param  array  $data
  * @return User
  */
 public function create(array $data)
 {
     $user = User::create(['username' => $data['username'], 'email' => $data['email'], 'password' => bcrypt($data['password'])]);
     // Create the user's personal pinboard
     if ($user) {
         $personalboard = Board::Create(['title' => 'My Personal Activities', 'body' => 'I will do these All Day! Erry Day!', 'shared_with' => 0, 'id_users' => $user->id]);
     }
     return $user;
 }
示例#14
0
 /**
  * Returns if the client has access to this form.
  *
  * @return boolean
  */
 public function authorize()
 {
     // Ban check.
     $ban = Ban::getBan($this->ip(), $this->board->board_uri);
     if ($ban) {
         $this->ban = $ban;
         return false;
     }
     return $this->board->canPost($this->user, $this->thread);
 }
示例#15
0
 public function run()
 {
     $this->command->info("Seeding boards.");
     if (Board::count() < 1) {
         $board = Board::firstOrCreate(['board_uri' => "test", 'title' => "Test", 'description' => "Discover software features on your own", 'created_by' => 1, 'operated_by' => 1]);
         $this->command->info("Success. At least one board exists now. Accessible at /test/.");
     } else {
         $this->command->info("Skipped. Site has at least one board.");
     }
 }
示例#16
0
 public function run()
 {
     $this->command->info('Seeding role to user associations.');
     $userRoles = [['user_id' => 1, 'role_id' => Role::ID_ADMIN]];
     foreach (Board::get() as $board) {
         $userRoles[] = ['user_id' => $board->operated_by, 'role_id' => $board->getOwnerRole()->role_id];
     }
     foreach ($userRoles as $userRole) {
         UserRole::firstOrCreate($userRole);
     }
 }
示例#17
0
 /**
  * Validate and save changes.
  *
  * @return Response
  */
 public function patchIndex(BoardConfigRequest $request, Board $board)
 {
     $input = $request->all();
     $optionGroups = $request->getBoardOptions();
     foreach ($optionGroups as $optionGroup) {
         foreach ($optionGroup->options as $option) {
             $setting = BoardSetting::firstOrNew(['option_name' => $option->option_name, 'board_uri' => $board->board_uri]);
             $option->option_value = $input[$option->option_name];
             $setting->option_value = $input[$option->option_name];
             $setting->save();
         }
     }
     $board->title = $input['boardBasicTitle'];
     $board->description = $input['boardBasicDesc'];
     $board->is_overboard = isset($input['boardBasicOverboard']) && !!$input['boardBasicOverboard'];
     $board->is_indexed = isset($input['boardBasicIndexed']) && !!$input['boardBasicIndexed'];
     $board->is_worksafe = isset($input['boardBasicWorksafe']) && !!$input['boardBasicWorksafe'];
     $board->save();
     Event::fire(new BoardWasModified($board));
     return $this->view(static::VIEW_CONFIG, ['board' => $board, 'groups' => $optionGroups]);
 }
示例#18
0
 /**
  * @return void
  */
 public function __construct(UserManager $manager)
 {
     $this->userManager = $manager;
     $this->auth = $manager->auth;
     $this->registrar = $manager->registrar;
     $this->user = $manager->user;
     if ($this->option('boardListShow')) {
         View::share('boardbar', Board::getBoardListBar());
     }
     View::share('user', $this->user);
     $this->boot();
 }
示例#19
0
 /**
  * Adds new staff.
  *
  * @return Response
  */
 public function putAdd(Board $board)
 {
     if (!$board->canEditConfig($this->user)) {
         return abort(403);
     }
     $createUser = false;
     $roles = $this->user->getAssignableRoles($board);
     $rules = [];
     $existing = Input::get('staff-source') == "existing";
     if ($existing) {
         $rules = ['existinguser' => ["required", "string", "exists:users,username"], 'captcha' => ["required", "captcha"]];
         $input = Input::only('existinguser', 'captcha');
         $validator = Validator::make($input, $rules);
     } else {
         $createUser = true;
         $validator = $this->registrationValidator();
     }
     $castes = $roles->pluck('role_id');
     $casteRules = ['castes' => ["required", "array"]];
     $casteInput = Input::only('castes');
     $casteValidator = Validator::make($casteInput, $casteRules);
     $casteValidator->each('castes', ["in:" . $castes->implode(",")]);
     if ($validator->fails()) {
         return redirect()->back()->withInput()->withErrors($validator->errors());
     } else {
         if ($casteValidator->fails()) {
             return redirect()->back()->withInput()->withErrors($casteValidator->errors());
         } else {
             if ($createUser) {
                 $user = $this->registrar->create(Input::all());
             } else {
                 $user = User::whereUsername(Input::only('existinguser'))->firstOrFail();
             }
         }
     }
     $user->roles()->detach($roles->pluck('role_id')->toArray());
     $user->roles()->attach($casteInput['castes']);
     Event::fire(new UserRolesModified($user));
     return redirect("/cp/board/{$board->board_uri}/staff");
 }
示例#20
0
 /**
  * Tests the board model and depndant views.
  *
  * @return void
  */
 public function testModelAndViews()
 {
     // Get a board.
     $boards = Board::take(1)->get();
     // Get a board that cannot exist.
     // The maximum `board_uri` length should be, at most, 31.
     $noBoards = Board::where('board_uri', "12345678901234567890123456789012")->take(1)->get();
     $this->assertInstanceOf("Illuminate\\Database\\Eloquent\\Collection", $boards);
     $this->assertInstanceOf("Illuminate\\Database\\Eloquent\\Collection", $noBoards);
     $this->assertEquals(0, count($noBoards));
     if (count($boards)) {
         $this->board = $board = $boards[0];
         $this->assertInstanceOf("App\\Board", $board);
         // Test relationships
         $this->assertInstanceOf("Illuminate\\Database\\Eloquent\\Relations\\HasMany", $board->posts());
         $this->assertInstanceOf("Illuminate\\Database\\Eloquent\\Relations\\HasMany", $board->logs());
         $this->assertInstanceOf("Illuminate\\Database\\Eloquent\\Relations\\HasMany", $board->threads());
         $this->assertInstanceOf("Illuminate\\Database\\Eloquent\\Relations\\HasMany", $board->roles());
         // Test modern routes
         $response = $this->call('GET', url("{$board->board_uri}"));
         $this->assertEquals(200, $response->getStatusCode());
         $this->doBoardIndexAssertions();
         $response = $this->call('GET', url("{$board->board_uri}/1"));
         $this->assertEquals(200, $response->getStatusCode());
         $this->doBoardIndexAssertions();
         $response = $this->call('GET', url("{$board->board_uri}/catalog"));
         $this->assertEquals(200, $response->getStatusCode());
         $response = $this->call('GET', url("{$board->board_uri}/logs"));
         $this->assertEquals(200, $response->getStatusCode());
         $this->assertViewHas('board');
         $this->assertViewHas('logs');
         // Test legacy routes
         $legacyCode = env('LEGACY_ROUTES', false) ? 302 : 404;
         $response = $this->call('GET', url("{$board->board_uri}/index.html"));
         $this->assertEquals($legacyCode, $response->getStatusCode());
         $response = $this->call('GET', url("{$board->board_uri}/1.html"));
         $this->assertEquals($legacyCode, $response->getStatusCode());
         $response = $this->call('GET', url("{$board->board_uri}/catalog.html"));
         $this->assertEquals($legacyCode, $response->getStatusCode());
     } else {
         $this->assertEquals(0, Board::count());
     }
 }
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     $firstPost = Post::orderBy('post_id', 'asc')->first()->pluck('created_at');
     $trackTime = clone $firstPost;
     $nowTime = Carbon::now()->minute(0)->second(0)->timestamp;
     $boards = Board::all();
     $this->comment("Reviewing all records.");
     while ($firstPost->timestamp < $nowTime) {
         $firstPost = $firstPost->addHour();
         $hourCount = 0;
         foreach ($boards as $board) {
             if ($board->posts_total > 0) {
                 $newRows = $board->createStatsSnapshot($firstPost);
                 $hourCount += count($newRows);
             }
         }
         if ($hourCount > 0) {
             $this->comment("\tAdded {$hourCount} new stat row(s) from " . $firstPost->diffForHumans());
         }
     }
 }
 public function getIndex()
 {
     if (!$this->option('adventureEnabled')) {
         return abort(404);
     }
     $adventures = BoardAdventure::select('board_uri')->where('adventurer_ip', inet_pton(Request::ip()))->get();
     $board_uris = [];
     foreach ($adventures as $adventure) {
         $board_uris[] = $adventure->board_uri;
     }
     $board = Board::select('board_uri')->whereNotIn('board_uri', $adventures)->wherePublic()->whereIndexed()->whereLastPost(48)->get();
     if (count($board)) {
         $board = $board->random(1);
         $newAdventure = new BoardAdventure(['board_uri' => $board->board_uri, 'adventurer_ip' => inet_pton(Request::ip())]);
         $newAdventure->expires_at = $newAdventure->freshTimestamp()->addHours(1);
         $newAdventure->save();
     } else {
         $board = false;
     }
     return $this->view(static::VIEW_ADVENTURE, ['board' => $board]);
 }
示例#23
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     $firstPost = Post::orderBy('post_id', 'asc')->first()->pluck('created_at');
     $nowTime = Carbon::now()->minute(0)->second(0)->timestamp;
     $boards = Board::all();
     $this->comment("Reviewing all records.");
     while ($firstPost->timestamp < $nowTime) {
         $firstPost = $firstPost->addHour();
         $hourCount = 0;
         foreach ($boards as $board) {
             if ($board->posts_total > 0) {
                 $newRows = $board->createStatsSnapshot($firstPost);
                 $hourCount += $newRows->count();
             }
         }
         if ($hourCount > 0) {
             $this->comment("\tAdded {$hourCount} new stat row(s) from " . $firstPost->diffForHumans());
         }
     }
     // Drop boardlist cache.
     Cache::forget('site.boardlist');
     // Generate boardlist again.
     Board::getBoardsForBoardlist();
 }
 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
     Schema::dropIfExists('stats_uniques');
     Schema::dropIfExists('stats');
     Schema::create('stats', function (Blueprint $table) {
         $table->bigIncrements('stats_id');
         $table->string('board_uri', 32);
         $table->timestamp('stats_time');
         $table->string('stats_type', 25);
         $table->bigInteger('counter')->unsigned()->default(0);
         $table->unique(['stats_time', 'board_uri', 'stats_type']);
     });
     Schema::create('stats_uniques', function (Blueprint $table) {
         $table->bigIncrements('stats_bit_id');
         $table->bigInteger('stats_id')->unsigned();
         $table->bigInteger('unique');
         $table->foreign('stats_id')->references('stats_id')->on('stats')->onDelete('cascade')->onUpdate('cascade');
     });
     $firstPost = Post::orderBy('post_id', 'asc')->first()->pluck('created_at');
     $trackTime = clone $firstPost;
     $nowTime = \Carbon\Carbon::now()->minute(0)->second(0)->timestamp;
     $boards = Board::all();
     while ($firstPost->timestamp < $nowTime) {
         $firstPost = $firstPost->addHour();
         $hourCount = 0;
         foreach ($boards as $board) {
             if ($board->posts_total > 0) {
                 $newRows = $board->createStatsSnapshot($firstPost);
                 $hourCount += count($newRows);
             }
         }
         if ($hourCount > 0) {
             echo "\tAdded {$hourCount} new stat row(s) from " . $firstPost->diffForHumans() . "\n";
         }
     }
 }
示例#25
0
 /**
  * Returns rules specifically for dropzone files for a board.
  *
  * @param  Board  $board
  * @param  array  $rules (POINTER, MODIFIED)
  * @return array  Validation rules.
  */
 public static function rulesForFileHashes(Board $board, array &$rules)
 {
     global $app;
     $attachmentsMax = $board->getConfig('postAttachmentsMax', 1);
     $rules['files'][] = "array";
     $rules['files'][] = "min:1";
     $rules['files'][] = "max:{$attachmentsMax}";
     // Create an additional rule for each possible file.
     for ($attachment = 0; $attachment < $attachmentsMax; ++$attachment) {
         $rules["files.name.{$attachment}"] = ["string", "required_with:files.hash.{$attachment}", "between:1,254", "file_name"];
         $rules["files.hash.{$attachment}"] = ["string", "required_with:files.name.{$attachment}", "md5", "exists:files,hash,banned,0"];
         $rules["files.spoiler.{$attachment}"] = ["boolean"];
     }
 }
 protected function boardListSearch($perPage = 25)
 {
     $input = $this->boardListInput();
     $title = $input['title'];
     $lang = $input['lang'];
     $page = $input['page'];
     $tags = $input['tags'];
     $sfw = $input['sfw'];
     $sort = $input['sort'];
     $sortBy = $input['sortBy'];
     $boards = collect(Board::getBoardsForBoardlist());
     $boards = $boards->filter(function ($item) use($lang, $tags, $sfw, $title) {
         // Are we able to view unindexed boards?
         if (!$item['is_indexed'] && !$this->user->canViewUnindexedBoards()) {
             return false;
         }
         // Are we requesting SFW only?
         if ($sfw && !$item['is_worksafe']) {
             return false;
         }
         // Are we searching by language?
         if ($lang) {
             $boardLang = $item->settings['boardLanguage'];
             if ($lang != $boardLang) {
                 return false;
             }
         }
         // Are we searching tags?
         if ($tags && (!count($item['tags']) || count(array_intersect($tags, array_fetch($item['tags'], 'tag'))) < count($tags))) {
             return false;
         }
         // Are we searching titles and descriptions?
         if ($title && stripos($item['board_uri'], $title) === false && stripos($item['title'], $title) === false && stripos($item['description'], $title) === false) {
             return false;
         }
         return true;
     });
     if ($title || $sort && $sortBy) {
         $sortWeight = $sortBy == "asc" ? -1 : 1;
         $boards = $boards->sort(function ($a, $b) use($title, $sort, $sortWeight) {
             // Sort by active users, then last post time.
             $aw = 0;
             $bw = 0;
             if ($title) {
                 $aw += $a['board_uri'] === $title ? 80 : 0;
                 $aw += stripos($a['board_uri'], $title) !== false ? 40 : 0;
                 $aw += stripos($a['title'], $title) !== false ? 20 : 0;
                 $aw += stripos($a['description'], $title) !== false ? 10 : 0;
                 $bw += $b['board_uri'] === $title ? 80 : 0;
                 $aw += stripos($b['board_uri'], $title) !== false ? 40 : 0;
                 $aw += stripos($b['title'], $title) !== false ? 20 : 0;
                 $aw += stripos($b['description'], $title) !== false ? 10 : 0;
             }
             if ($sort) {
                 if ($a[$sort] > $b[$sort]) {
                     $aw += $sortWeight;
                 } else {
                     if ($a[$sort] < $b[$sort]) {
                         $bw += $sortWeight;
                     }
                 }
             }
             return $bw - $aw;
         });
     }
     $paginator = new LengthAwarePaginator($boards->forPage($page, $perPage), $boards->count(), $perPage, $page);
     $paginator->setPath(url("boards.html"));
     foreach ($input as $inputIndex => $inputValue) {
         if ($inputIndex == "sfw") {
             $inputIndex = (int) (!!$inputValue);
         }
         $paginator->appends($inputIndex, $inputValue);
     }
     return $paginator;
 }
示例#27
0
 /**
  * Show the catalog (gridded) board view.
  *
  * @param  Board    $board
  * @return Response
  */
 public function getCatalog(Board $board)
 {
     // Load our list of threads and their latest replies.
     return $this->apiResponse($board->getThreadsForCatalog());
 }
 /**
  * Supplies a clean thumbnail URL for embedding an attachment on a board.
  *
  * @param  App\Board  $board
  * @return string
  */
 public function getThumbnailURL(Board $board)
 {
     $baseURL = "/{$board->board_uri}/file/thumb/{$this->hash}/";
     $ext = $this->guessExtension();
     if ($this->isSpoiler()) {
         return $board->getSpoilerUrl();
     }
     if ($this->isImage()) {
         $ext = Settings::get('attachmentThumbnailJpeg') ? "jpg" : "png";
     } else {
         if ($this->isVideo()) {
             $ext = "jpg";
         } else {
             if ($this->isAudio()) {
                 if (!$this->hasThumb()) {
                     return $board->getAudioArtURL();
                 }
                 $ext = "png";
             } else {
                 if ($this->isImageVector()) {
                     // With the SVG filetype, we do not generate a thumbnail, so just serve the actual SVG.
                     $baseURL = "/{$board->board_uri}/file/{$this->hash}/";
                 }
             }
         }
     }
     return url("{$baseURL}{$this->getFileName()}.{$ext}");
 }
示例#29
0
 /**
  * Supplies a clean thumbnail URL for embedding an attachment on a board.
  *
  * @param  \App\Board  $board
  * @return string
  */
 public function getThumbnailURL(Board $board)
 {
     $ext = $this->guessExtension();
     if ($this->isSpoiler()) {
         return $board->getSpoilerUrl();
     }
     if ($this->isImage() || $this->isDocument()) {
         $ext = Settings::get('attachmentThumbnailJpeg') ? "jpg" : "png";
     } else {
         if ($this->isVideo()) {
             $ext = "jpg";
         } else {
             if ($this->isAudio()) {
                 if (!$this->hasThumb()) {
                     return $board->getAudioArtURL();
                 }
                 $ext = "png";
             } else {
                 if ($this->isImageVector()) {
                     // With the SVG filetype, we do not generate a thumbnail, so just serve the actual SVG.
                     return $this->getDownloadURL($board);
                 }
             }
         }
     }
     $params = ['attachment' => $this->getIdentifier(), 'filename' => $this->getDownloadName() . ".{$ext}"];
     if (!env('APP_MEDIA_URL', false)) {
         $params['board'] = $board;
     }
     // "False" generates a relativel URL.
     // Attachments get cached, so we want that.
     return route('static.thumb.attachment', $params, false);
 }
 /**
  * Manage threads that have expired.
  *
  * @param  App\Board  $board
  * @param  Carbon\Carbon  $time  Optional Carbon that will be the xed_at timestamps. Defaults to now.
  * @return void
  */
 protected function handleThreadEphemeral(Board $board, Carbon $time = null)
 {
     if (is_null($time)) {
         $time = Carbon::now();
     }
     // Get important settings.
     $threadsPerPage = (int) $board->getConfig('postsPerPage', 10);
     // Collect a list of threads which have been modified.
     $threadsToSave = [];
     // There are two groups of autoprune settings.
     // x on day since last reply
     $sageOnDay = (int) $board->getConfig('epheSageThreadDays', false);
     $lockOnDay = (int) $board->getConfig('epheLockThreadDays', false);
     $deleteOnDay = (int) $board->getConfig('epheDeleteThreadDays', false);
     // x on page (meaning the thread has fallen to this page)
     $sageOnPage = (int) $board->getConfig('epheSageThreadPage', false);
     $lockOnPage = (int) $board->getConfig('epheLockThreadPage', false);
     $deleteOnPage = (int) $board->getConfig('epheDeleteThreadPage', false);
     // Don't do anything unless we have to.
     if ($sageOnDay || $lockOnDay || $deleteOnDay || $sageOnPage || $lockOnPage || $deleteOnPage) {
         $this->comment("       Pruning /{$board->board_uri}/...");
         // Modify threads based on these settings.
         foreach ($board->threads as $threadIndex => $thread) {
             $threadPage = (int) (floor($threadIndex / $threadsPerPage) + 1);
             $modified = false;
             $replyLast = clone $thread->reply_last;
             // x on day since last reply
             // This is asking if:
             // 1) The setting is set ($x > 0)
             // 2) the last reply date + the number of days permitted by each setting is < now.
             if (!$thread->isBumplocked() && ($sageOnDay > 0 && $replyLast->addDays($sageOnDay)->isPast() || $sageOnPage > 0 && $sageOnPage <= $threadPage)) {
                 $this->comment("           Bumplocking #{$thread->board_id}");
                 $modified = true;
                 $thread->bumplocked_at = $time;
             }
             if (!$thread->isLocked() && ($lockOnDay > 0 && $replyLast->addDays($lockOnDay)->isPast() || $lockOnPage > 0 && $lockOnPage <= $threadPage)) {
                 $this->comment("           Locking #{$thread->board_id}");
                 $modified = true;
                 $thread->locked_at = $time;
             }
             if (!$thread->isDeleted() && ($deleteOnDay > 0 && $replyLast->addDays($sageOnDay)->isPast() || $deleteOnPage > 0 && $deleteOnPage <= $threadPage)) {
                 $this->comment("           Deleting #{$thread->board_id}");
                 $modified = true;
                 $thread->deleted_at = $time;
             }
             if ($modified) {
                 $threadsToSave[] = $thread;
             }
         }
         if (count($threadsToSave)) {
             // Save all at once.
             $board->threads()->saveMany($threadsToSave);
         } else {
             $this->comment("           Nothing to do.");
         }
     }
 }