/**
  * Creates a new FileAttachment for a post using a hash.
  *
  * @param  Post  $post
  * @param  string  $filename
  * @param  boolean  $spoiler
  * @return FileAttachment
  */
 public function createAttachmentWithThis(Post $post, $filename, $spoiler = false, $autosave = true)
 {
     $fileName = pathinfo($filename, PATHINFO_FILENAME);
     $fileExt = $this->guessExtension();
     $attachment = new FileAttachment();
     $attachment->post_id = $post->post_id;
     $attachment->file_id = $this->file_id;
     $attachment->filename = urlencode("{$fileName}.{$fileExt}");
     $attachment->is_spoiler = !!$spoiler;
     if ($autosave) {
         $attachment->save();
         $this->upload_count++;
         $this->save();
     }
     return $attachment;
 }
 /**
  * Delete a post's attachment.
  *
  * @param  \App\FileAttachment  $attachment
  * @return Response
  */
 public function postSpoilerAttachment(Board $board, FileAttachment $attachment)
 {
     if (!$attachment->exists) {
         return abort(404);
     }
     $input = Input::all();
     $validator = Validator::make($input, ['scope' => "required|string|in:other,self", 'confirm' => "boolean|required_if:scope,other", 'password' => "string|required_if:scope,self"]);
     if (!$validator->passes()) {
         return redirect()->back()->withInput($input)->withErrors($validator->errors());
     }
     if ($input['scope'] == "other") {
         if ($this->user->canDeleteGlobally() || $this->user->canDeleteLocally($board)) {
             $this->log(!$attachment->is_spoiler ? 'log.attachment.spoiler' : 'log.attachment.unspoiler', $attachment->post, ["board_uri" => $attachment->post->board_uri, "board_id" => $attachment->post->board_id, "post_id" => $attachment->post->post_id, "file" => $attachment->storage->hash]);
         } else {
             abort(403);
         }
     } else {
         if ($input['scope'] == "self") {
             if ($this->user->canDeletePostWithPassword($board)) {
                 if (!$attachment->post->checkPassword($input['password'])) {
                     return redirect()->back()->withInput($input)->withErrors(['password' => \Lang::trans('validation.password', ['attribute' => "password"])]);
                 }
             }
         }
     }
     $attachment->is_spoiler = !$attachment->is_spoiler;
     $attachment->save();
     Event::fire(new AttachmentWasModified($attachment));
     return redirect($attachment->post->getURL());
 }
 /**
  * Creates a new FileAttachment for a post.
  *
  * @param  UploadedFile  $file
  * @param  Post  $post
  * @return FileAttachment
  */
 public static function createAttachment(UploadedFile $file, Post $post)
 {
     $storage = static::storeUpload($file);
     $uploadName = urlencode($file->getClientOriginalName());
     $uploadExt = pathinfo($uploadName, PATHINFO_EXTENSION);
     $fileName = basename($uploadName, "." . $uploadExt);
     $fileExt = $storage->guessExtension();
     $attachment = new FileAttachment();
     $attachment->post_id = $post->post_id;
     $attachment->file_id = $storage->file_id;
     $attachment->filename = urlencode("{$fileName}.{$fileExt}");
     $attachment->save();
     return $attachment;
 }
Exemple #4
0
 /**
  * Pushes the post to the specified board, as a new thread or as a reply.
  * This autoatically handles concurrency issues. Creating a new reply without
  * using this method is forbidden by the `creating` event in ::boot.
  *
  *
  * @param  App\Board  &$board
  * @param  App\Post   &$thread
  * @return void
  */
 public function submitTo(Board &$board, &$thread = null)
 {
     $this->board_uri = $board->board_uri;
     $this->author_ip = Request::getClientIp();
     $this->reply_last = $this->freshTimestamp();
     $this->bumped_last = $this->reply_last;
     $this->setCreatedAt($this->reply_last);
     $this->setUpdatedAt($this->reply_last);
     if (!is_null($thread) && !$thread instanceof Post) {
         $thread = $board->getLocalThread($thread);
         $this->reply_to = $thread->post_id;
         $this->reply_to_board_id = $thread->board_id;
     }
     // Store attachments
     $uploads = [];
     if (is_array($files = Input::file('files'))) {
         $uploads = array_filter($files);
     }
     // Store the post in the database.
     DB::transaction(function () use($thread) {
         // The objective of this transaction is to prevent concurrency issues in the database
         // on the unique joint index [`board_uri`,`board_id`] which is generated procedurally
         // alongside the primary autoincrement column `post_id`.
         // First instruction is to add +1 to posts_total.
         DB::table('boards')->where('board_uri', $this->board_uri)->increment('posts_total');
         // Second, we record this value and lock the table.
         $boards = DB::table('boards')->where('board_uri', $this->board_uri)->lockForUpdate()->select('posts_total')->get();
         $posts_total = $boards[0]->posts_total;
         // Optionally, the OP of this thread needs a +1 to reply count.
         if ($thread instanceof Post) {
             if (!$this->isBumpless() && !$thread->isBumplocked()) {
                 $thread->bumped_last = $this->created_at;
             }
             $thread->reply_last = $this->created_at;
             $thread->reply_count += 1;
             $thread->save();
         }
         // Finally, we set our board_id and save.
         $this->board_id = $posts_total;
         $this->save();
         // Queries and locks are handled automatically after this closure ends.
     });
     // Process uploads.
     if (count($uploads) > 0) {
         foreach ($uploads as $uploadIndex => $upload) {
             if (file_exists($upload->getPathname())) {
                 $uploadName = urlencode($upload->getClientOriginalName());
                 $uploadExt = pathinfo($uploadName, PATHINFO_EXTENSION);
                 $fileName = basename($uploadName, "." . $uploadExt);
                 $fileExt = $upload->guessExtension();
                 $storage = FileStorage::storeUpload($upload);
                 $attachment = new FileAttachment();
                 $attachment->post_id = $this->post_id;
                 $attachment->file_id = $storage->file_id;
                 $attachment->filename = urlencode("{$fileName}.{$fileExt}");
                 $attachment->save();
             }
         }
     }
     // Finally fire event on OP, if it exists.
     if ($thread instanceof Post) {
         Event::fire(new ThreadNewReply($thread));
     }
 }