[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/Ui/ -> Recent.php (source)

   1  <?php
   2  
   3  namespace dokuwiki\Ui;
   4  
   5  use dokuwiki\ChangeLog\MediaChangeLog;
   6  use dokuwiki\Form\Form;
   7  
   8  /**
   9   * DokuWiki Recent Interface
  10   *
  11   * @package dokuwiki\Ui
  12   */
  13  class Recent extends Ui
  14  {
  15      protected $first;
  16      protected $show_changes;
  17  
  18      /** 
  19       * Recent Ui constructor
  20       *
  21       * @param int $first  skip the first n changelog lines
  22       * @param string $show_changes  type of changes to show; pages, mediafiles, or both
  23       */
  24      public function __construct($first = 0, $show_changes = 'both')
  25      {
  26          $this->first        = $first;
  27          $this->show_changes = $show_changes;
  28      }
  29  
  30      /**
  31       * Display recent changes
  32       *
  33       * @author Andreas Gohr <andi@splitbrain.org>
  34       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
  35       * @author Ben Coburn <btcoburn@silicodon.net>
  36       * @author Kate Arzamastseva <pshns@ukr.net>
  37       * @author Satoshi Sahara <sahara.satoshi@gmail.com>
  38       *
  39       * @return void
  40       */
  41      public function show()
  42      {
  43          global $conf, $lang;
  44          global $ID;
  45  
  46          // get recent items, and set correct pagenation parameters (first, hasNext)
  47          $first = $this->first;
  48          $hasNext = false;
  49          $recents = $this->getRecents($first, $hasNext);
  50  
  51          // print intro
  52          print p_locale_xhtml('recent');
  53  
  54          if (getNS($ID) != '') {
  55              print '<div class="level1"><p>'
  56                  . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent'))
  57                  .'</p></div>';
  58          }
  59  
  60          // create the form
  61          $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']);
  62          $form->addTagOpen('div')->addClass('no');
  63          $form->setHiddenField('sectok', null);
  64          $form->setHiddenField('do', 'recent');
  65          $form->setHiddenField('id', $ID);
  66  
  67          // show dropdown selector, whether include not only recent pages but also recent media files?
  68          if ($conf['mediarevisions']) {
  69              $this->addRecentItemSelector($form);
  70          }
  71  
  72          // start listing of recent items
  73          $form->addTagOpen('ul');
  74          foreach ($recents as $recent) {
  75              $objRevInfo = $this->getObjRevInfo($recent);
  76              $class = ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': '';
  77              $form->addTagOpen('li')->addClass($class);
  78              $form->addTagOpen('div')->addClass('li');
  79              $html = implode(' ', [
  80                  $objRevInfo->itemIcon(),          // filetype icon
  81                  $objRevInfo->editDate(),          // edit date and time
  82                  $objRevInfo->difflink(),          // link to diffview icon
  83                  $objRevInfo->revisionlink(),      // linkto revisions icon
  84                  $objRevInfo->itemName(),          // name of page or media
  85                  $objRevInfo->editSummary(),       // edit summary
  86                  $objRevInfo->editor(),            // editor info
  87                  $objRevInfo->sizechange(),        // size change indicator
  88              ]);
  89              $form->addHTML($html);
  90              $form->addTagClose('div');
  91              $form->addTagClose('li');
  92          }
  93          $form->addTagClose('ul');
  94  
  95          $form->addTagClose('div'); // close div class=no
  96  
  97          // provide navigation for pagenated recent list (of pages and/or media files)
  98          $form->addHTML($this->htmlNavigation($first, $hasNext));
  99  
 100          print $form->toHTML('Recent');
 101      }
 102  
 103      /**
 104       * Get recent items, and set correct pagenation parameters (first, hasNext)
 105       *
 106       * @param int  $first
 107       * @param bool $hasNext
 108       * @return array  recent items to be shown in a pagenated list
 109       *
 110       * @see also dokuwiki\Changelog::getRevisionInfo()
 111       */
 112      protected function getRecents(&$first, &$hasNext)
 113      {
 114          global $ID, $conf;
 115  
 116          $flags = 0;
 117          if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
 118              $flags = RECENTS_MEDIA_CHANGES;
 119          } elseif ($this->show_changes == 'pages') {
 120              $flags = 0;
 121          } elseif ($conf['mediarevisions']) {
 122              $flags = RECENTS_MEDIA_PAGES_MIXED;
 123          }
 124  
 125          /* we need to get one additionally log entry to be able to
 126           * decide if this is the last page or is there another one.
 127           * This is the cheapest solution to get this information.
 128           */
 129          $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
 130          if (count($recents) == 0 && $first != 0) {
 131              $first = 0;
 132              $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
 133          }
 134  
 135          $hasNext = false;
 136          if (count($recents) > $conf['recent']) {
 137              $hasNext = true;
 138              array_pop($recents); // remove extra log entry
 139          }
 140          return $recents;
 141      }
 142  
 143      /**
 144       * Navigation buttons for Pagenation (prev/next)
 145       *
 146       * @param int  $first
 147       * @param bool $hasNext
 148       * @return array  html
 149       */
 150      protected function htmlNavigation($first, $hasNext)
 151      {
 152          global $conf, $lang;
 153  
 154          $last = $first + $conf['recent'];
 155          $html = '<div class="pagenav">';
 156          if ($first > 0) {
 157              $first = max($first - $conf['recent'], 0);
 158              $html.= '<div class="pagenav-prev">';
 159              $html.= '<button type="submit" name="first['.$first.']" accesskey="n"'
 160                    . ' title="'.$lang['btn_newer'].' [N]" class="button show">'
 161                    . $lang['btn_newer']
 162                    . '</button>';
 163              $html.= '</div>';
 164          }
 165          if ($hasNext) {
 166              $html.= '<div class="pagenav-next">';
 167              $html.= '<button type="submit" name="first['.$last.']" accesskey="p"'
 168                    . ' title="'.$lang['btn_older'].' [P]" class="button show">'
 169                    . $lang['btn_older']
 170                    . '</button>';
 171              $html.= '</div>';
 172          }
 173          $html.= '</div>';
 174          return $html;
 175      }
 176  
 177      /**
 178       * Add dropdown selector of item types to the form instance
 179       *
 180       * @param Form $form
 181       * @return void
 182       */
 183      protected function addRecentItemSelector(Form $form)
 184      {
 185          global $lang;
 186  
 187          $form->addTagOpen('div')->addClass('changeType');
 188          $options = array(
 189                      'pages'      => $lang['pages_changes'],
 190                      'mediafiles' => $lang['media_changes'],
 191                      'both'       => $lang['both_changes'],
 192          );
 193          $form->addDropdown('show_changes', $options, $lang['changes_type'])
 194                  ->val($this->show_changes)->addClass('quickselect');
 195          $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit');
 196          $form->addTagClose('div');
 197      }
 198  
 199      /**
 200       * Returns instance of objRevInfo
 201       * @param array $info  Revision info structure of page or media
 202       * @return objRevInfo object (anonymous class)
 203       */
 204      protected function getObjRevInfo(array $info)
 205      {
 206          return new class ($info) // anonymous class (objRevInfo)
 207          {
 208              protected $info;
 209  
 210              public function __construct(array $info)
 211              {
 212                  $this->info = $info;
 213              }
 214  
 215              // fileicon of the page or media file
 216              public function itemIcon()
 217              {
 218                  $id = $this->info['id'];
 219                  if (isset($this->info['media'])) {
 220                      $html = media_printicon($id);
 221                  } else {
 222                      $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />';
 223                  }
 224                  return $html;
 225              }
 226  
 227              // edit date and time of the page or media file
 228              public function editDate()
 229              {
 230                  return '<span class="date">'. dformat($this->info['date']) .'</span>';
 231              }
 232  
 233              // edit summary
 234              public function editSummary()
 235              {
 236                  return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>';
 237              }
 238  
 239              // editor of the page or media file
 240              public function editor()
 241              {
 242                  $html = '<span class="user">';
 243                  if ($this->info['user']) {
 244                      $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
 245                      if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
 246                  } else {
 247                      $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
 248                  }
 249                  $html.= '</span>';
 250                  return $html;
 251              }
 252  
 253              // name of the page or media file
 254              public function itemName()
 255              {
 256                  $id = $this->info['id'];
 257                  if (isset($this->info['media'])) {
 258                      $href = media_managerURL(['tab_details'=>'view', 'image'=> $id, 'ns'=> getNS($id)], '&');
 259                      $class = file_exists(mediaFN($id)) ? 'wikilink1' : 'wikilink2';
 260                      $html = '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>';
 261                  } else {
 262                      $html = html_wikilink(':'.$id, (useHeading('navigation') ? null : $id));
 263                  }
 264                  return $html;
 265              }
 266  
 267              // icon difflink
 268              public function difflink()
 269              {
 270                  global $lang;
 271                  $id = $this->info['id'];
 272  
 273                  if (isset($this->info['media'])) {
 274                      $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
 275                      $diff = (count($revs) && file_exists(mediaFN($id)));
 276                      if ($diff) {
 277                          $href = media_managerURL(
 278                              ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&'
 279                          );
 280                      } else {
 281                          $href = '';
 282                      }
 283                  } else {
 284                      $href = wl($id, "do=diff", false, '&');
 285                  }
 286  
 287                  if ($href) {
 288                      $html = '<a href="'.$href.'" class="diff_link">'
 289                            . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
 290                            . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
 291                            . '</a>';
 292                  } else {
 293                      $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
 294                  }
 295                  return $html;
 296              }
 297  
 298              // icon revision link
 299              public function revisionlink()
 300              {
 301                  global $lang;
 302                  $id = $this->info['id'];
 303                  if (isset($this->info['media'])) {
 304                      $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&');
 305                  } else {
 306                      $href = wl($id, "do=revisions", false, '&');
 307                  }
 308                  $html = '<a href="'.$href.'" class="revisions_link">'
 309                        . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"'
 310                        . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
 311                        . '</a>';
 312                  return $html;
 313              }
 314  
 315              // size change
 316              public function sizeChange()
 317              {
 318                  $class = 'sizechange';
 319                  $value = filesize_h(abs($this->info['sizechange']));
 320                  if ($this->info['sizechange'] > 0) {
 321                      $class .= ' positive';
 322                      $value = '+' . $value;
 323                  } elseif ($this->info['sizechange'] < 0) {
 324                      $class .= ' negative';
 325                      $value = '-' . $value;
 326                  } else {
 327                      $value = '±' . $value;
 328                  }
 329                  return '<span class="'.$class.'">'.$value.'</span>';
 330              }
 331          }; // end of anonymous class (objRevInfo)
 332      }
 333  
 334  }