Example #1
0
 /**
  * Gets a post by num or doc_d
  *
  * @return  \Foolz\Foolslide\Model\Board  The current object
  * @throws  BoardMalformedInputException  If the $num is not a valid post number
  * @throws  BoardMissingOptionsException  If doc_id or num has not been specified
  * @throws  BoardPostNotFoundException    If the post has not been found
  */
 protected function p_getPostComments()
 {
     extract($this->options);
     $query = $this->dc->qb()->select('*')->from($this->radix->getTable(), 'r');
     if (isset($num)) {
         if (!static::isValidPostNumber($num)) {
             throw new BoardMalformedInputException();
         }
         $num_arr = static::splitPostNumber($num);
         $query->where('num = :num')->andWhere('subnum = :subnum')->setParameter(':num', $num_arr['num'])->setParameter(':subnum', $num_arr['subnum']);
     } elseif (isset($doc_id)) {
         $query->where('doc_id = :doc_id')->setParameter(':doc_id', $doc_id);
     } else {
         throw new BoardMissingOptionsException(_i('No posts found with the submitted options.'));
     }
     $result = $query->leftJoin('r', $this->radix->getTable('_images'), 'mg', 'mg.media_id = r.media_id')->execute()->fetchAll();
     if (!count($result)) {
         throw new BoardPostNotFoundException(_i('Post not found.'));
     }
     foreach ($result as $bulk) {
         $data = new CommentBulk();
         $data->import($bulk, $this->radix);
         $this->comments_unsorted[] = $data;
     }
     foreach ($this->comments_unsorted as $comment) {
         $this->comments[$comment->comment->num . ($comment->comment->subnum ? '_' . $comment->comment->subnum : '')] = $comment;
     }
     return $this;
 }
Example #2
0
 /**
  * Gets the search results
  *
  * @return  \Foolz\Foolslide\Model\Search  The current object
  * @throws  SearchEmptyResultException     If there's no results to display
  * @throws  SearchRequiresSphinxException  If the search submitted requires Sphinx to run
  * @throws  SearchSphinxOfflineException   If the Sphinx server is unreachable
  * @throws  SearchInvalidException         If the values of the search weren't compatible with the domain
  */
 protected function p_getSearchComments()
 {
     $this->profiler->log('Board::getSearchComments Start');
     extract($this->options);
     // set all empty fields to null
     $search_fields = ['boards', 'subject', 'text', 'username', 'tripcode', 'email', 'capcode', 'uid', 'poster_ip', 'filename', 'image', 'deleted', 'ghost', 'filter', 'type', 'start', 'end', 'results', 'order'];
     foreach ($search_fields as $field) {
         if (!isset($args[$field])) {
             $args[$field] = null;
         }
     }
     // populate an array containing all boards that would be searched
     $boards = [];
     if ($args['boards'] !== null) {
         foreach ($args['boards'] as $board) {
             $b = $this->radix_coll->getByShortname($board);
             if ($b) {
                 $boards[] = $b;
             }
         }
     }
     // search all boards if none selected
     if (count($boards) == 0) {
         $boards = $this->radix_coll->getAll();
     }
     // if image is set, get either the media_hash or media_id
     if ($args['image'] !== null) {
         if (substr($args['image'], -2) !== '==') {
             $args['image'] .= '==';
         }
         // if board is set, retrieve media_id
         if ($this->radix !== null) {
             try {
                 $media = $this->media_factory->getByMediaHash($this->radix, $args['image']);
             } catch (MediaNotFoundException $e) {
                 $this->comments_unsorted = [];
                 $this->comments = [];
                 $this->profiler->log('Board::getSearchComments Ended Prematurely');
                 throw new SearchEmptyResultException(_i('No results found.'));
             }
             $args['image'] = $media->media_id;
         }
     }
     if ($this->radix === null && !$this->preferences->get('foolslide.sphinx.global')) {
         // global search requires sphinx
         throw new SearchRequiresSphinxException(_i('Sorry, this action requires the Sphinx to be installed and running.'));
     } elseif ($this->radix === null && $this->preferences->get('foolslide.sphinx.global') || $this->radix !== null && $this->radix->sphinx) {
         // configure sphinx connection params
         $sphinx = explode(':', $this->preferences->get('foolslide.sphinx.listen'));
         $conn = new SphinxConnnection();
         $conn->setParams(['host' => $sphinx[0], 'port' => $sphinx[1], 'options' => [MYSQLI_OPT_CONNECT_TIMEOUT => 5]]);
         $conn->silenceConnectionWarning(true);
         // determine if all boards will be used for search or not
         if ($this->radix == null) {
             $indexes = [];
             foreach ($boards as $radix) {
                 if (!$radix->sphinx) {
                     continue;
                 }
                 $indexes[] = $radix->shortname . '_ancient';
                 $indexes[] = $radix->shortname . '_main';
                 $indexes[] = $radix->shortname . '_delta';
             }
         } else {
             $indexes = [$this->radix->shortname . '_ancient', $this->radix->shortname . '_main', $this->radix->shortname . '_delta'];
         }
         // establish connection
         try {
             $query = SphinxQL::create($conn)->select('id', 'board')->from($indexes);
         } catch (\Foolz\SphinxQL\ConnectionException $e) {
             throw new SearchSphinxOfflineException(_i('The search backend is currently unavailable.'));
         }
         // parse search params
         if ($args['subject'] !== null) {
             $query->match('title', $args['subject']);
         }
         if ($args['text'] !== null) {
             if (mb_strlen($args['text'], 'utf-8') < 1) {
                 return [];
             }
             $query->match('comment', $args['text'], true);
         }
         if ($args['username'] !== null) {
             $query->match('name', $args['username']);
         }
         if ($args['tripcode'] !== null) {
             $query->match('trip', '"' . $args['tripcode'] . '"');
         }
         if ($args['email'] !== null) {
             $query->match('email', $args['email']);
         }
         if ($args['capcode'] !== null) {
             if ($args['capcode'] === 'user') {
                 $query->where('cap', ord('N'));
             } elseif ($args['capcode'] === 'mod') {
                 $query->where('cap', ord('M'));
             } elseif ($args['capcode'] === 'admin') {
                 $query->where('cap', ord('A'));
             } elseif ($args['capcode'] === 'dev') {
                 $query->where('cap', ord('D'));
             }
         }
         if ($args['uid'] !== null) {
             $query->match('pid', $args['uid']);
         }
         if ($this->getAuth()->hasAccess('comment.see_ip') && $args['poster_ip'] !== null) {
             $query->where('pip', (int) Inet::ptod($args['poster_ip']));
         }
         if ($args['filename'] !== null) {
             $query->match('media_filename', $args['filename']);
         }
         if ($args['image'] !== null) {
             if ($this->radix !== null) {
                 $query->where('mid', (int) $args['image']);
             } else {
                 $query->match('media_hash', '"' . $args['image'] . '"');
             }
         }
         if ($args['deleted'] !== null) {
             if ($args['deleted'] == 'deleted') {
                 $query->where('is_deleted', 1);
             }
             if ($args['deleted'] == 'not-deleted') {
                 $query->where('is_deleted', 0);
             }
         }
         if ($args['ghost'] !== null) {
             if ($args['ghost'] == 'only') {
                 $query->where('is_internal', 1);
             }
             if ($args['ghost'] == 'none') {
                 $query->where('is_internal', 0);
             }
         }
         if ($args['filter'] !== null) {
             if ($args['filter'] == 'image') {
                 $query->where('has_image', 0);
             }
             if ($args['filter'] == 'text') {
                 $query->where('has_image', 1);
             }
         }
         if ($args['type'] !== null) {
             if ($args['type'] == 'sticky') {
                 $query->where('is_sticky', 1);
             }
             if ($args['type'] == 'op') {
                 $query->where('is_op', 1);
             }
             if ($args['type'] == 'posts') {
                 $query->where('is_op', 0);
             }
         }
         if ($args['start'] !== null) {
             $query->where('timestamp', '>=', intval(strtotime($args['start'])));
         }
         if ($args['end'] !== null) {
             $query->where('timestamp', '<=', intval(strtotime($args['end'])));
         }
         if ($args['results'] !== null) {
             if ($args['results'] == 'op') {
                 $query->groupBy('thread_num');
                 $query->withinGroupOrderBy('is_op', 'desc');
             }
             if ($args['results'] == 'posts') {
                 $query->where('is_op', 0);
             }
         }
         if ($args['order'] !== null && $args['order'] == 'asc') {
             $query->orderBy('timestamp', 'ASC');
         } else {
             $query->orderBy('timestamp', 'DESC');
         }
         $max_matches = $this->preferences->get('foolslide.sphinx.max_matches', 5000);
         // set sphinx options
         $query->limit($limit)->offset($page * $limit - $limit >= $max_matches ? $max_matches - 1 : $page * $limit - $limit)->option('max_matches', (int) $max_matches)->option('reverse_scan', $args['order'] === 'asc' ? 0 : 1);
         // submit query
         try {
             $search = $query->execute();
         } catch (\Foolz\SphinxQL\DatabaseException $e) {
             $this->logger->error('Search Error: ' . $e->getMessage());
             throw new SearchInvalidException(_i('The search backend returned an error.'));
         }
         // no results found
         if (!count($search)) {
             $this->comments_unsorted = [];
             $this->comments = [];
             throw new SearchEmptyResultException(_i('No results found.'));
         }
         $sphinx_meta = Helper::pairsToAssoc(Helper::create($conn)->showMeta()->execute());
         $this->total_count = $sphinx_meta['total'];
         $this->total_found = $sphinx_meta['total_found'];
         // populate sql array for full records
         $sql = [];
         foreach ($search as $doc => $result) {
             $board = $this->radix_coll->getById($result['board']);
             $sql[] = $this->dc->qb()->select('*, ' . $result['board'] . ' AS board_id')->from($board->getTable(), 'r')->leftJoin('r', $board->getTable('_images'), 'mg', 'mg.media_id = r.media_id')->where('doc_id = ' . $this->dc->getConnection()->quote($result['id']))->getSQL();
         }
         $result = $this->dc->getConnection()->executeQuery(implode(' UNION ', $sql))->fetchAll();
     } else {
         // this is not implemented yet, would require some sort of MySQL search
         throw new SearchRequiresSphinxException(_i('Sorry, this board does not have search enabled.'));
     }
     // no results found IN DATABASE, but we might still get a search count from Sphinx
     if (!count($result)) {
         $this->comments_unsorted = [];
         $this->comments = [];
     } else {
         // process results
         foreach ($result as $key => $row) {
             $board = $this->radix !== null ? $this->radix : $this->radix_coll->getById($row['board_id']);
             $bulk = new CommentBulk();
             $bulk->import($row, $board);
             $this->comments_unsorted[] = $bulk;
             unset($result[$key]);
         }
     }
     $this->comments[0]['posts'] = $this->comments_unsorted;
     return $this;
 }
Example #3
0
 public function post_mod_actions()
 {
     if (!$this->checkCsrfToken()) {
         return $this->response->setData(['error' => _i('The security token was not found. Please try again.')]);
     }
     if (!$this->getAuth()->hasAccess('comment.mod_capcode')) {
         return $this->response->setData(['error' => _i('Access Denied.')])->setStatusCode(403);
     }
     if (!$this->check_board()) {
         return $this->response->setData(['error' => _i('No board was selected.')])->setStatusCode(422);
     }
     if ($this->getPost('action') === 'delete_report') {
         try {
             $this->report_coll->delete($this->getPost('id'));
         } catch (\Foolz\Foolslide\Model\ReportException $e) {
             return $this->response->setData(['error' => $e->getMessage()])->setStatusCode(404);
         }
         return $this->response->setData(['success' => _i('The report was deleted.')]);
     }
     if ($this->getPost('action') === 'delete_post') {
         try {
             $comments = Board::forge($this->getContext())->getPost()->setOptions('doc_id', $this->getPost('id'))->setRadix($this->radix)->getComments();
             $comment = current($comments);
             $comment = new Comment($this->getContext(), $comment);
             $comment->delete();
         } catch (\Foolz\Foolslide\Model\BoardException $e) {
             return $this->response->setData(['error' => $e->getMessage()])->setStatusCode(404);
         }
         return $this->response->setData(['success' => _i('This post was deleted.')]);
     }
     if ($this->getPost('action') === 'delete_image') {
         try {
             $media = $this->media_factory->getByMediaId($this->radix, $this->getPost('id'));
             $media = new Media($this->getContext(), CommentBulk::forge($this->radix, null, $media));
             $media->delete(true, true, true);
         } catch (\Foolz\Foolslide\Model\MediaNotFoundException $e) {
             return $this->response->setData(['error' => $e->getMessage()])->setStatusCode(404);
         }
         return $this->response->setData(['success' => _i('This image was deleted.')]);
     }
     if ($this->getPost('action') === 'ban_image_local' || $this->getPost('action') === 'ban_image_global') {
         $global = false;
         if ($this->getPost('action') === 'ban_image_global') {
             $global = true;
         }
         try {
             $media = $this->media_factory->getByMediaId($this->radix, $this->getPost('id'));
             $media = new Media($this->getContext(), CommentBulk::forge($this->radix, null, $media));
             $media->ban($global);
         } catch (\Foolz\Foolslide\Model\MediaNotFoundException $e) {
             return $this->response->setData(['error' => $e->getMessage()])->setStatusCode(404);
         }
         return $this->response->setData(['success' => _i('This image was banned.')]);
     }
     if ($this->getPost('action') === 'ban_user') {
         try {
             $this->ban_factory->add(Inet::ptod($this->getPost('ip')), $this->getPost('reason'), $this->getPost('length'), $this->getPost('board_ban') === 'global' ? array() : array($this->radix->id));
         } catch (\Foolz\Foolslide\Model\BanException $e) {
             return $this->response->setData(['error' => $e->getMessage()])->setStatusCode(404);
         }
         return $this->response->setData(['success' => _i('This user was banned.')]);
     }
 }
Example #4
0
 /**
  * Return a Media object by the media_hash column
  *
  * @param  Radix $radix  The Radix where the Media can be found
  * @param  string                        $value  The filename
  *
  * @return  \Foolz\Foolslide\Model\MediaData  The searched object
  * @throws  MediaNotFoundException        If the media has not been found
  */
 protected function p_getByFilename(Radix $radix, $filename)
 {
     $result = $this->dc->qb()->select('*')->from($radix->getTable(), 'r')->leftJoin('r', $radix->getTable('_images'), 'mg', 'mg.media_id = r.media_id')->where('r.media_orig = :media_orig')->setParameter(':media_orig', $filename)->execute()->fetch();
     if ($result) {
         $bulk = new CommentBulk();
         $bulk->import($result, $radix);
         return $bulk;
     }
     throw new MediaNotFoundException();
 }
Example #5
0
use Foolz\Foolslide\Model\Media;
$data_array = json_decode($data);
foreach ($data_array as $key => $item) {
    ?>
    <div class="image_reposts_image">
        <div class="image_reposts_number">
            <strong>#<?php 
    echo $key + 1;
    ?>
</strong> - Reposts: <?php 
    echo $item->total;
    ?>
        </div>

        <?php 
    $bulk = new CommentBulk();
    $bulk->import((array) $item, $this->radix);
    $media = new Media($this->getContext(), $bulk);
    $media->op = true;
    ?>

        <a href="<?php 
    echo $this->uri->create([$this->radix->shortname, 'search', 'image', $media->getSafeMediaHash()]);
    ?>
">
            <img src="<?php 
    echo $media->getThumbLink($this->getRequest());
    ?>
" />
        </a>
    </div>
Example #6
0
 /**
  * Inserts the media uploaded (static::forgeFromUpload())
  *
  * @param  string   $microtime  The time in microseconds to use for the local filename
  * @param  boolean  $is_op      True if the thumbnail sizes should be for OP, false if they should be for a reply
  *
  * @return  \Foolz\Foolslide\Model\Media       The current object updated with the insert data
  * @throws  MediaInsertInvalidFormatException  In case the media is not a valid format
  * @throws  MediaInsertDomainException         In case the media uploaded is in example too small or validations don't pass
  * @throws  MediaInsertRepostException         In case the media has been reposted too recently according to control panel settings
  * @throws  MediaThumbnailCreationException	   If the thumbnail fails to generate
  */
 public function p_insert($microtime, $is_op)
 {
     $file = $this->temp_file;
     $this->op = $is_op;
     $data = \Foolz\Plugin\Hook::forge('Foolz\\Foolslide\\Model\\Media::insert.result.media_data')->setParams(['dimensions' => getimagesize($file->getPathname()), 'file' => $file, 'name' => $file->getClientOriginalName(), 'path' => $file->getPathname(), 'hash' => base64_encode(pack("H*", md5(file_get_contents($file->getPathname())))), 'size' => $file->getClientSize(), 'time' => $microtime, 'media_orig' => $microtime . '.' . strtolower($file->getClientOriginalExtension()), 'preview_orig' => $microtime . 's.' . strtolower($file->getClientOriginalExtension())])->execute()->getParams();
     if (!($getimagesize = $data['dimensions'])) {
         throw new MediaInsertInvalidFormatException(_i('The file you uploaded is not allowed.'));
     }
     // if width and height are lower than 25 reject the image
     if ($getimagesize[0] < 25 || $getimagesize[1] < 25) {
         throw new MediaInsertDomainException(_i('The file you uploaded is too small.'));
     }
     if ($getimagesize[0] > $this->radix->getValue('max_image_size_width') || $getimagesize[1] > $this->radix->getValue('max_image_size_height')) {
         throw new MediaInsertDomainException(_i('The dimensions of the file you uploaded is too large.'));
     }
     $this->media->media_w = $getimagesize[0];
     $this->media->media_h = $getimagesize[1];
     $this->media->media_filename = $data['name'];
     $this->media->media_hash = $data['hash'];
     $this->media->media_size = $data['size'];
     $this->media->media_orig = $data['media_orig'];
     $this->media->preview_orig = $data['preview_orig'];
     $do_thumb = true;
     $do_full = true;
     try {
         $duplicate = CommentBulk::forge($this->radix, null, $this->media_factory->getByMediaHash($this->radix, $this->media->media_hash));
         $duplicate = new Media($this->getContext(), $duplicate);
         // we want the current media to work with the same filenames as previously stored
         $this->media->media_id = $duplicate->media->media_id;
         $this->media->media = $duplicate->media->media;
         $this->media->media_orig = $duplicate->media->media;
         $this->media->preview_op = $duplicate->media->preview_op;
         $this->media->preview_reply = $duplicate->media->preview_reply;
         if (!$this->getAuth()->hasAccess('comment.limitless_comment') && $this->radix->getValue('min_image_repost_time')) {
             // if it's -1 it means that image reposting is disabled, so this image shouldn't pass
             if ($this->radix->getValue('min_image_repost_time') == -1) {
                 throw new MediaInsertRepostException(_i('This image has already been posted once. This board doesn\'t allow image reposting.'));
             }
             // we don't have to worry about archives with weird timestamps, we can't post images there
             $duplicate_entry = $this->dc->qb()->select('COUNT(*) as count, MAX(timestamp) as max_timestamp')->from($this->radix->getTable(), 'r')->where('media_id = :media_id')->andWhere('timestamp > :timestamp')->setParameter('media_id', $duplicate->media->media_id)->setParameter('timestamp', time() - $this->radix->getValue('min_image_repost_time'))->setMaxResults(1)->execute()->fetch();
             if ($duplicate_entry['count']) {
                 $datetime = new \DateTime(date('Y-m-d H:i:s', $duplicate_entry['max_timestamp'] + $this->radix->getValue('min_image_repost_time')));
                 $remain = $datetime->diff(new \DateTime());
                 throw new MediaInsertRepostException(_i('This image has been posted recently. You will be able to post it again in %s.', ($remain->d > 0 ? $remain->d . ' ' . _i('day(s)') : '') . ' ' . ($remain->h > 0 ? $remain->h . ' ' . _i('hour(s)') : '') . ' ' . ($remain->i > 0 ? $remain->i . ' ' . _i('minute(s)') : '') . ' ' . ($remain->s > 0 ? $remain->s . ' ' . _i('second(s)') : '')));
             }
         }
         // if we're here, we got the media
         $duplicate_dir = $duplicate->getDir();
         if ($duplicate_dir !== null && file_exists($duplicate_dir)) {
             $do_full = false;
         }
         $duplicate->op = $is_op;
         $duplicate_dir_thumb = $duplicate->getDir(true, true);
         if ($duplicate_dir_thumb !== null && file_exists($duplicate_dir_thumb)) {
             $duplicate_dir_thumb_size = getimagesize($duplicate_dir_thumb);
             $this->media->preview_w = $duplicate_dir_thumb_size[0];
             $this->media->preview_h = $duplicate_dir_thumb_size[1];
             $do_thumb = false;
         }
     } catch (MediaNotFoundException $e) {
     }
     if ($do_thumb) {
         $thumb_width = $this->radix->getValue('thumbnail_reply_width');
         $thumb_height = $this->radix->getValue('thumbnail_reply_height');
         if ($is_op) {
             $thumb_width = $this->radix->getValue('thumbnail_op_width');
             $thumb_height = $this->radix->getValue('thumbnail_op_height');
         }
         if (!file_exists($this->pathFromFilename(true, $is_op))) {
             mkdir($this->pathFromFilename(true, $is_op), 0777, true);
         }
         $return = \Foolz\Plugin\Hook::forge('Foolz\\Foolslide\\Model\\Media::insert.result.create_thumbnail')->setObject($this)->setParams(['thumb_width' => $thumb_width, 'thumb_height' => $thumb_height, 'exec' => str_replace(' ', '\\ ', $this->preferences->get('foolframe.imagick.convert_path')), 'is_op' => $is_op, 'media' => $file, 'thumb' => $this->pathFromFilename(true, $is_op, true)])->execute()->get();
         if ($return instanceof \Foolz\Plugin\Void) {
             if ($this->radix->getValue('enable_animated_gif_thumbs') && strtolower($file->getClientOriginalExtension()) === 'gif') {
                 exec(str_replace(' ', '\\ ', $this->preferences->get('foolframe.imagick.convert_path')) . " " . $data['path'] . " -coalesce -treedepth 4 -colors 256 -quality 80 -background none " . "-resize \"" . $thumb_width . "x" . $thumb_height . ">\" " . $this->pathFromFilename(true, $is_op, true));
             } else {
                 exec(str_replace(' ', '\\ ', $this->preferences->get('foolframe.imagick.convert_path')) . " " . $data['path'] . "[0] -quality 80 -background none " . "-resize \"" . $thumb_width . "x" . $thumb_height . ">\" " . $this->pathFromFilename(true, $is_op, true));
             }
         }
         if (!file_exists($this->pathFromFilename(true, $is_op, true))) {
             throw new MediaThumbnailCreationException(_i('The thumbnail failed to generate.'));
         }
         $thumb_getimagesize = getimagesize($this->pathFromFilename(true, $is_op, true));
         $this->media->preview_w = $thumb_getimagesize[0];
         $this->media->preview_h = $thumb_getimagesize[1];
         if ($do_full) {
             if (!file_exists($this->pathFromFilename())) {
                 mkdir($this->pathFromFilename(), 0777, true);
             }
             copy($data['path'], $this->pathFromFilename(false, false, true));
         }
     }
     if (function_exists('exif_read_data') && in_array(strtolower($file->getClientOriginalExtension()), ['jpg', 'jpeg', 'tiff'])) {
         $exif_data = null;
         getimagesize($data['path'], $exif_data);
         if (!isset($exif_data['APP1']) || strpos($exif_data['APP1'], 'Exif') === 0) {
             $exif = exif_read_data($data['path']);
             if ($exif !== false) {
                 $this->media->exif = $exif;
             }
         }
     }
     if (!$this->media->media_id) {
         $this->dc->getConnection()->insert($this->radix->getTable('_images'), ['media_hash' => $this->media->media_hash, 'media' => $this->media->media_orig, 'preview_op' => $this->op ? $this->media->preview_orig : null, 'preview_reply' => !$this->op ? $this->media->preview_orig : null, 'total' => 1, 'banned' => 0]);
         $this->media->media_id = $this->dc->getConnection()->lastInsertId($this->radix->getTable('_images_media_id_seq'));
     } else {
         $media_sql = $this->dc->qb()->select('COUNT(*)')->from($this->radix->getTable(), 't')->where('media_id = :media_id')->setParameter(':media_id', $this->media->media_id)->getSQL();
         $query = $this->dc->qb()->update($this->radix->getTable('_images'));
         if ($this->media === null) {
             $query->set('media', ':media_orig')->setParameter(':media_orig', $this->media->preview_orig);
         }
         if ($this->op && $this->media->preview_op === null) {
             $query->set('preview_op', ':preview_orig')->setParameter(':preview_orig', $this->media->preview_orig);
         }
         if (!$this->op && $this->media->preview_reply === null) {
             $query->set('preview_reply', ':preview_orig')->setParameter(':preview_orig', $this->media->preview_orig);
         }
         $query->set('total', '(' . $media_sql . ')');
         $query->where('media_id = :media_id')->setParameter(':media_id', $this->media->media_id)->execute();
     }
     return $this;
 }
Example #7
0
 public function setBulk(CommentBulk $bulk)
 {
     $this->radix = $bulk->getRadix();
     $this->bulk = $bulk;
     $this->comment = $bulk->comment;
     $this->media = $bulk->media;
     $this->reports = null;
     // format 4chan archive timestamp
     if ($this->radix->archive && !$this->comment->isArchiveTimezone()) {
         $timestamp = new \DateTime(date('Y-m-d H:i:s', $this->comment->timestamp), new \DateTimeZone('America/New_York'));
         $timestamp->setTimezone(new \DateTimeZone('UTC'));
         $this->comment->timestamp = strtotime($timestamp->format('Y-m-d H:i:s'));
         if ($this->comment->timestamp_expired > 0) {
             $timestamp_expired = new \DateTime(date('Y-m-d H:i:s', $this->comment->timestamp_expired), new \DateTimeZone('America/New_York'));
             $timestamp_expired->setTimezone(new \DateTimeZone('UTC'));
             $this->comment->timestamp_expired = strtotime($timestamp_expired->format('Y-m-d H:i:s'));
         }
         $this->comment->setArchiveTimezone(true);
     }
     if ($this->comment->poster_country !== null) {
         $this->comment->poster_country_name = $this->config->get('foolz/foolslide', 'geoip_codes', 'codes.' . strtoupper($this->comment->poster_country));
     }
     $num = $this->comment->num . ($this->comment->subnum ? ',' . $this->comment->subnum : '');
     $this->comment_factory->posts[$this->comment->thread_num][] = $num;
 }
Example #8
0
 public function submit($data, $media)
 {
     // some beginners' validation, while through validation will happen in the Comment model
     $validator = new Validator();
     $validator->add('thread_num', _i('Thread Number'), [new Assert\NotBlank()])->add('name', _i('Name'), [new Assert\Length(['max' => 64])])->add('email', _i('Email'), [new Assert\Length(['max' => 64])])->add('title', _i('Title'), [new Assert\Length(['max' => 64])])->add('delpass', _i('Deletion pass'), [new Assert\Length(['min' => 3, 'max' => 32])]);
     // no empty posts without images
     if ($media === null) {
         $validator->add('comment', _i('Comment'), [new Assert\NotBlank(), new Assert\Length(['min' => 3])]);
     }
     // this is for redirecting, not for the database
     $limit = false;
     if (isset($data['last_limit'])) {
         $limit = intval($data['last_limit']);
         unset($data['last_limit']);
     }
     $validator->validate($data);
     if (!$validator->getViolations()->count()) {
         try {
             $data['poster_ip'] = Inet::ptod($this->getRequest()->getClientIp());
             $bulk = new CommentBulk();
             $bulk->import($data, $this->radix);
             $comment = new CommentInsert($this->getContext(), $bulk);
             $comment->insert($media, $data);
         } catch (\Foolz\Foolslide\Model\CommentSendingRequestCaptchaException $e) {
             if ($this->getRequest()->isXmlHttpRequest()) {
                 return $this->response->setData(['captcha' => true]);
             } else {
                 return $this->error(_i('Your message looked like spam. Make sure you have JavaScript enabled to display the reCAPTCHA to submit the comment.'));
             }
         } catch (\Foolz\Foolslide\Model\CommentSendingException $e) {
             if ($this->getRequest()->isXmlHttpRequest()) {
                 return $this->response->setData(['error' => $e->getMessage()]);
             } else {
                 return $this->error($e->getMessage());
             }
         }
     } else {
         if ($this->getRequest()->isXmlHttpRequest()) {
             return $this->response->setData(['error' => $validator->getViolations()->getText()]);
         } else {
             return $this->error($validator->getViolations()->getHtml());
         }
     }
     if ($this->request->isXmlHttpRequest()) {
         $latest_doc_id = $this->getPost('latest_doc_id');
         if ($latest_doc_id && ctype_digit((string) $latest_doc_id)) {
             try {
                 $board = Board::forge($this->getContext())->getThread($comment->comment->thread_num)->setRadix($this->radix)->setOptions(['type' => 'from_doc_id', 'latest_doc_id' => $latest_doc_id]);
                 $comments = $board->getComments();
             } catch (\Foolz\Foolslide\Model\BoardThreadNotFoundException $e) {
                 return $this->error(_i('Thread not found.'));
             } catch (\Foolz\Foolslide\Model\BoardException $e) {
                 return $this->error(_i('Unknown error.'));
             }
             $comment_obj = new Comment($this->getContext());
             $comment_obj->setControllerMethod($limit ? 'last/' . $limit : 'thread');
             $media_obj = new Media($this->getContext());
             $m = null;
             foreach ($board->getCommentsUnsorted() as $bulk) {
                 $comment_obj->setBulk($bulk, $this->radix);
                 if ($bulk->media) {
                     $media_obj->setBulk($bulk, $this->radix);
                     $m = $media_obj;
                 } else {
                     $m = null;
                 }
                 if ($this->builder) {
                     $this->param_manager->setParam('controller_method', $limit ? 'last/' . $limit : 'thread');
                     $partial = $this->builder->createPartial('board_comment', 'board_comment');
                     $partial->getParamManager()->setParam('p', $comment_obj)->setParam('p_media', $m);
                     $bulk->comment->formatted = $partial->build();
                     $partial->clearBuilt();
                 }
             }
             $this->response->setData(['success' => _i('Message sent.')] + $comments);
         } else {
             if ($this->builder) {
                 $this->param_manager->setParam('controller_method', $limit ? 'last/' . $limit : 'thread');
                 $partial = $this->builder->createPartial('board_comment', 'board_comment');
                 $partial->getParamManager()->setParam('p', new Comment($this->getContext(), $comment->bulk))->setParam('p_media', new Media($this->getContext(), $comment->bulk));
                 $bulk->comment->formatted = $partial->build();
                 $partial->clearBuilt();
             }
             $this->response->setData(['success' => _i('Message sent.'), 'thread_num' => $comment->comment->thread_num, $comment->comment->thread_num => ['posts' => [$comment->bulk]]]);
         }
     } else {
         $this->builder->createLayout('redirect')->getParamManager()->setParam('url', $this->uri->create([$this->radix->shortname, !$limit ? 'thread' : 'last/' . $limit, $comment->comment->thread_num]) . '#' . $comment->comment->num);
         $this->builder->getProps()->addTitle(_i('Redirecting'));
         $this->response->setContent($this->builder->build());
     }
     return $this->response;
 }