[ 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\PageChangeLog;
   6  use dokuwiki\ChangeLog\MediaChangeLog;
   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       * @author Andreas Gohr <andi@splitbrain.org>
  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       * @return void
  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          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']) {
  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          print $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          $itemType = $info['media'] ? 'media' : 'page';
 159          if ($itemType == 'page') {
 160              $changelog = new PageChangelog($info['id']);
 161          } else {
 162              $changelog = new MediaChangelog($info['id']);
 163          }
 164          if (!$changelog->isCurrentRevision($info['date'])) {
 165              $currentRevInfo = $changelog->getCurrentRevisionInfo();
 166              if ($currentRevInfo['type'] == DOKU_CHANGE_TYPE_DELETE) {
 167                  // the page or media file was externally deleted, updated info because the link is already red
 168                  // externally created and edited not updated because sorting by date is not worth so much changes
 169                  $info = array_merge($info, $currentRevInfo);
 170              }
 171          }
 172          unset($changelog);
 173      }
 174  
 175      /**
 176       * Navigation buttons for Pagination (prev/next)
 177       *
 178       * @param int  $first
 179       * @param bool $hasNext
 180       * @return string html
 181       */
 182      protected function htmlNavigation($first, $hasNext)
 183      {
 184          global $conf, $lang;
 185  
 186          $last = $first + $conf['recent'];
 187          $html = '<div class="pagenav">';
 188          if ($first > 0) {
 189              $first = max($first - $conf['recent'], 0);
 190              $html.= '<div class="pagenav-prev">';
 191              $html.= '<button type="submit" name="first['.$first.']" accesskey="n"'
 192                    . ' title="'.$lang['btn_newer'].' [N]" class="button show">'
 193                    . $lang['btn_newer']
 194                    . '</button>';
 195              $html.= '</div>';
 196          }
 197          if ($hasNext) {
 198              $html.= '<div class="pagenav-next">';
 199              $html.= '<button type="submit" name="first['.$last.']" accesskey="p"'
 200                    . ' title="'.$lang['btn_older'].' [P]" class="button show">'
 201                    . $lang['btn_older']
 202                    . '</button>';
 203              $html.= '</div>';
 204          }
 205          $html.= '</div>';
 206          return $html;
 207      }
 208  
 209      /**
 210       * Add dropdown selector of item types to the form instance
 211       *
 212       * @param Form $form
 213       * @return void
 214       */
 215      protected function addRecentItemSelector(Form $form)
 216      {
 217          global $lang;
 218  
 219          $form->addTagOpen('div')->addClass('changeType');
 220          $options = array(
 221                      'pages'      => $lang['pages_changes'],
 222                      'mediafiles' => $lang['media_changes'],
 223                      'both'       => $lang['both_changes'],
 224          );
 225          $form->addDropdown('show_changes', $options, $lang['changes_type'])
 226                  ->val($this->show_changes)->addClass('quickselect');
 227          $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit');
 228          $form->addTagClose('div');
 229      }
 230  
 231  }