Issues (326)

src/View/Helper/PostingHelper.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace App\View\Helper;
14
15
use App\View\Helper\TimeHHelper;
16
use Cake\Core\Configure;
17
use Cake\View\Helper\FormHelper;
18
use Cake\View\Helper\HtmlHelper;
19
use Saito\Event\SaitoEventManager;
20
use Saito\Posting\Basic\BasicPostingInterface;
21
use Saito\Posting\PostingInterface;
22
use Saito\Thread\Renderer;
23
24
/**
25
 * Class PostingHelper
26
 *
27
 * @property FormHelper $Form
28
 * @property HtmlHelper $Html
29
 * @property TimeHHelper $TimeH
30
 * @package App\View\Helper
31
 */
32
class PostingHelper extends AppHelper
33
{
34
    public $helpers = ['Form', 'Html', 'TimeH'];
35
36
    /**
37
     * @var array perf-cheat for renderers
38
     */
39
    protected $_renderers = [];
40
41
    /**
42
     * @var SaitoEventManager
43
     */
44
    protected $_SEM;
45
46
    /**
47
     * get paginated index
48
     *
49
     * @param int $tid tid
50
     * @param null|string $lastAction last action
51
     * @return string
52
     */
53
    public function getPaginatedIndexPageId(int $tid, ?string $lastAction = null): string
54
    {
55
        $params = [];
56
        if ($lastAction !== 'add') {
57
            $session = $this->getView()->getRequest()->getSession();
58
            if ($session->read('paginator.lastPage')) {
59
                $params[] = 'page=' . $session->read('paginator.lastPage');
0 ignored issues
show
Are you sure $session->read('paginator.lastPage') of type array|null|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
                $params[] = 'page=' . /** @scrutinizer ignore-type */ $session->read('paginator.lastPage');
Loading history...
60
            }
61
        }
62
        $params[] = 'jump=' . $tid;
63
64
        return '/?' . implode('&', $params);
65
    }
66
67
    /**
68
     * Get fast link for posting.
69
     *
70
     * @param BasicPostingInterface $posting posting
71
     * @param array $options options
72
     * @return string HTML
73
     */
74
    public function getFastLink(BasicPostingInterface $posting, array $options = [])
75
    {
76
        $options += ['class' => ''];
77
        $id = $posting->get('id');
78
        $webroot = $this->getView()->getRequest()->getAttribute('webroot');
79
        $url = "{$webroot}entries/view/{$id}";
80
        $link = "<a href=\"{$url}\" class=\"{$options['class']}\">" . $this->getSubject($posting) . '</a>';
81
82
        return $link;
83
    }
84
85
    /**
86
     * Render view counter
87
     *
88
     * @param BasicPostingInterface $posting posting
89
     *
90
     * @return string
91
     */
92
    public function views(BasicPostingInterface $posting)
93
    {
94
        return __('views_headline') . ': ' . $posting->get('views');
95
    }
96
97
    /**
98
     * renders a posting tree as thread
99
     *
100
     * @param PostingInterface $tree passed as reference to share CU-decorator "up"
101
     * @param array $options options
102
     *    - 'renderer' [thread]|mix
103
     * @return string
104
     * @internal param CurrentUser $CurrentUser current user
105
     */
106
    public function renderThread(PostingInterface $tree, array $options = [])
107
    {
108
        $options += [
109
            'lineCache' => $this->_View->get('LineCache'),
110
            'maxThreadDepthIndent' => (int)Configure::read(
111
                'Saito.Settings.thread_depth_indent'
112
            ),
113
            'renderer' => 'thread',
114
            'rootWrap' => false,
115
        ];
116
        $renderer = $options['renderer'];
117
        unset($options['renderer']);
118
119
        if (isset($this->_renderers[$renderer])) {
120
            $renderer = $this->_renderers[$renderer];
121
        } else {
122
            $name = $renderer;
123
            switch ($name) {
124
                case 'mix':
125
                    $renderer = new Renderer\MixHtmlRenderer($this);
126
                    break;
127
                case 'thread':
128
                    $renderer = new Renderer\ThreadHtmlRenderer($this);
129
                    break;
130
                case (is_string($renderer)):
131
                    $renderer = new $renderer($this);
132
                    break;
133
                default:
134
                    $renderer = new Renderer\ThreadHtmlRenderer($this);
135
            }
136
            $this->_renderers[$name] = $renderer;
137
        }
138
        $renderer->setOptions($options);
139
140
        return $renderer->render($tree);
141
    }
142
143
    /**
144
     * Get badges
145
     *
146
     * @param PostingInterface $entry posting
147
     * @return string
148
     */
149
    public function getBadges(PostingInterface $entry)
150
    {
151
        $out = '';
152
        if ($entry->isPinned()) {
153
            $out .= '<i class="fa fa-thumb-tack" title="' . __('fixed') . '"></i> ';
154
        }
155
        // anchor for inserting solve-icon via FE-JS
156
        $out .= '<span class="solves ' . $entry->get('id') . '">';
157
        if ($entry->get('solves')) {
158
            $out .= $this->solvedBadge();
159
        }
160
        $out .= '</span>';
161
162
        $additionalBadges = $this->getSaitoEventManager()->dispatch(
163
            'saito.core.posting.view.badges.request',
164
            ['posting' => $entry->toArray()]
165
        );
166
        if ($additionalBadges) {
167
            $out .= implode('', $additionalBadges);
168
        }
169
170
        return $out;
171
    }
172
173
    /**
174
     * Get solved badge
175
     *
176
     * @return string
177
     */
178
    public function solvedBadge()
179
    {
180
        return '<i class="fa fa-badge-solves solves-isSolved" title="' .
181
        __('Helpful entry') . '"></i>';
182
    }
183
184
    /**
185
     * This function may be called serveral hundred times on the front page.
186
     * Don't make ist slow, benchmark!
187
     *
188
     * @param BasicPostingInterface $posting posting
189
     * @return string
190
     */
191
    public function getSubject(BasicPostingInterface $posting)
192
    {
193
        return \h($posting->get('subject')) . ($posting->isNt() ? ' n/t' : '');
194
    }
195
196
    /**
197
     * Generate URL to mix view from Posting
198
     *
199
     * @param PostingInterface $posting Posting to generate URL for
200
     * @param bool $jump Jump to posting in mix view
201
     * @param bool $base Add base in front
202
     * @return string
203
     */
204
    public function urlToMix(PostingInterface $posting, bool $jump = true, bool $base = true): string
205
    {
206
        $tid = $posting->get('tid');
207
        $url = '';
208
        if ($base) {
209
            $url .= $this->getView()->getRequest()->getAttribute('base');
210
        }
211
        $url .= "/entries/mix/${tid}";
212
        $url .= $jump ? '#' . $posting->get('id') : '';
213
214
        return $url;
215
    }
216
217
    /**
218
     * Gets SaitoEventManager
219
     *
220
     * @return SaitoEventManager
221
     */
222
    private function getSaitoEventManager(): SaitoEventManager
223
    {
224
        if ($this->_SEM === null) {
225
            $this->_SEM = SaitoEventManager::getInstance();
226
        }
227
228
        return $this->_SEM;
229
    }
230
}
231