1<?php 2 3/** 4 * Dokuwiki WebDAV Plugin: Admin Interface 5 * 6 * @link https://dokuwiki.org/plugin:webdav 7 * @author Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com> 8 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 9 */ 10 11require_once DOKU_PLUGIN . 'webdav/vendor/autoload.php'; 12 13use Sabre\DAV\Locks\LockInfo; 14 15class admin_plugin_webdav extends DokuWiki_Admin_Plugin 16{ 17 /** @inheritDoc */ 18 public function getMenuSort() 19 { 20 return 1; 21 } 22 23 /** @inheritDoc */ 24 public function forAdminOnly() 25 { 26 return false; 27 } 28 29 /** @inheritDoc */ 30 public function getMenuIcon() 31 { 32 return dirname(__FILE__) . '/folder-network-outline.svg'; 33 } 34 35 /** @inheritDoc */ 36 public function getMenuText($language) 37 { 38 return 'WebDAV'; 39 } 40 41 /** @inheritDoc */ 42 public function handle() 43 { 44 global $INPUT; 45 46 if (!$_REQUEST['cmd']) { 47 return; 48 } 49 50 if (!checkSecurityToken()) { 51 return; 52 } 53 54 $cmd = $INPUT->extract('cmd')->str('cmd'); 55 56 $dispatch = [ 57 'unlock' => 'unlockFile', 58 ]; 59 60 if ($cmd) { 61 if (!isset($dispatch[$cmd])) { 62 msg('Unknown command', -1); 63 return; 64 } 65 call_user_func([$this, $dispatch[$cmd]]); 66 } 67 } 68 69 /** 70 * Unlock file 71 * 72 * @return bool 73 */ 74 public function unlockFile() 75 { 76 global $INPUT; 77 global $conf; 78 79 $lock_id = $INPUT->str('lock'); 80 $locks_file = $conf['cachedir'] . '/webdav.lock'; 81 $locked_file = ''; 82 83 if (!$lock_id) { 84 msg('No lock provided', -1); 85 return; 86 } 87 88 if ($locks = $this->getLocks()) { 89 foreach ($locks as $id => $lock) { 90 if ($lock->token == $lock_id) { 91 $locked_file = $lock->uri; 92 unset($locks[$id]); 93 } 94 } 95 96 if ($locked_file) { 97 if (!io_saveFile($locks_file, serialize($locks))) { 98 msg('Unlock failed', -1); 99 return; 100 } 101 102 msg("File $locked_file successfully unlocked", 1); 103 } 104 } 105 } 106 107 /** @inheritDoc */ 108 public function html() 109 { 110 echo '<div id="plugin_advanced_export">'; 111 echo $this->locale_xhtml('intro'); 112 113 echo '<form action="" method="post" class="form-inline">'; 114 115 $this->displayLocks(); 116 117 formSecurityToken(); 118 119 echo '<input type="hidden" name="do" value="admin" />'; 120 echo '<input type="hidden" name="page" value="webdav" />'; 121 echo '<input type="hidden" name="cmd" value="unlock" />'; 122 123 echo '</form>'; 124 echo '</div>'; 125 } 126 127 /** 128 * Display active locks 129 */ 130 private function displayLocks() 131 { 132 echo '<h3>Locks</h3>'; 133 echo '<table class="inline" style="width:100%">'; 134 echo '<thead> 135 <tr> 136 <th>Owner</th> 137 <th>Timeout</th> 138 <th>Created</th> 139 <th>Type</th> 140 <th>URI</th> 141 <th>User Agent</th> 142 <th> </th> 143 </tr> 144 </thead>'; 145 echo '<tbody>'; 146 foreach ($this->getLocks() as $lock) { 147 $pathinfo = pathinfo($lock->uri); 148 echo '<tr>'; 149 echo '<td><a href="#" class="interwiki iw_user"></a>' . (($lock->owner == $lock->user) ? $lock->owner : $lock->user . ' (' . $lock->owner . ')') . '</td>'; 150 echo "<td>{$lock->timeout} seconds</td>"; 151 echo '<td>' . datetime_h($lock->created) . '<br><small>(' . dformat($lock->created) . ')</small></td>'; 152 echo "<td>{$this->getLockType($lock->scope)}</td>"; 153 echo '<td><a class="mediafile mf_' . $pathinfo['extension'] . '" href="' . getBaseURL(true) . 'lib/plugins/webdav/server.php/' . hsc($lock->uri) . '">' . $lock->uri . '</a></td>'; 154 echo "<td>{$lock->ua}</td>"; 155 echo '<td><button type="submit" class="btn btn-default btn-xs btn_unlock_file" name="lock" value="' . $lock->token . '">Unlock</button></td>'; 156 echo '</tr>'; 157 } 158 echo '</tbody>'; 159 echo '</table>'; 160 } 161 162 /** 163 * Get active locks 164 * 165 * @return array 166 */ 167 private function getLocks() 168 { 169 global $conf; 170 171 $locks = []; 172 $locks_file = $conf['cachedir'] . '/webdav.lock'; 173 174 if (file_exists($locks_file)) { 175 $locks = unserialize(io_readFile($locks_file)); 176 } 177 return $locks; 178 } 179 180 /** 181 * Get lock type 182 * 183 * @param string $scope 184 * @return string 185 */ 186 private function getLockType($scope) 187 { 188 switch ($scope) { 189 case LockInfo::EXCLUSIVE: 190 return 'Exclusive'; 191 case LockInfo::SHARED: 192 return 'Shared'; 193 case LockInfo::TIMEOUT_INFINITE: 194 return 'Timeout Infinite'; 195 default: 196 return 'N/A'; 197 } 198 } 199} 200