Failed Conditions
Pull Request — master (#3198)
by
unknown
03:26
created

Recent.php$0 ➔ itemIcon()   A

Complexity

Conditions 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\Ui;
4
5
use dokuwiki\ChangeLog\MediaChangeLog;
6
use dokuwiki\Extension\Event;
7
use dokuwiki\Form\Form;
8
9
/**
10
 * DokuWiki Recent Interface
11
 *
12
 * @package dokuwiki\Ui
13
 */
14
class Recent extends Ui
15
{
16
    protected $first;
17
    protected $show_changes;
18
19
    /** 
20
     * Recent Ui constructor
21
     *
22
     * @param int $first  skip the first n changelog lines
23
     * @param string $show_changes  type of changes to show; pages, mediafiles, or both
24
     */
25
    public function __construct($first = 0, $show_changes = 'both')
26
    {
27
        $this->first        = $first;
28
        $this->show_changes = $show_changes;
29
    }
30
31
    /**
32
     * Display recent changes
33
     *
34
     * @author Andreas Gohr <[email protected]>
35
     * @author Matthias Grimm <[email protected]>
36
     * @author Ben Coburn <[email protected]>
37
     * @author Kate Arzamastseva <[email protected]>
38
     * @author Satoshi Sahara <[email protected]>
39
     *
40
     * @triggers HTMLFORM_RECENT_OUTPUT
41
     * @return void
42
     */
43
    public function show()
44
    {
45
        global $lang;
46
        global $ID;
47
48
        // get recent items, and set correct pagenation parameters (first, hasNext)
49
        $first = $this->first;
50
        $hasNext = false;
51
        $recents = $this->getRecents($first, $hasNext);
52
53
        // print intro
54
        print p_locale_xhtml('recent');
55
56
        if (getNS($ID) != '') {
57
            print '<div class="level1"><p>'
58
                . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent'))
59
                .'</p></div>';
60
        }
61
62
        // create the form
63
        $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']);
64
        $form->addTagOpen('div')->addClass('no');
65
        $form->setHiddenField('sectok', null);
66
        $form->setHiddenField('do', 'recent');
67
        $form->setHiddenField('id', $ID);
68
69
        // show dropdown selector, whether include not only recent pages but also recent media files?
70
        if ($conf['mediarevisions']) {
0 ignored issues
show
Bug introduced by
The variable $conf does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
71
            $this->addRecentItemSelector($form);
72
        }
73
74
        // start listing of recent items
75
        $form->addTagOpen('ul');
76
        foreach ($recents as $recent) {
77
            $objRevInfo = $this->getObjRevInfo($recent);
78
            $class = ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': '';
79
            $form->addTagOpen('li')->addClass($class);
80
            $form->addTagOpen('div')->addClass('li');
81
            $html = implode(' ', [
82
                $objRevInfo->itemIcon(),          // filetype icon
83
                $objRevInfo->editDate(),          // edit date and time
84
                $objRevInfo->difflink(),          // link to diffview icon
85
                $objRevInfo->revisionlink(),      // linkto revisions icon
86
                $objRevInfo->itemName(),          // name of page or media
87
                $objRevInfo->editSummary(),       // edit summary
88
                $objRevInfo->editor(),            // editor info
89
                html_sizechange($recent['sizechange']), // size change indicator
90
            ]);
91
            $form->addHTML($html);
92
            $form->addTagClose('div');
93
            $form->addTagClose('li');
94
        }
95
        $form->addTagClose('ul');
96
97
        $form->addTagClose('div'); // close div class=no
98
99
        // provide navigation for pagenated recent list (of pages and/or media files)
100
        $form->addHTML($this->htmlNavigation($first, $hasNext));
101
102
        // print form that might be modified by HTMLFORM_RECENT_OUTPUT event handlers
103
        print $form->toHTML('recent');
104
    }
105
106
    /**
107
     * Get recent items, and set correct pagenation parameters (first, hasNext)
108
     *
109
     * @param int  $first
110
     * @param bool $hasNext
111
     * @return array  recent items to be shown in a pagenated list
112
     *
113
     * @see also dokuwiki\Changelog::getRevisionInfo()
114
     */
115
    protected function getRecents(&$first, &$hasNext)
116
    {
117
        global $ID, $conf;
118
119
        $flags = 0;
120
        if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
121
            $flags = RECENTS_MEDIA_CHANGES;
122
        } elseif ($this->show_changes == 'pages') {
123
            $flags = 0;
124
        } elseif ($conf['mediarevisions']) {
125
            $flags = RECENTS_MEDIA_PAGES_MIXED;
126
        }
127
128
        /* we need to get one additionally log entry to be able to
129
         * decide if this is the last page or is there another one.
130
         * This is the cheapest solution to get this information.
131
         */
132
        $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
Security Bug introduced by
It seems like getNS($ID) targeting getNS() can also be of type false; however, getRecents() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
133
        if (count($recents) == 0 && $first != 0) {
134
            $first = 0;
135
            $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
Security Bug introduced by
It seems like getNS($ID) targeting getNS() can also be of type false; however, getRecents() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
136
        }
137
138
        $hasNext = false;
139
        if (count($recents) > $conf['recent']) {
140
            $hasNext = true;
141
            array_pop($recents); // remove extra log entry
142
        }
143
        return $recents;
144
    }
145
146
    /**
147
     * Navigation buttons for Pagenation (prev/next)
148
     *
149
     * @param int  $first
150
     * @param bool $hasNext
151
     * @return array  html
152
     */
153
    protected function htmlNavigation($first, $hasNext)
154
    {
155
        global $conf, $lang;
156
157
        $last = $first + $conf['recent'];
158
        $html = '<div class="pagenav">';
159
        if ($first > 0) {
160
            $first = max($first - $conf['recent'], 0);
161
            $html.= '<div class="pagenav-prev">';
162
            $html.= '<button type="submit" name="first['.$first.']" accesskey="n"'
163
                  . ' title="'.$lang['btn_newer'].' [N]" class="button show">'
164
                  . $lang['btn_newer']
165
                  . '</button>';
166
            $html.= '</div>';
167
        }
168
        if ($hasNext) {
169
            $html.= '<div class="pagenav-next">';
170
            $html.= '<button type="submit" name="first['.$last.']" accesskey="p"'
171
                  . ' title="'.$lang['btn_older'].' [P]" class="button show">'
172
                  . $lang['btn_older']
173
                  . '</button>';
174
            $html.= '</div>';
175
        }
176
        $html.= '</div>';
177
        return $html;
178
    }
179
180
    /**
181
     * Add dropdown selector of item types to the form instance
182
     *
183
     * @param Form $form
184
     * @return void
185
     */
186
    protected function addRecentItemSelector(Form $form)
187
    {
188
        global $lang;
189
190
        $form->addTagOpen('div')->addClass('changeType');
191
        $options = array(
192
                    'pages'      => $lang['pages_changes'],
193
                    'mediafiles' => $lang['media_changes'],
194
                    'both'       => $lang['both_changes'],
195
        );
196
        $form->addDropdown('show_changes', $options, $lang['changes_type'])
197
                ->val($this->show_changes)->addClass('quickselect');
198
        $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit');
199
        $form->addTagClose('div');
200
    }
201
202
    /**
203
     * Returns instance of objRevInfo
204
     * @param array $info  Revision info structure of page or media
205
     * @return objRevInfo object (anonymous class)
206
     */
207
    protected function getObjRevInfo(array $info)
208
    {
209
        return new class ($info) // anonymous class (objRevInfo)
210
        {
211
            protected $info;
212
213
            public function __construct(array $info)
214
            {
215
                $this->info = $info;
216
            }
217
218
            // fileicon of the page or media file
219
            public function itemIcon()
220
            {
221
                $id = $this->info['id'];
222
                if (isset($this->info['media'])) {
223
                    $html = media_printicon($id);
224
                } else {
225
                    $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />';
226
                }
227
                return $html;
228
            }
229
230
            // edit date and time of the page or media file
231
            public function editDate()
232
            {
233
                $date = $this->info['date'];
234
                $html = '<span class="date">'. dformat($date) .'</span>';
235
                return $html;
236
            }
237
238
            // icon difflink
239
            public function difflink()
240
            {
241
                global $lang;
242
                $id = $this->info['id'];
243
                $diff = false;
244
245
                if (isset($this->info['media'])) {
246
                    $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
247
                    $diff = (count($revs) && file_exists(mediaFN($id)));
248
                    if ($diff) {
249
                        $href = media_managerURL(
250
                            ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&'
251
                        );
252
                    }
253
                } else {
254
                    $href = wl($id, "do=diff", false, '&');
255
                }
256
257
                if (isset($this->info['media']) && !$diff) {
258
                    $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
259
                } else {
260
                    $html = '<a href="'.$href.'" class="diff_link">'
0 ignored issues
show
Bug introduced by
The variable $href does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
261
                          . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
262
                          . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
263
                          . '</a>';
264
                }
265
                return $html;
266
            }
267
268
            // icon revision link
269
            public function revisionlink()
270
            {
271
                global $lang;
272
                $id = $this->info['id'];
273
                if (isset($this->info['media'])) {
274
                    $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&');
275
                } else {
276
                    $href = wl($id, "do=revisions", false, '&');
277
                }
278
                $html = '<a href="'.$href.'" class="revisions_link">'
279
                      . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"'
280
                      . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
281
                      . '</a>';
282
                return $html;
283
            }
284
285
            // name of the page or media file
286
            public function itemName()
287
            {
288
                $id = $this->info['id'];
289
                if (isset($this->info['media'])) {
290
                    $href = media_managerURL(['tab_details'=>'view', 'image'=> $id, 'ns'=> getNS($id)], '&');
291
                    $class = file_exists(mediaFN($id)) ? 'wikilink1' : 'wikilink2';
292
                    $html = '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>';
293
                } else {
294
                    $html = html_wikilink(':'.$id, (useHeading('navigation') ? null : $id));
295
                }
296
                return $html;
297
            }
298
299
            // edit summary
300
            public function editSummary()
301
            {
302
                $html = '<span class="sum">';
303
                $html.= ' – '. hsc($this->info['sum']);
304
                $html.= '</span>';
305
                return $html;
306
            }
307
308
            // editor of the page or media file
309
            public function editor()
310
            {
311
                $html = '<span class="user">';
312
                if ($this->info['user']) {
313
                    $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
314
                    if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
315
                } else {
316
                    $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
317
                }
318
                $html.= '</span>';
319
                return $html;
320
            }
321
        }; // end of anonymous class (objRevInfo)
322
    }
323
324
}
325