예제 #1
0
 public function action_login()
 {
     // redirect user to admin panel
     if ($this->getAuth()->hasAccess('maccess.user')) {
         return $this->redirectToAdmin();
     }
     // the login button has been submitted - authenticate username and password
     if ($this->getPost() && !$this->security->checkCsrfToken($this->getRequest())) {
         $this->notices->set('error', _i('The security token was not found. Please try again.'));
     } elseif ($this->getPost()) {
         // load authentication instance
         // verify credentials
         try {
             $this->getAuth()->authenticateWithUsernameAndPassword($this->getPost('username', ''), $this->getPost('password', ''));
             $rememberme_token = $this->getAuth()->createAutologinHash(Inet::ptod($this->getRequest()->getClientIp()), $this->getRequest()->headers->get('User-Agent'));
             $response = new RedirectResponse($this->uri->create('admin'));
             //$this->getRequest()->getSession()->set('rememberme', $rememberme_token);
             if ($this->getPost('remember')) {
                 $response->headers->setCookie(new Cookie($this->getContext(), 'rememberme', $rememberme_token, 365 * 24 * 60 * 60));
             }
             return $response;
         } catch (WrongUsernameOrPasswordException $e) {
             $this->notices->set('error', _i('You have entered an invalid username and/or password. Please try again.'));
         }
     }
     // generate login form
     $this->param_manager->setParam('method_title', _i('Login'));
     $this->builder->createLayout('account');
     $this->builder->createPartial('body', 'account/login');
     return new Response($this->builder->build());
 }
예제 #2
0
 public function blockCountryComment(Result $result)
 {
     /** @var Comment $obj */
     $obj = $result->getObject();
     // globally allowed and disallowed
     $allow = $this->preferences->get('foolfuuka.plugins.geoip_region_lock.allow_comment');
     $disallow = $this->preferences->get('foolfuuka.plugins.geoip_region_lock.disallow_comment');
     $board_allow = trim($obj->radix->getValue('plugin_geo_ip_region_lock_allow_comment'), " ,");
     $board_disallow = trim($obj->radix->getValue('plugin_geo_ip_region_lock_disallow_comment'), " ,");
     // allow board settings to override global
     if ($board_allow || $board_disallow) {
         $allow = $board_allow;
         $disallow = $board_disallow;
     }
     if ($allow || $disallow) {
         $ip = Inet::dtop($obj->comment->poster_ip);
         $reader = new Reader($this->preferences->get('foolframe.maxmind.geoip2_db_path'));
         $country = null;
         try {
             $record = $reader->country($ip);
             $country = strtolower($record->country->isoCode);
         } catch (AddressNotFoundException $e) {
             $country = 'xx';
         }
         if ($allow) {
             $allow = array_filter(explode(',', $allow));
             foreach ($allow as $al) {
                 if (strtolower(trim($al)) === $country) {
                     return;
                 }
             }
             throw new CommentSendingException(_i('Your nation has been blocked from posting.') . '<br/><br/>This product includes GeoLite2 data created by MaxMind, available from http://www.maxmind.com/');
         }
         if ($disallow) {
             $disallow = array_filter(explode(',', $disallow));
             foreach ($disallow as $disal) {
                 if (strtolower(trim($disal)) == $country) {
                     throw new CommentSendingException(_i('Your nation has been blocked from posting.') . '<br/><br/>This product includes GeoLite2 data created by MaxMind, available from http://www.maxmind.com/');
                 }
             }
         }
     }
 }
예제 #3
0
    public function toString()
    {
        $controller_method = $this->getBuilderParamManager()->getParam('controller_method', 'thread');
        $p = $this->getParamManager()->getParam('p');
        $p_media = $this->getParamManager()->getParam('p_media');
        if ($this->getParamManager()->getParam('modifiers', false)) {
            $modifiers = $this->getParamManager()->getParam('modifiers');
        }
        $num = $p->num . ($p->subnum ? '_' . $p->subnum : '');
        ?>
        <div class="post stub stub_doc_id_<?php 
        echo $p->doc_id;
        ?>
">
                <button class="btn-toggle-post" data-function="showPost" data-board="<?php 
        echo $p->radix->shortname;
        ?>
"  data-doc-id="<?php 
        echo $p->doc_id;
        ?>
" data-thread-num="<?php 
        echo $p->thread_num;
        ?>
"><i class="icon-plus"></i></button>
                <?php 
        if ($p->email && $p->email !== 'noko') {
            ?>
<a href="mailto:<?php 
            echo rawurlencode($p->email);
            ?>
"><?php 
        }
        ?>
<span class="post_author"><?php 
        echo $p->getNameProcessed();
        ?>
</span><?php 
        echo $p->getNameProcessed() && $p->getTripProcessed() ? ' ' : '';
        ?>
<span class="post_tripcode"><?php 
        echo $p->getTripProcessed();
        ?>
</span><?php 
        if ($p->email && $p->email !== 'noko') {
            ?>
</a><?php 
        }
        ?>
        </div>
        <article class="post doc_id_<?php 
        echo $p->doc_id;
        if ($p->subnum > 0) {
            ?>
 post_ghost<?php 
        }
        if ($p->thread_num === $p->num) {
            ?>
 post_is_op<?php 
        }
        if (!is_null($p_media)) {
            ?>
 has_image<?php 
        }
        ?>
" id="<?php 
        echo $num;
        ?>
">
            <div class="stub pull-left">
                <button class="btn-toggle-post" data-function="hidePost" data-board="<?php 
        echo $p->radix->shortname;
        ?>
" data-doc-id="<?php 
        echo $p->doc_id;
        ?>
"><i class="icon-minus"></i></button>
            </div>
            <div class="<?php 
        if ($p->capcode === 'A') {
            ?>
adminpost<?php 
        }
        ?>
 post_wrapper">
                <?php 
        if ($p_media !== null) {
            ?>
                <div class="post_file" style="overflow:visible;">
                    <span class="post_file_controls">
                    <?php 
            if ($p_media->getMediaStatus($this->getRequest()) !== 'banned' || $this->getAuth()->hasAccess('media.see_hidden')) {
                ?>
                        <?php 
                if (!$p->radix->hide_thumbnails || $this->getAuth()->hasAccess('media.see_hidden')) {
                    ?>
                            <?php 
                    $dropdowntest = 0;
                    if ($dropdowntest === 1) {
                        ?>
                            <a href="<?php 
                        echo $this->getUri()->create((isset($modifiers['post_show_board_name']) && $modifiers['post_show_board_name'] ? '_' : $p->radix->shortname) . '/search/image/' . $p_media->getSafeMediaHash());
                        ?>
" class="btnr parent"><?php 
                        echo _i('View Same');
                        ?>
</a>
                            <a href="http://google.com/searchbyimage?image_url=<?php 
                        echo $p_media->getThumbLink($this->getRequest());
                        ?>
" target="_blank" class="btnr parent">Google</a>
                            <a href="http://iqdb.org/?url=<?php 
                        echo $p_media->getThumbLink($this->getRequest());
                        ?>
" target="_blank" class="btnr parent">iqdb</a>
                            <a href="http://saucenao.com/search.php?url=<?php 
                        echo $p_media->getThumbLink($this->getRequest());
                        ?>
" target="_blank" class="btnr parent">SauceNAO</a>
                            <?php 
                    } else {
                        ?>
                            <div class="saucenav">
                                <ul>
                                    <li class="btnr parent"><a href="#" onclick="return false;">Image Search</a>
                                        <ul class="saucenav-reply">
                                            <li><a href="<?php 
                        echo $this->getUri()->create((isset($modifiers['post_show_board_name']) && $modifiers['post_show_board_name'] ? '_' : $p->radix->shortname) . '/search/image/' . $p_media->getSafeMediaHash());
                        ?>
"><?php 
                        echo _i('View Same');
                        ?>
</a></li>
                                            <li><a href="http://google.com/searchbyimage?image_url=<?php 
                        echo $p_media->getThumbLink($this->getRequest());
                        ?>
" target="_blank">Google</a></li>
                                            <li><a href="http://iqdb.org/?url=<?php 
                        echo $p_media->getThumbLink($this->getRequest());
                        ?>
" target="_blank">Iqdb</a></li>
                                            <li><a href="http://saucenao.com/search.php?url=<?php 
                        echo $p_media->getThumbLink($this->getRequest());
                        ?>
" target="_blank">SauceNAO</a></li>
                                        </ul>
                                    </li>
                                </ul>
                            </div>
                            <?php 
                    }
                    ?>
                            <?php 
                    if (!$p->radix->archive || $p->radix->getValue('archive_full_images')) {
                        ?>
                                <a href="<?php 
                        echo $p_media->getMediaDownloadLink($this->getRequest());
                        ?>
" download="<?php 
                        echo $p_media->getMediaFilenameProcessed();
                        ?>
" style="border-color: #9E9E9E!important;" class="btnr parent"><i class="icon-download-alt"></i></a>
                            <?php 
                    }
                    ?>
                        <?php 
                }
                ?>
                    <?php 
            }
            ?>
                    </span>
                    <?php 
            if ($p_media->getMediaStatus($this->getRequest()) !== 'banned' || $this->getAuth()->hasAccess('media.see_banned')) {
                ?>
                    <?php 
                if (mb_strlen($p_media->getMediaFilenameProcessed()) > 35) {
                    ?>
                        <a href="<?php 
                    echo $p_media->getMediaLink($this->getRequest()) ? $p_media->getMediaLink($this->getRequest()) : $p_media->getRemoteMediaLink($this->getRequest());
                    ?>
" class="post_file_filename" rel="tooltip" title="<?php 
                    echo htmlspecialchars($p_media->media_filename);
                    ?>
" target="_blank"><?php 
                    echo mb_substr($p_media->getMediaFilenameProcessed(), 0, 30, 'utf-8') . ' (...)' . mb_substr($p_media->getMediaFilenameProcessed(), mb_strrpos($p_media->getMediaFilenameProcessed(), '.', 'utf-8'), null, 'utf-8');
                    ?>
</a>,
                    <?php 
                } else {
                    ?>
                        <a href="<?php 
                    echo $p_media->getMediaLink($this->getRequest()) ? $p_media->getMediaLink($this->getRequest()) : $p_media->getRemoteMediaLink($this->getRequest());
                    ?>
" class="post_file_filename" rel="tooltip" title="<?php 
                    echo htmlspecialchars($p_media->media_filename);
                    ?>
" target="_blank"><?php 
                    echo $p_media->getMediaFilenameProcessed();
                    ?>
</a>,
                    <?php 
                }
                ?>
                    <span class="post_file_metadata">
                        <?php 
                echo \Rych\ByteSize\ByteSize::formatBinary($p_media->media_size, 0) . ', ' . $p_media->media_w . 'x' . $p_media->media_h;
                ?>
                    </span>
                    <?php 
            }
            ?>
                </div>
                <div class="thread_image_box">
                    <?php 
            if ($p_media->getMediaStatus($this->getRequest()) === 'banned') {
                ?>
                        <img src="<?php 
                echo $this->getAssetManager()->getAssetLink('images/banned-image.png');
                ?>
" width="150" height="150" />
                    <?php 
            } elseif ($p_media->getMediaStatus($this->getRequest()) !== 'normal') {
                ?>
                        <a href="<?php 
                echo $p_media->getMediaLink($this->getRequest()) ? $p_media->getMediaLink($this->getRequest()) : $p_media->getRemoteMediaLink($this->getRequest());
                ?>
" target="_blank" rel="noreferrer" class="thread_image_link">
                            <img src="<?php 
                echo $this->getAssetManager()->getAssetLink('images/missing-image.jpg');
                ?>
" width="150" height="150" />
                        </a>
                    <?php 
            } else {
                ?>
                        <a href="<?php 
                echo $p_media->getMediaLink($this->getRequest()) ? $p_media->getMediaLink($this->getRequest()) : $p_media->getRemoteMediaLink($this->getRequest());
                ?>
" target="_blank" rel="noreferrer" class="thread_image_link">
                            <?php 
                if (!$this->getAuth()->hasAccess('maccess.mod') && !$p->radix->getValue('transparent_spoiler') && $p_media->spoiler) {
                    ?>
                            <div class="spoiler_box"><span class="spoiler_box_text"><?php 
                    echo _i('Spoiler');
                    ?>
<span class="spoiler_box_text_help"><?php 
                    echo _i('Click to view');
                    ?>
</span></div>
                            <?php 
                } elseif (isset($modifiers['lazyload']) && $modifiers['lazyload'] == true) {
                    ?>
                            <img src="<?php 
                    echo $this->getUri()->base() . $this->getAssetManager()->getAssetLink('images/transparent_pixel.png');
                    ?>
" data-original="<?php 
                    echo $p_media->getThumbLink($this->getRequest());
                    ?>
" width="<?php 
                    echo $p_media->preview_w;
                    ?>
" height="<?php 
                    echo $p_media->preview_h;
                    ?>
" class="lazyload post_image<?php 
                    echo $p_media->spoiler ? ' is_spoiler_image' : '';
                    ?>
" data-md5="<?php 
                    echo $p_media->media_hash;
                    ?>
" />
                            <noscript>
                                <a href="<?php 
                    echo $p_media->getMediaLink($this->getRequest()) ? $p_media->getMediaLink($this->getRequest()) : $p_media->getRemoteMediaLink($this->getRequest());
                    ?>
" target="_blank" rel="noreferrer" class="thread_image_link">
                                    <img src="<?php 
                    echo $p_media->getThumbLink($this->getRequest());
                    ?>
" style="margin-left: -<?php 
                    echo $p_media->preview_w;
                    ?>
px" width="<?php 
                    echo $p_media->preview_w;
                    ?>
" height="<?php 
                    echo $p_media->preview_h;
                    ?>
" class="lazyload post_image<?php 
                    echo $p_media->spoiler ? ' is_spoiler_image' : '';
                    ?>
" data-md5="<?php 
                    echo $p_media->media_hash;
                    ?>
" />
                                </a>
                            </noscript>
                            <?php 
                } else {
                    ?>
                            <img src="<?php 
                    echo $p_media->getThumbLink($this->getRequest());
                    ?>
" width="<?php 
                    echo $p_media->preview_w;
                    ?>
" height="<?php 
                    echo $p_media->preview_h;
                    ?>
" class="lazyload post_image<?php 
                    echo $p_media->spoiler ? ' is_spoiler_image' : '';
                    ?>
" imgstate="normal" smsize="<?php 
                    echo $p->media->preview_w . "x" . $p->media->preview_h;
                    ?>
" data-md5="<?php 
                    echo $p_media->media_hash;
                    ?>
" />
                            <?php 
                }
                ?>
                        </a>
                    <?php 
            }
            ?>
                </div>
                <?php 
        }
        ?>
                <header>
                    <div class="post_data">
                        <?php 
        if (isset($modifiers['post_show_board_name']) && $modifiers['post_show_board_name']) {
            ?>
                        <span class="post_show_board">/<?php 
            echo $p->radix->shortname;
            ?>
/</span>
                        <?php 
        }
        ?>

                        <?php 
        if ($p->getTitleProcessed() !== '') {
            ?>
<h2 class="post_title"><?php 
            echo $p->getTitleProcessed();
            ?>
</h2><?php 
        }
        ?>
                        <span class="post_poster_data">
                            <?php 
        if ($p->email && $p->email !== 'noko') {
            ?>
<a href="mailto:<?php 
            echo rawurlencode($p->email);
            ?>
"><?php 
        }
        ?>
<span class="post_author"><?php 
        echo $p->getNameProcessed();
        ?>
</span><?php 
        echo $p->getNameProcessed() && $p->getTripProcessed() ? ' ' : '';
        ?>
<span class="post_tripcode"><?php 
        echo $p->getTripProcessed();
        ?>
</span><?php 
        if ($p->email && $p->email !== 'noko') {
            ?>
</a><?php 
        }
        ?>

                            <?php 
        if ($p->getPosterHashProcessed()) {
            ?>
<span class="poster_hash">ID:<?php 
            echo $p->getPosterHashProcessed();
            ?>
</span><?php 
        }
        ?>
                            <?php 
        if ($p->capcode !== 'N') {
            ?>
                                <?php 
            if ($p->capcode === 'M') {
                ?>
<span class="post_level post_level_moderator">## <?php 
                echo _i('Mod');
                ?>
</span><?php 
            }
            ?>
                                <?php 
            if ($p->capcode === 'A') {
                ?>
<span class="post_level post_level_administrator">## <?php 
                echo _i('Admin');
                ?>
</span><?php 
            }
            ?>
                                <?php 
            if ($p->capcode === 'D') {
                ?>
<span class="post_level post_level_developer">## <?php 
                echo _i('Developer');
                ?>
</span><?php 
            }
            ?>
                            <?php 
        }
        ?>
                        </span>
                        <span class="time_wrap">
                            <time datetime="<?php 
        echo gmdate(DATE_W3C, $p->timestamp);
        ?>
" <?php 
        if ($p->radix->archive) {
            ?>
 title="<?php 
            echo _i('4chan Time') . ': ' . $p->getFourchanDate();
            ?>
"<?php 
        }
        ?>
><?php 
        echo gmdate('D d M Y H:i:s', $p->timestamp);
        ?>
</time>
                        </span>
                        <a href="<?php 
        echo $this->getUri()->create([$p->radix->shortname, $controller_method, $p->thread_num]) . '#' . $num;
        ?>
" data-post="<?php 
        echo $num;
        ?>
" data-function="highlight">No.</a><a href="<?php 
        echo $this->getUri()->create([$p->radix->shortname, $controller_method, $p->thread_num]) . '#q' . $num;
        ?>
" data-post="<?php 
        echo str_replace('_', ',', $num);
        ?>
" data-function="quote"><?php 
        if ($p->capcode === 'L') {
            echo str_replace('_', ',', 1999999999);
        } else {
            echo str_replace('_', ',', $num);
        }
        ?>
</a>

                        <span class="post_type">
                            <?php 
        if ($p->poster_country !== null) {
            ?>
<span title="<?php 
            echo e($p->poster_country_name);
            ?>
" class="flag flag-<?php 
            echo strtolower($p->poster_country);
            ?>
"></span><?php 
        }
        ?>
                            <?php 
        if ($p->subnum) {
            ?>
<i class="icon-comment-alt" title="<?php 
            echo htmlspecialchars(_i('This post was submitted as a "ghost" reply.'));
            ?>
"></i><?php 
        }
        ?>
                            <?php 
        if (isset($p_media) && $p_media->spoiler) {
            ?>
<i class="icon-eye-close" title="<?php 
            echo htmlspecialchars(_i('The image in this post has been marked spoiler.'));
            ?>
"></i><?php 
        }
        ?>
                            <?php 
        if ($p->deleted && !$p->timestamp_expired) {
            ?>
<i class="icon-trash" title="<?php 
            echo htmlspecialchars(_i('This post was prematurely deleted.'));
            ?>
"></i><?php 
        }
        ?>
                            <?php 
        if ($p->deleted && $p->timestamp_expired) {
            ?>
<i class="icon-trash" title="<?php 
            echo htmlspecialchars(_i('This post was deleted on %s.', gmdate('M d, Y \\a\\t H:i:s e', $p->timestamp_expired)));
            ?>
"></i><?php 
        }
        ?>
                            <?php 
        if ($p->sticky) {
            ?>
<i class="icon-pushpin" title="<?php 
            echo _i('This thread has been stickied.');
            ?>
"></i><?php 
        }
        ?>
                            <?php 
        if ($p->locked) {
            ?>
<i class="icon-lock" title="<?php 
            echo _i('This thread has been locked.');
            ?>
"></i><?php 
        }
        ?>
                        </span>

                        <span class="post_controls">
                            <?php 
        if (isset($modifiers['post_show_view_button'])) {
            ?>
<a href="<?php 
            echo $this->getUri()->create($p->radix->shortname . '/thread/' . $p->thread_num) . '#' . $num;
            ?>
" class="btnr parent"><?php 
            echo _i('View');
            ?>
</a><?php 
        }
        ?>
<a href="#" class="btnr parent" data-post="<?php 
        echo $p->doc_id;
        ?>
" data-post-id="<?php 
        echo $num;
        ?>
" data-board="<?php 
        echo htmlspecialchars($p->radix->shortname);
        ?>
" data-controls-modal="post_tools_modal" data-backdrop="true" data-keyboard="true" data-function="report"><?php 
        echo _i('Report');
        ?>
</a><?php 
        if ($p->subnum > 0 || $this->getAuth()->hasAccess('comment.passwordless_deletion') || !$p->radix->archive) {
            ?>
<a href="#" class="btnr parent" data-post="<?php 
            echo $p->doc_id;
            ?>
" data-post-id="<?php 
            echo $num;
            ?>
" data-board="<?php 
            echo htmlspecialchars($p->radix->shortname);
            ?>
" data-controls-modal="post_tools_modal" data-backdrop="true" data-keyboard="true" data-function="delete"><?php 
            echo _i('Delete');
            ?>
</a><?php 
        }
        ?>
                        </span>
                    </div>
                </header>
                <div class="backlink_list"<?php 
        echo $p->getBacklinks() ? ' style="display:block"' : '';
        ?>
>
                    <?php 
        echo _i('Quoted By:');
        ?>
 <span class="post_backlink" data-post="<?php 
        echo $p->num;
        ?>
"><?php 
        echo $p->getBacklinks() ? implode(' ', $p->getBacklinks()) : '';
        ?>
</span>
                </div>
                <div class="text<?php 
        if (preg_match('/[\\x{4E00}-\\x{9FBF}\\x{3040}-\\x{309F}\\x{30A0}-\\x{30FF}]/u', $p->getCommentProcessed())) {
            echo ' shift-jis';
        }
        ?>
">
                    <?php 
        echo $p->getCommentProcessed();
        ?>
                </div>
                <?php 
        if ($this->getAuth()->hasAccess('maccess.mod')) {
            ?>
                <div class="btn-group" style="clear:both; padding:5px 0 0 0;">
                    <button class="btn btn-mini" data-function="activateModeration"><?php 
            echo _i('Mod');
            if ($p->poster_ip) {
                echo ' ' . Inet::dtop($p->poster_ip);
            }
            ?>
</button>
                </div>
                <div class="btn-group post_mod_controls" style="clear:both; padding:5px 0 0 5px;">
                    <?php 
            if ($p->op) {
                ?>
                    <button class="btn btn-mini" data-function="mod" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-id="<?php 
                echo $p->doc_id;
                ?>
" data-action="toggle_sticky"><?php 
                echo _i('Toggle Sticky');
                ?>
</button>
                    <button class="btn btn-mini" data-function="mod" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-id="<?php 
                echo $p->doc_id;
                ?>
" data-action="toggle_locked"><?php 
                echo _i('Toggle Locked');
                ?>
</button>
                    <?php 
            }
            ?>
                    <button class="btn btn-mini" data-function="mod" data-board="<?php 
            echo $p->radix->shortname;
            ?>
" data-board-url="<?php 
            echo $this->getUri()->create([$p->radix->shortname]);
            ?>
" data-id="<?php 
            echo $p->doc_id;
            ?>
" data-action="delete_post"><?php 
            echo _i('Delete Post');
            ?>
</button>
                    <?php 
            if (!is_null($p_media)) {
                ?>
                        <button class="btn btn-mini" data-function="mod" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-id="<?php 
                echo $p_media->media_id;
                ?>
" data-doc-id="<?php 
                echo $p->doc_id;
                ?>
" data-action="delete_image"><?php 
                echo _i('Delete Image');
                ?>
</button>
                        <button class="btn btn-mini" data-function="mod" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-id="<?php 
                echo $p_media->media_id;
                ?>
" data-doc-id="<?php 
                echo $p->doc_id;
                ?>
" data-action="ban_image_local"><?php 
                echo _i('Ban Image');
                ?>
</button>
                        <button class="btn btn-mini" data-function="mod" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-id="<?php 
                echo $p_media->media_id;
                ?>
" data-doc-id="<?php 
                echo $p->doc_id;
                ?>
" data-action="ban_image_global"><?php 
                echo _i('Ban Image Globally');
                ?>
</button>
                    <?php 
            }
            ?>
                    <?php 
            if ($p->poster_ip) {
                ?>
                        <button class="btn btn-mini" data-function="ban" data-controls-modal="post_tools_modal" data-backdrop="true" data-keyboard="true" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-ip="<?php 
                echo Inet::dtop($p->poster_ip);
                ?>
" data-action="ban_user"><?php 
                echo _i('Ban IP:') . ' ' . Inet::dtop($p->poster_ip);
                ?>
</button>
                        <button class="btn btn-mini" data-function="searchUser" data-board="<?php 
                echo $p->radix->shortname;
                ?>
" data-id="<?php 
                echo $p->doc_id;
                ?>
" data-poster-ip="<?php 
                echo Inet::dtop($p->poster_ip);
                ?>
"><?php 
                echo _i('Search IP');
                ?>
</button>
                        <?php 
                if ($this->getPreferences()->get('foolfuuka.sphinx.global')) {
                    ?>
                            <button class="btn btn-mini" data-function="searchUserGlobal" data-board="<?php 
                    echo $p->radix->shortname;
                    ?>
" data-id="<?php 
                    echo $p->doc_id;
                    ?>
" data-poster-ip="<?php 
                    echo Inet::dtop($p->poster_ip);
                    ?>
"><?php 
                    echo _i('Search IP Globally');
                    ?>
</button>
                        <?php 
                }
                ?>
                    <?php 
            }
            ?>
                </div>
                <?php 
            if ($p->getReports()) {
                ?>
                    <?php 
                foreach ($p->getReports() as $report) {
                    ?>
                        <div class="report_reason"><?php 
                    echo '<strong>' . _i('Reported Reason:') . '</strong> ' . $report->getReasonProcessed();
                    ?>
                            <br/>
                            <div class="ip_reporter">
                                <strong><?php 
                    echo _i('Info:');
                    ?>
</strong>
                                <?php 
                    echo Inet::dtop($report->ip_reporter);
                    ?>
, <?php 
                    echo _i('Type:');
                    ?>
 <?php 
                    echo $report->media_id !== null ? _i('media') : _i('post');
                    ?>
, <?php 
                    echo _i('Time:');
                    ?>
 <?php 
                    echo gmdate('D M d H:i:s Y', $report->created);
                    ?>
                                <button class="btn btn-mini" data-function="mod" data-id="<?php 
                    echo $report->id;
                    ?>
" data-board="<?php 
                    echo htmlspecialchars($p->radix->shortname);
                    ?>
" data-action="delete_report"><?php 
                    echo _i('Delete Report');
                    ?>
</button>
                            </div>
                        </div>
                    <?php 
                }
                ?>
                <?php 
            }
            ?>
                <?php 
        }
        ?>
            </div>
        </article>
        <?php 
    }
예제 #4
0
 /**
  * @return bool
  */
 public function radix_submit()
 {
     // adapter
     if (!$this->getPost()) {
         return $this->error(_i('You aren\'t sending the required fields for creating a new message.'));
     }
     if (!$this->checkCsrfToken()) {
         return $this->error(_i('The security token wasn\'t found. Try resubmitting.'));
     }
     if ($this->getPost('reply_delete')) {
         foreach ($this->getPost('delete') as $idx => $doc_id) {
             try {
                 $comments = Board::forge($this->getContext())->getPost()->setOptions('doc_id', $doc_id)->setRadix($this->radix)->getComments();
                 $comment = current($comments);
                 $comment = new Comment($this->getContext(), $comment);
                 $comment->delete($this->getPost('delpass'));
             } catch (\Foolz\Foolfuuka\Model\BoardException $e) {
                 return $this->error($e->getMessage(), 404);
             } catch (\Foolz\Foolfuuka\Model\CommentDeleteWrongPassException $e) {
                 return $this->error($e->getMessage(), 404);
             }
         }
         $this->builder->createLayout('redirect')->getParamManager()->setParam('url', $this->uri->create([$this->radix->shortname, 'thread', $comment->comment->thread_num]));
         $this->builder->getProps()->addTitle(_i('Redirecting'));
         return new Response($this->builder->build());
     }
     if ($this->getPost('reply_report')) {
         foreach ($this->getPost('delete') as $idx => $doc_id) {
             try {
                 $this->getContext()->getService('foolfuuka.report_collection')->add($this->radix, $doc_id, $this->getPost('KOMENTO'), Inet::ptod($this->getRequest()->getClientIp()));
             } catch (\Foolz\Foolfuuka\Model\ReportException $e) {
                 return $this->error($e->getMessage(), 404);
             }
         }
         $this->builder->createLayout('redirect')->getParamManager()->setParam('url', $this->uri->create($this->radix->shortname . '/thread/' . $this->getPost('parent')));
         $this->builder->getProps()->addTitle(_i('Redirecting'));
         return new Response($this->builder->build());
     }
     // Determine if the invalid post fields are populated by bots.
     if (isset($post['name']) && mb_strlen($post['name'], 'utf-8') > 0) {
         return $this->error();
     }
     if (isset($post['reply']) && mb_strlen($post['reply'], 'utf-8') > 0) {
         return $this->error();
     }
     if (isset($post['email']) && mb_strlen($post['email'], 'utf-8') > 0) {
         return $this->error();
     }
     $data = [];
     $post = $this->getPost();
     if (isset($post['parent'])) {
         $data['thread_num'] = $post['parent'];
     }
     if (isset($post['NAMAE'])) {
         $data['name'] = $post['NAMAE'];
         $this->response->headers->setCookie(new Cookie($this->getContext(), 'reply_name', $data['name'], 60 * 60 * 24 * 30));
     }
     if (isset($post['MERU'])) {
         $data['email'] = $post['MERU'];
         $this->response->headers->setCookie(new Cookie($this->getContext(), 'reply_email', $data['email'], 60 * 60 * 24 * 30));
     }
     if (isset($post['subject'])) {
         $data['title'] = $post['subject'];
     }
     if (isset($post['KOMENTO'])) {
         $data['comment'] = $post['KOMENTO'];
     }
     if (isset($post['delpass'])) {
         // get the password needed for the reply field if it's not set yet
         if (!$post['delpass'] || strlen($post['delpass']) < 3) {
             $post['delpass'] = Util::randomString(7);
         }
         $data['delpass'] = $post['delpass'];
     }
     if (isset($post['reply_spoiler'])) {
         $data['spoiler'] = true;
     }
     if (isset($post['reply_postas'])) {
         $data['capcode'] = $post['reply_postas'];
     }
     if (isset($post['recaptcha_challenge_field']) && isset($post['recaptcha_response_field'])) {
         $data['recaptcha_challenge'] = $post['recaptcha_challenge_field'];
         $data['recaptcha_response'] = $post['recaptcha_response_field'];
     }
     $media = null;
     if ($this->getRequest()->files->count()) {
         try {
             $media = $this->media_factory->forgeFromUpload($this->getRequest(), $this->radix);
             $media->spoiler = isset($data['spoiler']) && $data['spoiler'];
         } catch (\Foolz\Foolfuuka\Model\MediaUploadNoFileException $e) {
             $media = null;
         } catch (\Foolz\Foolfuuka\Model\MediaUploadException $e) {
             return $this->error($e->getMessage());
         }
     }
     return $this->submit($data, $media);
 }
예제 #5
0
 /**
  * Send the comment and attached media to database
  *
  * @param Media $media
  * @param array $data extra data
  * @throws CommentSendingDatabaseException
  * @throws CommentSendingBannedException
  * @throws CommentSendingThreadWithoutMediaException
  * @throws CommentSendingSpamException
  * @throws CommentSendingImageInGhostException
  * @throws CommentSendingNoDelPassException
  * @throws CommentSendingThreadClosedException
  * @throws CommentSendingRequestCaptchaException
  * @throws CommentSendingTimeLimitException
  * @throws CommentSendingException
  * @throws CommentSendingTooManyCharactersException
  * @throws \RuntimeException
  * @throws CommentSendingDisplaysEmptyException
  * @throws CommentSendingTooManyLinesException
  * @throws CommentSendingSameCommentException
  * @throws CommentSendingWrongCaptchaException
  * @throws CommentSendingUnallowedCapcodeException
  * @return array error key with explanation to show to user, or success and post row
  */
 public function p_insert(Media $media = null, $data = [])
 {
     if (isset($data['recaptcha_challenge'])) {
         $this->recaptcha_challenge = $data['recaptcha_challenge'];
         $this->recaptcha_response = $data['recaptcha_response'];
     }
     $this->ghost = false;
     $this->ghost_exist = false;
     $this->allow_media = true;
     // some users don't need to be limited, in here go all the ban and posting limitators
     if (!$this->getAuth()->hasAccess('comment.limitless_comment')) {
         // check if the user is banned
         if ($ban = $this->ban_factory->isBanned($this->comment->poster_ip, $this->radix)) {
             if ($ban->board_id == 0) {
                 $banned_string = _i('It looks like you were banned on all boards.');
             } else {
                 $banned_string = _i('It looks like you were banned on /' . $this->radix->shortname . '/.');
             }
             if ($ban->length) {
                 $banned_string .= ' ' . _i('This ban will last until:') . ' ' . date(DATE_COOKIE, $ban->start + $ban->length) . '.';
             } else {
                 $banned_string .= ' ' . _i('This ban will last forever.');
             }
             if ($ban->reason) {
                 $banned_string .= ' ' . _i('The reason for this ban is:') . ' «' . $ban->reason . '».';
             }
             if ($ban->appeal_status == Ban::APPEAL_NONE) {
                 $banned_string .= ' ' . _i('If you\'d like to appeal to your ban, go to the %s page.', '<a href="' . $this->uri->create($this->radix->shortname . '/appeal') . '">' . _i('Appeal') . '</a>');
             } elseif ($ban->appeal_status == Ban::APPEAL_PENDING) {
                 $banned_string .= ' ' . _i('Your appeal is pending.');
             }
             throw new CommentSendingBannedException($banned_string);
         }
     }
     // check if it's a thread and its status
     if ($this->comment->thread_num > 0) {
         try {
             $thread = Board::forge($this->getContext())->getThread($this->comment->thread_num)->setRadix($this->radix);
             $status = $thread->getThreadStatus();
         } catch (BoardException $e) {
             throw new CommentSendingException($e->getMessage());
         }
         if ($status['closed']) {
             throw new CommentSendingThreadClosedException(_i('The thread is closed.'));
         }
         $this->ghost = $status['dead'];
         $this->ghost_exist = $status['ghost_exist'];
         $this->allow_media = !$status['disable_image_upload'];
     }
     foreach (['name', 'email', 'title', 'comment', 'capcode'] as $key) {
         $this->comment->{$key} = trim((string) $this->comment->{$key});
     }
     $this->comment->setDelpass(trim((string) $this->comment->getDelPass()));
     // some users don't need to be limited, in here go all the ban and posting limitators
     if (!$this->getAuth()->hasAccess('comment.limitless_comment')) {
         if ($this->comment->thread_num < 1) {
             // one can create a new thread only once every 5 minutes
             $check_op = $this->dc->qb()->select('*')->from($this->radix->getTable(), 'r')->where('r.poster_ip = :poster_ip')->andWhere('r.timestamp > :timestamp')->andWhere('r.op = :op')->setParameters([':poster_ip' => $this->comment->poster_ip, ':timestamp' => time() - $this->radix->getValue('cooldown_new_thread'), ':op' => true])->setMaxResults(1)->execute()->fetch();
             if ($check_op) {
                 throw new CommentSendingTimeLimitException(_i('You must wait up to %d minutes to make another new thread.', ceil($this->radix->getValue('cooldown_new_thread') / 60)));
             }
         }
         // check the latest posts by the user to see if he's posting the same message or if he's posting too fast
         $check = $this->dc->qb()->select('*')->from($this->radix->getTable(), 'r')->where('poster_ip = :poster_ip')->orderBy('timestamp', 'DESC')->setMaxResults(1)->setParameter(':poster_ip', $this->comment->poster_ip)->execute()->fetch();
         if ($check) {
             if ($this->comment->comment !== null && $check['comment'] === $this->comment->comment) {
                 throw new CommentSendingSameCommentException(_i('You\'re sending the same comment as the last time'));
             }
             $check_time = $this->getRadixTime();
             if ($check_time - $check['timestamp'] < $this->radix->getValue('cooldown_new_comment') && $check_time - $check['timestamp'] > 0) {
                 throw new CommentSendingTimeLimitException(_i('You must wait up to %d seconds to post again.', $this->radix->getValue('cooldown_new_comment')));
             }
         }
         // we want to know if the comment will display empty, and in case we won't let it pass
         $comment_parsed = $this->processComment();
         if ($this->comment->comment !== '' && $comment_parsed === '') {
             throw new CommentSendingDisplaysEmptyException(_i('This comment would display empty.'));
         }
         // clean up to reset eventual auto-built entries
         $this->comment->clean();
         if ($this->recaptcha_challenge && $this->recaptcha_response && $this->preferences->get('foolframe.auth.recaptcha_public', false)) {
             $recaptcha = ReCaptcha::create($this->preferences->get('foolframe.auth.recaptcha_public'), $this->preferences->get('foolframe.auth.recaptcha_private'));
             $recaptcha_result = $recaptcha->checkAnswer(Inet::dtop($this->comment->poster_ip), $this->recaptcha_challenge, $this->recaptcha_response);
             if (!$recaptcha_result->isValid()) {
                 throw new CommentSendingWrongCaptchaException(_i('Incorrect CAPTCHA solution.'));
             }
         } elseif ($this->preferences->get('foolframe.auth.recaptcha_public')) {
             // if there wasn't a recaptcha input, let's go with heavier checks
             if (substr_count($this->comment->comment, 'http') >= $this->radix->getValue('captcha_comment_link_limit')) {
                 throw new CommentSendingRequestCaptchaException();
             }
             // bots usually fill all the fields
             if ($this->comment->comment && $this->comment->title && $this->comment->email) {
                 throw new CommentSendingRequestCaptchaException();
             }
             // bots usually try various BBC, this checks if there's unparsed BBC after parsing it
             if ($comment_parsed !== '' && substr_count($comment_parsed, '[') + substr_count($comment_parsed, ']') > 4) {
                 throw new CommentSendingRequestCaptchaException();
             }
         }
         // load the spam list and check comment, name, title and email
         $spam = array_filter(preg_split('/\\r\\n|\\r|\\n/', file_get_contents(ASSETSPATH . 'packages/anti-spam/databases/urls.dat')));
         foreach ($spam as $s) {
             if (strpos($this->comment->comment, $s) !== false || strpos($this->comment->name, $s) !== false || strpos($this->comment->title, $s) !== false || strpos($this->comment->email, $s) !== false) {
                 throw new CommentSendingSpamException(_i('Your post has undesidered content.'));
             }
         }
         // check entire length of comment
         if (mb_strlen($this->comment->comment, 'utf-8') > $this->radix->getValue('max_comment_characters_allowed')) {
             throw new CommentSendingTooManyCharactersException(_i('Your comment has too many characters'));
         }
         // check total numbers of lines in comment
         if (count(explode("\n", $this->comment->comment)) > $this->radix->getValue('max_comment_lines_allowed')) {
             throw new CommentSendingTooManyLinesException(_i('Your comment has too many lines.'));
         }
     }
     \Foolz\Plugin\Hook::forge('Foolz\\Foolslide\\Model\\CommentInsert::insert.call.after.input_checks')->setObject($this)->execute();
     // process comment name+trip
     if ($this->comment->name === '') {
         $this->comment->name = $this->radix->getValue('anonymous_default_name');
         $this->comment->trip = null;
     } else {
         $this->processName();
         if ($this->comment->trip === '') {
             $this->comment->trip = null;
         }
     }
     foreach (['email', 'title', 'comment'] as $key) {
         if ($this->comment->{$key} === '') {
             $this->comment->{$key} = null;
         }
     }
     // process comment password
     if ($this->comment->getDelpass() === '') {
         throw new CommentSendingNoDelPassException(_i('You must submit a deletion password.'));
     }
     $pass = password_hash($this->comment->getDelpass(), PASSWORD_BCRYPT, ['cost' => 10]);
     if ($this->comment->getDelpass() === false) {
         throw new \RuntimeException('Password hashing failed');
     }
     $this->comment->setDelpass($pass);
     if ($this->comment->capcode != '') {
         $allowed_capcodes = ['N'];
         if ($this->getAuth()->hasAccess('comment.mod_capcode')) {
             $allowed_capcodes[] = 'M';
         }
         if ($this->getAuth()->hasAccess('comment.admin_capcode')) {
             $allowed_capcodes[] = 'A';
         }
         if ($this->getAuth()->hasAccess('comment.dev_capcode')) {
             $allowed_capcodes[] = 'D';
         }
         if (!in_array($this->comment->capcode, $allowed_capcodes)) {
             throw new CommentSendingUnallowedCapcodeException(_i('You\'re not allowed to use this capcode.'));
         }
     } else {
         $this->comment->capcode = 'N';
     }
     $microtime = str_replace('.', '', (string) microtime(true));
     $this->comment->timestamp = substr($microtime, 0, 10);
     $this->comment->op = (bool) (!$this->comment->thread_num);
     if ($this->radix->getValue('enable_flags')) {
         $reader = new Reader($this->preferences->get('foolframe.maxmind.geoip2_db_path'));
         try {
             $record = $reader->country(Inet::dtop($this->comment->poster_ip));
             $this->comment->poster_country = strtolower($record->country->isoCode);
         } catch (AddressNotFoundException $e) {
             $this->comment->poster_country = 'xx';
         }
     }
     // process comment media
     if ($media !== null) {
         // if uploading an image with OP is prohibited
         if (!$this->comment->thread_num && $this->radix->getValue('op_image_upload_necessity') === 'never') {
             throw new CommentSendingException(_i('You can\'t start a new thread with an image.'));
         }
         if (!$this->allow_media) {
             if ($this->ghost) {
                 throw new CommentSendingImageInGhostException(_i('You can\'t post images when the thread is in ghost mode.'));
             } else {
                 throw new CommentSendingException(_i('This thread has reached its image limit.'));
             }
         }
         try {
             $media->insert($microtime, $this->comment->op);
             $this->media = $media->media;
         } catch (MediaInsertException $e) {
             throw new CommentSendingException($e->getMessage());
         }
     } else {
         // if the user is forced to upload an image when making a new thread
         if (!$this->comment->thread_num && $this->radix->getValue('op_image_upload_necessity') === 'always') {
             throw new CommentSendingThreadWithoutMediaException(_i('You can\'t start a new thread without an image.'));
         }
         // in case of no media, check comment field again for null
         if ($this->comment->comment === null) {
             throw new CommentSendingDisplaysEmptyException(_i('This comment would display empty.'));
         }
         $this->media = $this->bulk->media = new MediaData();
     }
     // 2ch-style codes, only if enabled
     if ($this->comment->thread_num && $this->radix->getValue('enable_poster_hash')) {
         $this->comment->poster_hash = substr(substr(crypt(md5($this->comment->poster_ip . 'id' . $this->comment->thread_num), 'id'), +3), 0, 8);
     }
     $this->comment->timestamp = $this->getRadixTime($this->comment->timestamp);
     \Foolz\Plugin\Hook::forge('Foolz\\Foolslide\\Model\\CommentInsert::insert.call.before.sql')->setObject($this)->execute();
     // being processing insert...
     if ($this->ghost) {
         $num = '
         (
             SELECT MAX(num) AS num
             FROM (
                 (
                     SELECT num
                     FROM ' . $this->radix->getTable() . ' xr
                     WHERE thread_num = ' . $this->dc->getConnection()->quote($this->comment->thread_num) . '
                 )
                 UNION
                 (
                     SELECT num
                     FROM ' . $this->radix->getTable('_deleted') . ' xrd
                     WHERE thread_num = ' . $this->dc->getConnection()->quote($this->comment->thread_num) . '
                 )
             ) x
         )';
         $subnum = '
         (
             SELECT MAX(subnum) + 1 AS subnum
             FROM (
                 (
                     SELECT subnum
                     FROM ' . $this->radix->getTable() . ' xxr
                     WHERE num = (
                         SELECT MAX(num)
                         FROM (
                             (
                                 SELECT num
                                 FROM ' . $this->radix->getTable() . ' xxxr
                                 WHERE thread_num = ' . $this->dc->getConnection()->quote($this->comment->thread_num) . '
                             )
                             UNION
                             (
                                 SELECT num
                                 FROM ' . $this->radix->getTable('_deleted') . ' xxxrd
                                 WHERE thread_num = ' . $this->dc->getConnection()->quote($this->comment->thread_num) . '
                             )
                         ) xxx
                     )
                 )
                 UNION
                 (
                     SELECT subnum
                     FROM ' . $this->radix->getTable('_deleted') . ' xxdr
                     WHERE num = (
                         SELECT MAX(num)
                         FROM (
                             (
                                 SELECT num
                                 FROM ' . $this->radix->getTable() . ' xxxr
                                 WHERE thread_num = ' . $this->dc->getConnection()->quote($this->comment->thread_num) . '
                             )
                             UNION
                             (
                                 SELECT num
                                 FROM ' . $this->radix->getTable('_deleted') . ' xxxdrd
                                 WHERE thread_num = ' . $this->dc->getConnection()->quote($this->comment->thread_num) . '
                             )
                         ) xxxd
                     )
                 )
             ) xx
         )';
         $thread_num = $this->comment->thread_num;
     } else {
         $num = '
         (
             SELECT MAX(num) + 1 AS num
             FROM (
                 (
                     SELECT COALESCE(MAX(num), 0) AS num
                     FROM ' . $this->radix->getTable() . ' xr
                 )
                 UNION
                 (
                     SELECT COALESCE(MAX(num), 0) AS num
                     FROM ' . $this->radix->getTable('_deleted') . ' xdr
                 )
             ) x
         )';
         $subnum = 0;
         if ($this->comment->thread_num > 0) {
             $thread_num = $this->dc->getConnection()->quote($this->comment->thread_num);
         } else {
             $thread_num = '
             (
                 SELECT MAX(thread_num) + 1 AS thread_num
                 FROM (
                     (
                         SELECT COALESCE(MAX(num), 0) as thread_num
                         FROM ' . $this->radix->getTable() . ' xxr
                     )
                     UNION
                     (
                         SELECT COALESCE(MAX(num), 0) as thread_num
                         FROM ' . $this->radix->getTable('_deleted') . ' xxdr
                     )
                 ) xx
             )';
         }
     }
     try {
         $query_fields = ['num' => $num, 'subnum' => $subnum, 'thread_num' => $thread_num];
         $fields = ['media_id' => $this->media->media_id ? $this->media->media_id : 0, 'op' => (int) $this->op, 'timestamp' => $this->comment->timestamp, 'capcode' => $this->comment->capcode, 'email' => $this->comment->email, 'name' => $this->comment->name, 'trip' => $this->comment->trip, 'title' => $this->comment->title, 'comment' => $this->comment->comment, 'delpass' => $this->comment->getDelpass(), 'spoiler' => (int) $this->media->spoiler, 'poster_ip' => $this->comment->poster_ip, 'poster_hash' => $this->comment->poster_hash, 'poster_country' => $this->comment->poster_country, 'preview_orig' => $this->media->preview_orig, 'preview_w' => $this->media->preview_w, 'preview_h' => $this->media->preview_h, 'media_filename' => $this->media->media_filename, 'media_w' => $this->media->media_w, 'media_h' => $this->media->media_h, 'media_size' => $this->media->media_size, 'media_hash' => $this->media->media_hash, 'media_orig' => $this->media->media_orig, 'exif' => $this->media->exif !== null ? @json_encode($this->media->exif) : null, 'timestamp_expired' => 0];
         foreach ($fields as $key => $item) {
             if ($item === null) {
                 $fields[$key] = 'null';
             } else {
                 $fields[$key] = $this->dc->getConnection()->quote($item);
             }
         }
         $fields = $query_fields + $fields;
         $this->dc->getConnection()->beginTransaction();
         $this->dc->getConnection()->executeUpdate('INSERT INTO ' . $this->radix->getTable() . ' (' . implode(', ', array_keys($fields)) . ') VALUES (' . implode(', ', array_values($fields)) . ')');
         $last_id = $this->dc->getConnection()->lastInsertId($this->radix->getTable('_doc_id_seq'));
         $comment = $this->dc->qb()->select('*')->from($this->radix->getTable(), 'r')->where('doc_id = :doc_id')->setParameter(':doc_id', $last_id)->execute()->fetchAll();
         $this->bulk->import($comment[0], $this->radix);
         if (!$this->radix->archive) {
             $this->insertTriggerThreads();
             $this->insertTriggerDaily();
             $this->insertTriggerUsers();
         }
         // update poster_hash for op posts
         if ($this->comment->op && $this->radix->getValue('enable_poster_hash')) {
             $this->comment->poster_hash = substr(substr(crypt(md5($this->comment->poster_ip . 'id' . $this->comment->thread_num), 'id'), 3), 0, 8);
             $this->dc->qb()->update($this->radix->getTable(), 'ph')->set('poster_hash', $this->dc->getConnection()->quote($this->comment->poster_hash))->where('doc_id = :doc_id')->setParameter(':doc_id', $this->comment->doc_id)->execute();
         }
         $this->dc->getConnection()->commit();
         // clean up some caches
         Cache::item('foolslide.model.board.getThreadComments.thread.' . md5(serialize([$this->radix->shortname, $this->comment->thread_num])))->delete();
         // clean up the 10 first pages of index and gallery that are cached
         for ($i = 1; $i <= 10; $i++) {
             Cache::item('foolslide.model.board.getLatestComments.query.' . $this->radix->shortname . '.by_post.' . $i)->delete();
             Cache::item('foolslide.model.board.getLatestComments.query.' . $this->radix->shortname . '.by_thread.' . $i)->delete();
             Cache::item('foolslide.model.board.getThreadsComments.query.' . $this->radix->shortname . '.' . $i)->delete();
         }
     } catch (\Doctrine\DBAL\DBALException $e) {
         $this->logger->error('\\Foolz\\Foolslide\\Model\\CommentInsert: ' . $e->getMessage());
         $this->dc->getConnection()->rollBack();
         throw new CommentSendingDatabaseException(_i('Something went wrong when inserting the post in the database. Try again.'));
     }
     return $this;
 }
예제 #6
0
파일: Bans.php 프로젝트: voh/FoolFuuka
    public function toString()
    {
        $users = $this->getContext()->getService('users');
        $radix_coll = $this->getContext()->getService('foolfuuka.radix_collection');
        $form = $this->getForm();
        ?>
<div class="admin-container">
    <div class="admin-container-header">
        <?php 
        echo _i('Bans');
        ?>
    </div>

    <div class="pull-right">
        <?php 
        echo $form->open(['action' => 'admin/moderation/find_ban']);
        ?>
        <div class="input-prepend">
            <label class="add-on" for="form_ip">Search by IP</label><?php 
        echo $form->input('ip');
        ?>
        </div>
        <?php 
        echo $form->close();
        ?>
    </div>

    <table class="table table-hover table-condensed">
        <thead>
            <tr>
                <th><?php 
        echo _i('IP');
        ?>
</th>
                <th><?php 
        echo _i('Board');
        ?>
</th>
                <th><?php 
        echo _i('Reason');
        ?>
</th>
                <th><?php 
        echo _i('Appeal');
        ?>
</th>
                <th><?php 
        echo _i('Issued - Length');
        ?>
</th>
                <th><?php 
        echo _i('Actions');
        ?>
</th>
            </tr>
        </thead>
        <tbody>
            <?php 
        foreach ($this->getParamManager()->getParam('bans') as $b) {
            ?>
            <tr>
                <td><?php 
            echo Inet::dtop($b->ip);
            echo $this->getPreferences()->get('foolfuuka.sphinx.global') ? '<br><small><a href="' . $this->getUri()->create('_/search/poster_ip/' . Inet::dtop($b->ip)) . '" target="_blank">' . _i('Search posts') . '</a></small>' : '';
            ?>
</td>
                <td><?php 
            echo $b->board_id ? '/' . $radix_coll->getById($b->board_id)->shortname . '/' : _i('Global');
            ?>
</td>
                <td><?php 
            echo htmlentities($b->reason);
            ?>
<br><small><?php 
            echo _i('By:') . ' ' . htmlentities($users->getUserBy('id', $b->creator_id)->username);
            ?>
</small></td>
                <td><?php 
            echo htmlentities($b->appeal);
            ?>
<br><small><?php 
            echo _i('Status:') . ' ' . ($b->appeal_status == Ban::APPEAL_PENDING ? _i('pending') : '') . ($b->appeal_status == Ban::APPEAL_REJECTED ? _i('rejected') : '') . ($b->appeal_status == Ban::APPEAL_NONE ? _i('none') : '');
            ?>
</small></td>
                <td><?php 
            echo date('d-M-y H:i:s T', $b->start);
            ?>
, <?php 
            echo $b->length ? $b->length / 24 / 60 / 60 . ' ' . _i('Day(s)') : _i('Forever');
            ?>
<br><small><?php 
            echo _i('Status:') . ' ' . (!$b->length || time() < $b->start + $b->length ? _i('ongoing') : _i('expired'));
            ?>
</small></td>
                <td>
                    <div class="btn-group">
                        <a class="btn btn-small dropdown-toggle" data-toggle="dropdown" href="#">
                            <?php 
            echo _i('Action');
            ?>
                            <span class="caret"></span>
                        </a>
                        <ul class="dropdown-menu">
                            <li><a href="<?php 
            echo $this->getUri()->create('admin/moderation/ban_manage/unban/' . $b->id);
            ?>
"><?php 
            echo _i('Unban');
            ?>
</a></li>
                            <?php 
            if ($b->appeal_status == Ban::APPEAL_PENDING) {
                ?>
                                <li><a href="<?php 
                echo $this->getUri()->create('admin/moderation/ban_manage/reject_appeal/' . $b->id);
                ?>
"><?php 
                echo _i('Reject appeal');
                ?>
</a></li>
                            <?php 
            }
            ?>
                        </ul>
                    </div>
                </td>
            </tr>
            <?php 
        }
        ?>
        </tbody>
    </table>

    <?php 
        $page = $this->getParamManager()->getParam('page');
        ?>
    <?php 
        if ($page) {
            ?>
    <div class="pagination">
      <ul>
        <?php 
            if ($page > 1) {
                ?>
        <li class=""><a href="<?php 
                echo $this->getParamManager()->getParam('page_url') . ($page - 1);
                ?>
"><?php 
                echo _i('Prev');
                ?>
</a></li>
        <?php 
            }
            ?>
        <li class=""><a href="<?php 
            echo $this->getParamManager()->getParam('page_url') . ($page + 1);
            ?>
"><?php 
            echo _i('Next');
            ?>
</a></li>
      </ul>
    </div>
    <?php 
        }
        ?>
</div>
<?php 
    }
예제 #7
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.')]);
     }
 }
예제 #8
0
파일: Chan.php 프로젝트: procod3R/FoolFuuka
 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\Foolfuuka\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\Foolfuuka\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\Foolfuuka\Model\BoardThreadNotFoundException $e) {
                 return $this->error(_i('Thread not found.'));
             } catch (\Foolz\Foolfuuka\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;
 }
예제 #9
0
 public function action_ban_manage($action, $id)
 {
     try {
         $ban = $this->ban_factory->getById($id);
     } catch (\Foolz\Foolfuuka\Model\BanException $e) {
         throw new NotFoundHttpException();
     }
     if ($this->getPost() && !$this->checkCsrfToken()) {
         $this->notices->set('warning', _i('The security token wasn\'t found. Try resubmitting.'));
     } elseif ($this->getPost()) {
         switch ($action) {
             case 'unban':
                 $ban->delete();
                 $this->notices->setFlash('success', _i('The poster with IP %s has been unbanned.', Inet::dtop($ban->ip)));
                 return $this->redirect('admin/moderation/bans');
                 break;
             case 'reject_appeal':
                 $ban->appealReject();
                 $this->notices->setFlash('success', _i('The appeal of the poster with IP %s has been rejected.', Inet::dtop($ban->ip)));
                 return $this->redirect('admin/moderation/bans');
                 break;
             default:
                 throw new NotFoundHttpException();
         }
     }
     switch ($action) {
         case 'unban':
             $this->_views['method_title'] = _i('Unbanning') . ' ' . Inet::dtop($ban->ip);
             $data['alert_level'] = 'warning';
             $data['message'] = _i('Do you want to unban this user?');
             break;
         case 'reject_appeal':
             $this->_views['method_title'] = _i('Rejecting appeal for') . ' ' . Inet::dtop($ban->ip);
             $data['alert_level'] = 'warning';
             $data['message'] = _i('Do you want to reject the appeal of this user? He won\'t be able to appeal again.');
             break;
         default:
             throw new NotFoundHttpException();
     }
     $this->builder->createPartial('body', 'confirm')->getParamManager()->setParams($data);
     return new Response($this->builder->build());
 }
예제 #10
0
 /**
  * Gets the search results
  *
  * @return  \Foolz\Foolfuuka\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('foolfuuka.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('foolfuuka.sphinx.global') || $this->radix !== null && $this->radix->sphinx) {
         // configure sphinx connection params
         $sphinx = explode(':', $this->preferences->get('foolfuuka.sphinx.listen'));
         $conn = new SphinxConnnection();
         $conn->setParams(['host' => $sphinx[0], 'port' => $sphinx[1], 'options' => [MYSQLI_OPT_CONNECT_TIMEOUT => 5]]);
         $conn->silenceConnectionWarning(true);
         // establish connection
         try {
             SphinxQL::forge($conn);
         } catch (\Foolz\SphinxQL\ConnectionException $e) {
             throw new SearchSphinxOfflineException(_i('The search backend is currently unavailable.'));
         }
         // 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'];
         }
         // start search query
         $query = SphinxQL::forge()->select('id', 'board')->from($indexes);
         // 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('foolfuuka.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;
 }
예제 #11
0
    public function toString()
    {
        $board = $this->getParamManager()->getParam('board');
        $controller_method = $this->getBuilderParamManager()->getParam('controller_method', 'thread');
        $thread_id = $this->getBuilderParamManager()->getParam('thread_id', 0);
        foreach ($board as $key => $post) {
            if (isset($post['op'])) {
                $op_bulk = $post['op'];
                $op = new Comment($this->getContext(), $op_bulk);
                $op->setControllerMethod($controller_method);
                if ($op_bulk->media !== null) {
                    $op_media = new Media($this->getContext(), $op_bulk);
                } else {
                    $op_media = null;
                }
                $num = $op->num . ($op->subnum ? '_' . $op->subnum : '');
                ?>
        <?php 
                if ($thread_id === 0) {
                    ?>
        <div class="thread stub stub_doc_id_<?php 
                    echo $op->doc_id;
                    ?>
">
            <button class="btn-toggle-post" data-function="showThread" data-board="<?php 
                    echo $op->radix->shortname;
                    ?>
" data-doc-id="<?php 
                    echo $op->doc_id;
                    ?>
" data-thread-num="<?php 
                    echo $op->thread_num;
                    ?>
"><i class="icon-plus"></i></button>
            <?php 
                    if ($op->email && $op->email !== 'noko') {
                        ?>
<a href="mailto:<?php 
                        echo rawurlencode($op->email);
                        ?>
"><?php 
                    }
                    ?>
<span class="post_author"><?php 
                    echo $op->getNameProcessed();
                    ?>
</span><?php 
                    echo $op->getNameProcessed() && $op->getTripProcessed() ? ' ' : '';
                    ?>
<span class="post_tripcode"><?php 
                    echo $op->getTripProcessed();
                    ?>
</span><?php 
                    if ($op->email && $op->email !== 'noko') {
                        ?>
</a><?php 
                    }
                    ?>
            (<?php 
                    echo $post['omitted'] + 5 . ' ' . _i('replies');
                    ?>
)
        </div>
        <?php 
                }
                ?>
        <article id="<?php 
                echo $num;
                ?>
" class="clearfix thread doc_id_<?php 
                echo $op->doc_id;
                ?>
 board_<?php 
                echo $op->radix->shortname;
                ?>
" data-doc-id="<?php 
                echo $op->doc_id;
                ?>
" data-thread-num="<?php 
                echo $op->thread_num;
                ?>
">
                <?php 
                if ($thread_id === 0) {
                    ?>
                <div class="stub pull-left">
                    <button class="btn-toggle-post" data-function="hideThread" data-board="<?php 
                    echo $op->radix->shortname;
                    ?>
" data-doc-id="<?php 
                    echo $op->doc_id;
                    ?>
"><i class="icon-minus"></i></button>
                </div>
                <?php 
                }
                ?>
                <?php 
                \Foolz\Plugin\Hook::forge('foolfuuka.themes.default_after_op_open')->setObject($this)->setParam('board', $op->radix)->execute();
                ?>
                <?php 
                if ($op_media !== null) {
                    ?>
                <div class="thread_image_box">
                    <?php 
                    if ($op_media->getMediaStatus($this->getRequest()) === 'banned') {
                        ?>
                    <img src="<?php 
                        echo $this->getAssetManager()->getAssetLink('images/banned-image.png');
                        ?>
" width="150" height="150" />
                    <?php 
                    } elseif ($op_media->getMediaStatus($this->getRequest()) !== 'normal') {
                        ?>
                    <a href="<?php 
                        echo $op_media->getMediaLink($this->getRequest()) ? $op_media->getMediaLink($this->getRequest()) : $op_media->getRemoteMediaLink($this->getRequest());
                        ?>
" target="_blank" rel="noreferrer" class="thread_image_link">
                        <img src="<?php 
                        echo $this->getAssetManager()->getAssetLink('images/missing-image.jpg');
                        ?>
" width="150" height="150" />
                    </a>
                    <?php 
                    } else {
                        ?>
                    <a href="<?php 
                        echo $op_media->getMediaLink($this->getRequest()) ? $op_media->getMediaLink($this->getRequest()) : $op_media->getRemoteMediaLink($this->getRequest());
                        ?>
" target="_blank" rel="noreferrer" class="thread_image_link">
                        <?php 
                        if (!$this->getAuth()->hasAccess('maccess.mod') && !$op->radix->getValue('transparent_spoiler') && $op_media->spoiler) {
                            ?>
                        <div class="spoiler_box"><span class="spoiler_box_text"><?php 
                            echo _i('Spoiler');
                            ?>
<span class="spoiler_box_text_help"><?php 
                            echo _i('Click to view');
                            ?>
</span></div>
                        <?php 
                        } else {
                            ?>
                        <img src="<?php 
                            echo $op_media->getThumbLink($this->getRequest());
                            ?>
" width="<?php 
                            echo $op_media->preview_w;
                            ?>
" height="<?php 
                            echo $op_media->preview_h;
                            ?>
" class="thread_image<?php 
                            echo $op_media->spoiler ? ' is_spoiler_image' : '';
                            ?>
" data-md5="<?php 
                            echo $op_media->media_hash;
                            ?>
" />
                        <?php 
                        }
                        ?>
                    </a>
                    <?php 
                    }
                    ?>
                    <?php 
                    if ($op_media->getMediaStatus($this->getRequest()) !== 'banned') {
                        ?>
                    <div class="post_file" style="padding-left: 2px;<?php 
                        if ($op_media->preview_w > 149) {
                            echo 'max-width:' . $op_media->preview_w . 'px;';
                        }
                        ?>
">
                        <?php 
                        echo ByteSize::formatBinary($op_media->media_size, 0) . ', ' . $op_media->media_w . 'x' . $op_media->media_h . ', ';
                        ?>
<a class="post_file_filename" href="<?php 
                        echo $op_media->getMediaLink($this->getRequest()) ? $op_media->getMediaLink($this->getRequest()) : $op_media->getRemoteMediaLink($this->getRequest());
                        ?>
" target="_blank"><?php 
                        echo $op_media->getMediaFilenameProcessed();
                        ?>
</a>
                    </div>
                    <?php 
                    }
                    ?>
                    <div class="post_file_controls">
                        <?php 
                    if ($op_media->getMediaStatus($this->getRequest()) !== 'banned' || $this->getAuth()->hasAccess('media.see_banned')) {
                        ?>
                        <?php 
                        if (!$op->radix->hide_thumbnails || $this->getAuth()->hasAccess('maccess.mod')) {
                            ?>
                            <a href="<?php 
                            echo $this->getUri()->create($op->radix->shortname . '/search/image/' . $op_media->getSafeMediaHash());
                            ?>
" class="btnr parent"><?php 
                            echo _i('View Same');
                            ?>
</a><a
                                href="http://google.com/searchbyimage?image_url=<?php 
                            echo $op_media->getThumbLink($this->getRequest());
                            ?>
" target="_blank"
                                class="btnr parent">Google</a><a
                                href="http://iqdb.org/?url=<?php 
                            echo $op_media->getThumbLink($this->getRequest());
                            ?>
" target="_blank"
                                class="btnr parent">iqdb</a><a
                                href="http://saucenao.com/search.php?url=<?php 
                            echo $op_media->getThumbLink($this->getRequest());
                            ?>
" target="_blank"
                                class="btnr parent">SauceNAO</a><?php 
                            if (!$op->radix->archive || $op->radix->getValue('archive_full_images')) {
                                ?>
<a
                                href="<?php 
                                echo $op_media->getMediaDownloadLink($this->getRequest());
                                ?>
" download="<?php 
                                echo $op_media->getMediaFilenameProcessed();
                                ?>
"
                                class="btnr parent"><i class="icon-download-alt"></i></a><?php 
                            }
                            ?>
                            <?php 
                        }
                        ?>
                        <?php 
                    }
                    ?>
                    </div>
                </div>
                <?php 
                }
                ?>
                <header>
                    <div class="post_data">
                        <?php 
                if ($op->getTitleProcessed() !== '') {
                    ?>
<h2 class="post_title"><?php 
                    echo $op->getTitleProcessed();
                    ?>
</h2><?php 
                }
                ?>
                        <span class="post_poster_data">
                            <?php 
                if ($op->email && $op->email !== 'noko') {
                    ?>
<a href="mailto:<?php 
                    echo rawurlencode($op->email);
                    ?>
"><?php 
                }
                ?>
<span class="post_author"><?php 
                echo $op->getNameProcessed();
                ?>
</span><?php 
                echo $op->getNameProcessed() && $op->getTripProcessed() ? ' ' : '';
                ?>
<span class="post_tripcode"><?php 
                echo $op->getTripProcessed();
                ?>
</span><?php 
                if ($op->email && $op->email !== 'noko') {
                    ?>
</a><?php 
                }
                ?>

                            <?php 
                if ($op->getPosterHashProcessed()) {
                    ?>
<span class="poster_hash">ID:<?php 
                    echo $op->getPosterHashProcessed();
                    ?>
</span><?php 
                }
                ?>
                            <?php 
                if ($op->capcode !== 'N') {
                    ?>
                            <?php 
                    if ($op->capcode === 'M') {
                        ?>
<span class="post_level post_level_moderator">## <?php 
                        echo _i('Mod');
                        ?>
</span><?php 
                    }
                    ?>
                            <?php 
                    if ($op->capcode === 'A') {
                        ?>
<span class="post_level post_level_administrator">## <?php 
                        echo _i('Admin');
                        ?>
</span><?php 
                    }
                    ?>
                            <?php 
                    if ($op->capcode === 'D') {
                        ?>
<span class="post_level post_level_developer">## <?php 
                        echo _i('Developer');
                        ?>
</span><?php 
                    }
                    ?>
                            <?php 
                }
                ?>
                        </span>
                        <span class="time_wrap">
                            <time datetime="<?php 
                echo gmdate(DATE_W3C, $op->timestamp);
                ?>
" class="show_time" <?php 
                if ($op->radix->archive) {
                    ?>
 title="<?php 
                    echo _i('4chan Time') . ': ' . $op->getFourchanDate();
                    ?>
"<?php 
                }
                ?>
><?php 
                echo gmdate('D d M H:i:s Y', $op->timestamp);
                ?>
</time>
                        </span>
                        <a href="<?php 
                echo $this->getUri()->create(array($op->radix->shortname, $controller_method, $op->thread_num)) . '#' . $num;
                ?>
" data-post="<?php 
                echo $num;
                ?>
" data-function="highlight">No.</a><a href="<?php 
                echo $this->getUri()->create(array($op->radix->shortname, $controller_method, $op->thread_num)) . '#q' . $num;
                ?>
" data-post="<?php 
                echo $num;
                ?>
" data-function="quote"><?php 
                echo $num;
                ?>
</a>

                        <span class="post_type">
                            <?php 
                if ($op->poster_country !== null) {
                    ?>
<span title="<?php 
                    echo e($op->poster_country_name);
                    ?>
" class="flag flag-<?php 
                    echo strtolower($op->poster_country);
                    ?>
"></span><?php 
                }
                ?>
                            <?php 
                if (isset($op_media) && $op_media->spoiler) {
                    ?>
<i class="icon-eye-close" title="<?php 
                    echo htmlspecialchars(_i('The image in this post has been marked spoiler.'));
                    ?>
"></i><?php 
                }
                ?>
                            <?php 
                if ($op->deleted && !$op->timestamp_expired) {
                    ?>
<i class="icon-trash" title="<?php 
                    echo htmlspecialchars(_i('This thread was prematurely deleted.'));
                    ?>
"></i><?php 
                }
                ?>
                            <?php 
                if ($op->deleted && $op->timestamp_expired) {
                    ?>
<i class="icon-trash" title="<?php 
                    echo htmlspecialchars(_i('This thread was deleted on %s.', gmdate('M d, Y \\a\\t H:i:s e', $op->timestamp_expired)));
                    ?>
"></i><?php 
                }
                ?>
                            <?php 
                if ($op->sticky) {
                    ?>
<i class="icon-pushpin" title="<?php 
                    echo _i('This thread has been stickied.');
                    ?>
"></i><?php 
                }
                ?>
                            <?php 
                if ($op->locked) {
                    ?>
<i class="icon-lock" title="<?php 
                    echo _i('This thread has been locked.');
                    ?>
"></i><?php 
                }
                ?>
                        </span>

                        <span class="post_controls">
                <a href="<?php 
                echo $this->getUri()->create(array($op->radix->shortname, 'thread', $num));
                ?>
" class="btnr parent"><?php 
                echo _i('View');
                ?>
</a><a href="<?php 
                echo $this->getUri()->create(array($op->radix->shortname, $controller_method, $num)) . '#reply';
                ?>
" class="btnr parent"><?php 
                echo _i('Reply');
                ?>
</a><?php 
                echo isset($post['omitted']) && $post['omitted'] > 50 ? '<a href="' . $this->getUri()->create($op->radix->shortname . '/last/50/' . $num) . '" class="btnr parent">' . _i('Last 50') . '</a>' : '';
                echo $op->radix->archive ? '<a href="//boards.4chan.org/' . $op->radix->shortname . '/thread/' . $num . '" class="btnr parent">' . _i('Original') . '</a>' : '';
                ?>
<a href="#" class="btnr parent" data-post="<?php 
                echo $op->doc_id;
                ?>
" data-post-id="<?php 
                echo $num;
                ?>
" data-board="<?php 
                echo htmlspecialchars($op->radix->shortname);
                ?>
" data-controls-modal="post_tools_modal" data-backdrop="true" data-keyboard="true" data-function="report"><?php 
                echo _i('Report');
                ?>
</a><?php 
                if ($this->getAuth()->hasAccess('maccess.mod') || !$op->radix->archive) {
                    ?>
<a href="#" class="btnr parent" data-post="<?php 
                    echo $op->doc_id;
                    ?>
" data-post-id="<?php 
                    echo $num;
                    ?>
" data-board="<?php 
                    echo htmlspecialchars($op->radix->shortname);
                    ?>
" data-controls-modal="post_tools_modal" data-backdrop="true" data-keyboard="true" data-function="delete"><?php 
                    echo _i('Delete');
                    ?>
</a><?php 
                }
                ?>
            </span>

                        <div class="backlink_list"<?php 
                echo $op->getBacklinks() ? ' style="display:block"' : '';
                ?>
>
                            <?php 
                echo _i('Quoted By:');
                ?>
 <span class="post_backlink" data-post="<?php 
                echo $num;
                ?>
"><?php 
                echo $op->getBacklinks() ? implode(' ', $op->getBacklinks()) : '';
                ?>
</span>
                        </div>

                        <?php 
                if ($this->getAuth()->hasAccess('maccess.mod')) {
                    ?>
                        <div class="btn-group" style="clear:both; padding:5px 0 0 0;">
                            <button class="btn btn-mini" data-function="activateModeration"><?php 
                    echo _i('Mod');
                    if ($op->poster_ip) {
                        echo ' ' . Inet::dtop($op->poster_ip);
                    }
                    ?>
</button>
                        </div>
                        <div class="btn-group post_mod_controls" style="clear:both; padding:5px 0 0 0;">
                            <button class="btn btn-mini" data-function="mod" data-board="<?php 
                    echo $op->radix->shortname;
                    ?>
" data-id="<?php 
                    echo $op->doc_id;
                    ?>
" data-action="delete_post"><?php 
                    echo _i('Delete Thread');
                    ?>
</button>
                            <?php 
                    if (!is_null($op_media)) {
                        ?>
                            <button class="btn btn-mini" data-function="mod" data-board="<?php 
                        echo $op->radix->shortname;
                        ?>
" data-id="<?php 
                        echo $op_media->media_id;
                        ?>
" data-doc-id="<?php 
                        echo $op->doc_id;
                        ?>
" data-action="delete_image"><?php 
                        echo _i('Delete Image');
                        ?>
</button>
                            <button class="btn btn-mini" data-function="mod" data-board="<?php 
                        echo $op->radix->shortname;
                        ?>
" data-id="<?php 
                        echo $op_media->media_id;
                        ?>
" data-doc-id="<?php 
                        echo $op->doc_id;
                        ?>
" data-action="ban_image_local"><?php 
                        echo _i('Ban Image');
                        ?>
</button>
                            <button class="btn btn-mini" data-function="mod" data-board="<?php 
                        echo $op->radix->shortname;
                        ?>
" data-id="<?php 
                        echo $op_media->media_id;
                        ?>
" data-doc-id="<?php 
                        echo $op->doc_id;
                        ?>
" data-action="ban_image_global"><?php 
                        echo _i('Ban Image Globally');
                        ?>
</button>
                            <?php 
                    }
                    ?>
                            <?php 
                    if ($op->poster_ip) {
                        ?>
                            <button class="btn btn-mini" data-function="ban" data-controls-modal="post_tools_modal" data-backdrop="true" data-keyboard="true" data-board="<?php 
                        echo $op->radix->shortname;
                        ?>
" data-ip="<?php 
                        echo Inet::dtop($op->poster_ip);
                        ?>
" data-action="ban_user"><?php 
                        echo _i('Ban IP:') . ' ' . Inet::dtop($op->poster_ip);
                        ?>
</button>
                            <button class="btn btn-mini" data-function="searchUser" data-board="<?php 
                        echo $op->radix->shortname;
                        ?>
" data-board-url="<?php 
                        echo $this->getUri()->create(array($op->radix->shortname));
                        ?>
" data-id="<?php 
                        echo $op->doc_id;
                        ?>
" data-poster-ip="<?php 
                        echo Inet::dtop($op->poster_ip);
                        ?>
"><?php 
                        echo _i('Search IP');
                        ?>
</button>
                            <?php 
                        if ($this->getPreferences()->get('foolfuuka.sphinx.global')) {
                            ?>
                                <button class="btn btn-mini" data-function="searchUserGlobal" data-board="<?php 
                            echo $op->radix->shortname;
                            ?>
" data-board-url="<?php 
                            echo $this->getUri()->create(array($op->radix->shortname));
                            ?>
" data-id="<?php 
                            echo $op->doc_id;
                            ?>
" data-poster-ip="<?php 
                            echo Inet::dtop($op->poster_ip);
                            ?>
"><?php 
                            echo _i('Search IP Globally');
                            ?>
</button>
                                <?php 
                        }
                        ?>
                            <?php 
                    }
                    ?>
                        </div>
                        <?php 
                }
                ?>
                    </div>
                </header>

                <div class="text<?php 
                if (preg_match('/[\\x{4E00}-\\x{9FBF}\\x{3040}-\\x{309F}\\x{30A0}-\\x{30FF}]/u', $op->getCommentProcessed())) {
                    echo ' shift-jis';
                }
                ?>
">
                    <?php 
                echo $op->getCommentProcessed();
                ?>
                </div>
                <div class="thread_tools_bottom">
                    <?php 
                if (isset($post['omitted']) && $post['omitted'] > 0) {
                    ?>
        <span class="omitted">
            <a style="display:inline-block" href="<?php 
                    echo $this->getUri()->create(array($op->radix->shortname, $controller_method, $op->thread_num));
                    ?>
" data-function="expandThread" data-thread-num="<?php 
                    echo $op->thread_num;
                    ?>
"><i class="icon icon-resize-full"></i></a>
                    <span class="omitted_text">
                <span class="omitted_posts"><?php 
                    echo $post['omitted'];
                    ?>
</span> <?php 
                    echo _n('post', 'posts', $post['omitted']);
                    ?>
                        <?php 
                    if (isset($post['images_omitted']) && $post['images_omitted'] > 0) {
                        ?>
                        <?php 
                        echo _i('and');
                        ?>
 <span class="omitted_images"><?php 
                        echo $post['images_omitted'];
                        ?>
</span> <?php 
                        echo _n('image', 'images', $post['images_omitted']);
                        ?>
                        <?php 
                    }
                    ?>
                        <?php 
                    echo _n('omitted', 'omitted', $post['omitted'] + $post['images_omitted']);
                    ?>
        </span>
                    <?php 
                }
                ?>
                </div>

                <?php 
                if ($op->getReports()) {
                    ?>
                <?php 
                    foreach ($op->getReports() as $report) {
                        ?>
                    <div class="report_reason"><?php 
                        echo '<strong>' . _i('Reported Reason:') . '</strong> ' . $report->getReasonProcessed();
                        ?>
                        <br/>
                        <div class="ip_reporter">
                            <strong><?php 
                        echo _i('Info:');
                        ?>
</strong>
                            <?php 
                        echo Inet::dtop($report->ip_reporter);
                        ?>
, <?php 
                        echo _i('Type:');
                        ?>
 <?php 
                        echo $report->media_id !== null ? _i('media') : _i('post');
                        ?>
, <?php 
                        echo _i('Time:');
                        ?>
 <?php 
                        echo gmdate('D M d H:i:s Y', $report->created);
                        ?>
                            <button class="btn btn-mini" data-function="mod" data-id="<?php 
                        echo $report->id;
                        ?>
" data-board="<?php 
                        echo htmlspecialchars($op->radix->shortname);
                        ?>
" data-action="delete_report"><?php 
                        echo _i('Delete Report');
                        ?>
</button>
                        </div>
                    </div>
                    <?php 
                    }
                    ?>
                <?php 
                }
                ?>
                <?php 
            } elseif (isset($post['posts'])) {
                ?>
        <article class="clearfix thread">
                    <?php 
                \Foolz\Plugin\Hook::forge('foolfuuka.themes.default_after_headless_open')->setObject($this)->setParam('board', array(isset($radix) ? $radix : null))->execute();
                ?>
                <?php 
            }
            ?>

            <aside class="posts">
                <?php 
            if (isset($post['posts'])) {
                $post_counter = 0;
                $image_counter = 0;
                $board_comment_view = $this->getBuilder()->createPartial('post', 'board_comment');
                // reusable Comment object not to create one every loop
                $comment = new Comment($this->getContext());
                $comment->setControllerMethod($controller_method);
                $media_obj = new Media($this->getContext());
                $search = array('/\\>[^\\S ]+/s', '/[^\\S ]+\\</s', '/(\\s)+/s');
                $replace = array('>', '<', '\\1');
                foreach ($post['posts'] as $p) {
                    /** @var CommentBulk $p */
                    $post_counter++;
                    if ($p->media !== null) {
                        $image_counter++;
                    }
                    if ($image_counter == 150) {
                        $modifiers['lazyload'] = true;
                    }
                    $comment->setBulk($p);
                    // set the $media to null and leave the Media object in existence
                    if ($p->media !== null) {
                        $media_obj->setBulk($p);
                        $media = $media_obj;
                    } else {
                        $media = null;
                    }
                    $board_comment_view->getParamManager()->setParams(['p' => $comment, 'p_media' => $media, 'modifiers' => $this->getBuilderParamManager()->getParam('modifiers', false), 'post_counter' => $post_counter, 'image_counter' => $image_counter]);
                    // refreshes the string
                    $board_comment_view->doBuild();
                    echo preg_replace($search, $replace, $board_comment_view->build());
                    // remove extra strings from the objects
                    $board_comment_view->clearBuilt();
                    $p->comment->clean();
                    if ($p->media !== null) {
                        $p->media->clean();
                    }
                    $this->flush();
                }
            }
            ?>
            </aside>

            <?php 
            if ($thread_id !== 0) {
                ?>
            <div class="js_hook_realtimethread"></div>
            <?php 
                echo $this->getBuilder()->isPartial('tools_reply_box') ? $this->getBuilder()->getPartial('tools_reply_box')->build() : '';
                ?>
            <?php 
            }
            ?>
            <?php 
            if (isset($post['op']) || isset($post['posts'])) {
                ?>
        </article>
        <?php 
            }
            ?>
            <?php 
        }
        ?>
        <article class="clearfix thread backlink_container">
            <div id="backlink" style="position: absolute; top: 0; left: 0; z-index: 5;"></div>
        </article>
        <?php 
    }
예제 #12
0
파일: Search.php 프로젝트: voh/FoolFuuka
 /**
  * Gets the search results
  *
  * @return  \Foolz\FoolFuuka\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_getResults()
 {
     $this->profiler->log('Search::getResults Start');
     extract($this->options);
     $boards = [];
     $input = $this->getUserInput();
     if ($this->radix !== null) {
         $boards[] = $this->radix;
     } elseif ($input['boards'] !== null) {
         foreach ($input['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 ($input['image'] !== null && substr($input['image'], -2) !== '==') {
         $input['image'] .= '==';
     }
     if ($this->radix === null && !$this->preferences->get('foolfuuka.sphinx.global')) {
         throw new SearchRequiresSphinxException(_i('Sorry, the global search function has not been enabled.'));
     }
     if ($this->radix !== null && !$this->radix->sphinx) {
         throw new SearchRequiresSphinxException(_i('Sorry, this board does not have search enabled.'));
     }
     $sphinx = explode(':', $this->preferences->get('foolfuuka.sphinx.listen'));
     $conn = new SphinxConnnection();
     $conn->setParams(['host' => $sphinx[0], 'port' => $sphinx[1], 'options' => [MYSQLI_OPT_CONNECT_TIMEOUT => 5]]);
     $indices = [];
     foreach ($boards as $radix) {
         if (!$radix->sphinx) {
             continue;
         }
         $indices[] = $radix->shortname . '_ancient';
         $indices[] = $radix->shortname . '_main';
         $indices[] = $radix->shortname . '_delta';
     }
     // establish connection
     try {
         $query = SphinxQL::create($conn)->select('id', 'board', 'tnum')->from($indices)->setFullEscapeChars(['\\', '(', ')', '|', '-', '!', '@', '%', '~', '"', '&', '/', '^', '$', '='])->setHalfEscapeChars(['\\', '(', ')', '!', '@', '%', '~', '&', '/', '^', '$', '=']);
     } catch (\Foolz\SphinxQL\Exception\ConnectionException $e) {
         throw new SearchSphinxOfflineException($this->preferences->get('foolfuuka.sphinx.custom_message', _i('The search backend is currently unavailable.')));
     }
     // process user input
     if ($input['subject'] !== null) {
         $query->match('title', $input['subject']);
     }
     if ($input['text'] !== null) {
         if (mb_strlen($input['text'], 'utf-8') < 1) {
             return [];
         }
         $query->match('comment', $input['text'], true);
     }
     if ($input['username'] !== null) {
         $query->match('name', $input['username']);
     }
     if ($input['tripcode'] !== null) {
         $query->match('trip', '"' . $input['tripcode'] . '"');
     }
     if ($input['email'] !== null) {
         $query->match('email', $input['email']);
     }
     if ($input['capcode'] !== null) {
         switch ($input['capcode']) {
             case 'user':
                 $query->where('cap', ord('N'));
                 break;
             case 'mod':
                 $query->where('cap', ord('M'));
                 break;
             case 'dev':
                 $query->where('cap', ord('D'));
                 break;
             case 'admin':
                 $query->where('cap', ord('A'));
                 break;
         }
     }
     if ($input['uid'] !== null) {
         $query->match('pid', $input['uid']);
     }
     if ($input['country'] !== null) {
         $query->match('country', $input['country'], true);
     }
     if ($this->getAuth()->hasAccess('comment.see_ip') && $input['poster_ip'] !== null) {
         $query->where('pip', (int) Inet::ptod($input['poster_ip']));
     }
     if ($input['filename'] !== null) {
         $query->match('media_filename', $input['filename']);
     }
     if ($input['image'] !== null) {
         $query->match('media_hash', '"' . $input['image'] . '"');
     }
     if ($input['deleted'] !== null) {
         switch ($input['deleted']) {
             case 'deleted':
                 $query->where('is_deleted', 1);
                 break;
             case 'not-deleted':
                 $query->where('is_deleted', 0);
                 break;
         }
     }
     if ($input['ghost'] !== null) {
         switch ($input['ghost']) {
             case 'only':
                 $query->where('is_internal', 1);
                 break;
             case 'none':
                 $query->where('is_internal', 0);
                 break;
         }
     }
     if ($input['filter'] !== null) {
         switch ($input['filter']) {
             case 'image':
                 $query->where('has_image', 0);
                 break;
             case 'text':
                 $query->where('has_image', 1);
                 break;
         }
     }
     if ($input['type'] !== null) {
         switch ($input['type']) {
             case 'sticky':
                 $query->where('is_sticky', 1);
                 break;
             case 'op':
                 $query->where('is_op', 1);
                 break;
             case 'posts':
                 $query->where('is_op', 0);
                 break;
         }
     }
     if ($input['start'] !== null) {
         $query->where('timestamp', '>=', intval(strtotime($input['start'])));
     }
     if ($input['end'] !== null) {
         $query->where('timestamp', '<=', intval(strtotime($input['end'])));
     }
     if ($input['results'] !== null && $input['results'] == 'thread') {
         $query->groupBy('tnum');
         $query->withinGroupOrderBy('is_op', 'desc');
     }
     if ($input['order'] !== null && $input['order'] == 'asc') {
         $query->orderBy('timestamp', 'ASC');
     } else {
         $query->orderBy('timestamp', 'DESC');
     }
     $max_matches = $this->preferences->get('foolfuuka.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', $input['order'] === 'asc' ? 0 : 1);
     // submit query
     try {
         $this->profiler->log('Start: SphinxQL: ' . $query->compile()->getCompiled());
         $search = $query->execute();
         $this->profiler->log('Stop: SphinxQL');
     } catch (\Foolz\SphinxQL\Exception\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']);
         if ($input['results'] !== null && $input['results'] == 'thread') {
             $post = 'num = ' . $this->dc->getConnection()->quote($result['tnum']) . ' AND subnum = 0';
         } else {
             $post = 'doc_id = ' . $this->dc->getConnection()->quote($result['id']);
         }
         $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($post)->getSQL();
     }
     $result = $this->dc->getConnection()->executeQuery(implode(' UNION ', $sql))->fetchAll();
     // 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;
 }