[ 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\ChangeLog\PageChangeLog;
   7  use dokuwiki\ChangeLog\RevisionInfo;
   8  use dokuwiki\Form\Form;
   9  
  10  /**
  11   * DokuWiki Recent Interface
  12   *
  13   * @package dokuwiki\Ui
  14   */
  15  class Recent extends Ui
  16  {
  17      protected $first;
  18      protected $show_changes;
  19  
  20      /**
  21       * Recent Ui constructor
  22       *
  23       * @param int $first skip the first n changelog lines
  24       * @param string $show_changes type of changes to show; 'pages', 'mediafiles', or 'both'
  25       */
  26      public function __construct($first = 0, $show_changes = 'both')
  27      {
  28          $this->first = $first;
  29          $this->show_changes = $show_changes;
  30      }
  31  
  32      /**
  33       * Display recent changes
  34       *
  35       * @return void
  36       * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
  37       * @author Ben Coburn <btcoburn@silicodon.net>
  38       * @author Kate Arzamastseva <pshns@ukr.net>
  39       * @author Satoshi Sahara <sahara.satoshi@gmail.com>
  40       *
  41       * @author Andreas Gohr <andi@splitbrain.org>
  42       */
  43      public function show()
  44      {
  45          global $conf, $lang;
  46          global $ID;
  47  
  48          // get recent items, and set correct pagination parameters (first, hasNext)
  49          $first = $this->first;
  50          $hasNext = false;
  51          $recents = $this->getRecents($first, $hasNext);
  52  
  53          // print intro
  54          echo p_locale_xhtml('recent');
  55  
  56          if (getNS($ID) != '') {
  57              echo '<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']) {
  71              $this->addRecentItemSelector($form);
  72          }
  73  
  74          // start listing of recent items
  75          $form->addTagOpen('ul');
  76          foreach ($recents as $recent) {
  77              // check possible external edition for current page or media
  78              $this->checkCurrentRevision($recent);
  79  
  80              $RevInfo = new RevisionInfo($recent);
  81              $RevInfo->isCurrent(true);
  82              $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : '';
  83              $form->addTagOpen('li')->addClass($class);
  84              $form->addTagOpen('div')->addClass('li');
  85              $html = implode(' ', [
  86                  $RevInfo->showFileIcon(),          // filetype icon
  87                  $RevInfo->showEditDate(),          // edit date and time
  88                  $RevInfo->showIconCompareWithPrevious(),    // link to diff view icon
  89                  $RevInfo->showIconRevisions(),     // link to revisions icon
  90                  $RevInfo->showFileName(),          // name of page or media
  91                  $RevInfo->showEditSummary(),       // edit summary
  92                  $RevInfo->showEditor(),            // editor info
  93                  $RevInfo->showSizechange(),        // size change indicator
  94              ]);
  95              $form->addHTML($html);
  96              $form->addTagClose('div');
  97              $form->addTagClose('li');
  98          }
  99          $form->addTagClose('ul');
 100  
 101          $form->addTagClose('div'); // close div class=no
 102  
 103          // provide navigation for paginated recent list (of pages and/or media files)
 104          $form->addHTML($this->htmlNavigation($first, $hasNext));
 105  
 106          echo $form->toHTML('Recent');
 107      }
 108  
 109      /**
 110       * Get recent items, and set correct pagination parameters (first, hasNext)
 111       *
 112       * @param int $first
 113       * @param bool $hasNext
 114       * @return array  recent items to be shown in a paginated list
 115       *
 116       * @see also dokuwiki\Changelog::getRevisionInfo()
 117       */
 118      protected function getRecents(&$first, &$hasNext)
 119      {
 120          global $ID, $conf;
 121  
 122          $flags = 0;
 123          if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
 124              $flags = RECENTS_MEDIA_CHANGES;
 125          } elseif ($this->show_changes == 'pages') {
 126              $flags = 0;
 127          } elseif ($conf['mediarevisions']) {
 128              $flags = RECENTS_MEDIA_PAGES_MIXED;
 129          }
 130  
 131          /* we need to get one additionally log entry to be able to
 132           * decide if this is the last page or is there another one.
 133           * This is the cheapest solution to get this information.
 134           */
 135          $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
 136          if (count($recents) == 0 && $first != 0) {
 137              $first = 0;
 138              $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
 139          }
 140  
 141          $hasNext = false;
 142          if (count($recents) > $conf['recent']) {
 143              $hasNext = true;
 144              array_pop($recents); // remove extra log entry
 145          }
 146          return $recents;
 147      }
 148  
 149      /**
 150       * Check possible external deletion for current page or media
 151       *
 152       * To keep sort order in the recent list, we ignore externally modification.
 153       * It is not possible to know when external deletion had happened,
 154       * $info['date'] is to be incremented 1 second when such deletion detected.
 155       */
 156      protected function checkCurrentRevision(array &$info)
 157      {
 158          if ($info['mode'] == RevisionInfo::MODE_PAGE) {
 159              $changelog = new PageChangelog($info['id']);
 160          } else {
 161              $changelog = new MediaChangelog($info['id']);
 162          }
 163          if (!$changelog->isCurrentRevision($info['date'])) {
 164              $currentRevInfo = $changelog->getCurrentRevisionInfo();
 165              if ($currentRevInfo['type'] == DOKU_CHANGE_TYPE_DELETE) {
 166                  // the page or media file was externally deleted, updated info because the link is already red
 167                  // externally created and edited not updated because sorting by date is not worth so much changes
 168                  $info = array_merge($info, $currentRevInfo);
 169              }
 170          }
 171          unset($changelog);
 172      }
 173  
 174      /**
 175       * Navigation buttons for Pagination (prev/next)
 176       *
 177       * @param int $first
 178       * @param bool $hasNext
 179       * @return string html
 180       */
 181      protected function htmlNavigation($first, $hasNext)
 182      {
 183          global $conf, $lang;
 184  
 185          $last = $first + $conf['recent'];
 186          $html = '<div class="pagenav">';
 187          if ($first > 0) {
 188              $first = max($first - $conf['recent'], 0);
 189              $html .= '<div class="pagenav-prev">';
 190              $html .= '<button type="submit" name="first[' . $first . ']" accesskey="n"'
 191                  . ' title="' . $lang['btn_newer'] . ' [N]" class="button show">'
 192                  . $lang['btn_newer']
 193                  . '</button>';
 194              $html .= '</div>';
 195          }
 196          if ($hasNext) {
 197              $html .= '<div class="pagenav-next">';
 198              $html .= '<button type="submit" name="first[' . $last . ']" accesskey="p"'
 199                  . ' title="' . $lang['btn_older'] . ' [P]" class="button show">'
 200                  . $lang['btn_older']
 201                  . '</button>';
 202              $html .= '</div>';
 203          }
 204          $html .= '</div>';
 205          return $html;
 206      }
 207  
 208      /**
 209       * Add dropdown selector of item types to the form instance
 210       *
 211       * @param Form $form
 212       * @return void
 213       */
 214      protected function addRecentItemSelector(Form $form)
 215      {
 216          global $lang;
 217  
 218          $form->addTagOpen('div')->addClass('changeType');
 219          $options = [
 220              'pages' => $lang['pages_changes'],
 221              'mediafiles' => $lang['media_changes'],
 222              'both' => $lang['both_changes']
 223          ];
 224          $form->addDropdown('show_changes', $options, $lang['changes_type'])
 225              ->val($this->show_changes)->addClass('quickselect');
 226          $form->addButton('do[recent]', $lang['btn_apply'])->attr('type', 'submit');
 227          $form->addTagClose('div');
 228      }
 229  }