xref: /dokuwiki/bin/dwpage.php (revision f4c788ee87e2a5de27fd70cd38490ef6d0cb7aa5)
1#!/usr/bin/php
2<?php
3#------------------------------------------------------------------------------
4if ('cli' != php_sapi_name()) die();
5
6ini_set('memory_limit','128M');
7if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
8require_once DOKU_INC.'inc/init.php';
9require_once DOKU_INC.'inc/common.php';
10require_once DOKU_INC.'inc/cliopts.php';
11
12#------------------------------------------------------------------------------
13function usage($action) {
14    switch ( $action ) {
15        case 'checkout':
16           print "Usage: dwpage.php [opts] checkout <wiki:page> [working_file]
17
18    Checks out a file from the repository, using the wiki id and obtaining
19    a lock for the page.
20    If a working_file is specified, this is where the page is copied to.
21    Otherwise defaults to the same as the wiki page in the current
22    working directory.
23
24    EXAMPLE
25    $ ./dwpage.php checkout wiki:syntax ./new_syntax.txt
26
27    OPTIONS
28        -h, --help=<action>: get help
29        -f: force obtaining a lock for the page (generally bad idea)
30";
31        break;
32        case 'commit':
33           print "Usage: dwpage.php [opts] -m \"Msg\" commit <working_file> <wiki:page>
34
35    Checks in the working_file into the repository using the specified
36    wiki id, archiving the previous version.
37
38    EXAMPLE
39    $ ./dwpage.php -m \"Some message\" commit ./new_syntax.txt wiki:syntax
40
41    OPTIONS
42        -h, --help=<action>: get help
43        -f: force obtaining a lock for the page (generally bad idea)
44        -t, trivial: minor change
45        -m (required): Summary message describing the change
46";
47        break;
48        case 'lock':
49           print "Usage: dwpage.php [opts] lock <wiki:page>
50
51    Obtains or updates a lock for a wiki page
52
53    EXAMPLE
54    $ ./dwpage.php lock wiki:syntax
55
56    OPTIONS
57        -h, --help=<action>: get help
58        -f: force obtaining a lock for the page (generally bad idea)
59";
60        break;
61        case 'unlock':
62           print "Usage: dwpage.php [opts] unlock <wiki:page>
63
64    Removes a lock for a wiki page.
65
66    EXAMPLE
67    $ ./dwpage.php unlock wiki:syntax
68
69    OPTIONS
70        -h, --help=<action>: get help
71        -f: force obtaining a lock for the page (generally bad idea)
72";
73        break;
74        default:
75            print "Usage: dwpage.php [opts] <action>
76
77    Utility to help command line Dokuwiki page editing, allow
78    pages to be checked out for editing then committed after changes
79
80    Normal operation would be;
81
82
83
84    ACTIONS
85        checkout: see $ dwpage.php --help=checkout
86        commit: see $ dwpage.php --help=commit
87        lock: see $ dwpage.php --help=lock
88
89    OPTIONS
90        -h, --help=<action>: get help
91            e.g. $ ./dwpage.php -hcommit
92            e.g. $ ./dwpage.php --help=commit
93";
94        break;
95    }
96}
97
98#------------------------------------------------------------------------------
99function getUser() {
100    $user = getenv('USER');
101    if (empty ($user)) {
102        $user = getenv('USERNAME');
103    } else {
104        return $user;
105    }
106    if (empty ($user)) {
107        $user = 'admin';
108    }
109    return $user;
110}
111
112#------------------------------------------------------------------------------
113function getSuppliedArgument($OPTS, $short, $long) {
114    $arg = $OPTS->get($short);
115    if ( is_null($arg) ) {
116        $arg = $OPTS->get($long);
117    }
118    return $arg;
119}
120
121#------------------------------------------------------------------------------
122function obtainLock($WIKI_ID) {
123
124    global $USERNAME;
125
126    if ( !file_exists(wikiFN($WIKI_ID)) ) {
127        fwrite( STDERR, "$WIKI_ID does not yet exist\n");
128    }
129
130    $_SERVER['REMOTE_USER'] = $USERNAME;
131    if ( checklock($WIKI_ID) ) {
132        fwrite( STDERR, "Page $WIKI_ID is already locked by another user\n");
133        exit(1);
134    }
135
136    lock($WIKI_ID);
137
138    $_SERVER['REMOTE_USER'] = '_'.$USERNAME.'_';
139
140    if ( checklock($WIKI_ID) != $USERNAME ) {
141
142        fwrite( STDERR, "Unable to obtain lock for $WIKI_ID\n" );
143        exit(1);
144
145    }
146}
147
148#------------------------------------------------------------------------------
149function clearLock($WIKI_ID) {
150
151    global $USERNAME ;
152
153    if ( !file_exists(wikiFN($WIKI_ID)) ) {
154        fwrite( STDERR, "$WIKI_ID does not yet exist\n");
155    }
156
157    $_SERVER['REMOTE_USER'] = $USERNAME;
158    if ( checklock($WIKI_ID) ) {
159        fwrite( STDERR, "Page $WIKI_ID is locked by another user\n");
160        exit(1);
161    }
162
163    unlock($WIKI_ID);
164
165    if ( file_exists(wikiLockFN($WIKI_ID)) ) {
166        fwrite( STDERR, "Unable to clear lock for $WIKI_ID\n" );
167        exit(1);
168    }
169
170}
171
172#------------------------------------------------------------------------------
173function deleteLock($WIKI_ID) {
174
175    $wikiLockFN = wikiLockFN($WIKI_ID);
176
177    if ( file_exists($wikiLockFN) ) {
178        if ( !unlink($wikiLockFN) ) {
179            fwrite( STDERR, "Unable to delete $wikiLockFN\n" );
180            exit(1);
181        }
182    }
183
184}
185
186#------------------------------------------------------------------------------
187$USERNAME = getUser();
188$CWD = getcwd();
189$SYSTEM_ID = '127.0.0.1';
190
191#------------------------------------------------------------------------------
192$OPTS = Doku_Cli_Opts::getOptions(
193    __FILE__,
194    'h::fm:u:s:t',
195    array(
196        'help==',
197        'user=',
198        'system=',
199        'trivial',
200        )
201);
202
203if ( $OPTS->isError() ) {
204    print $OPTS->getMessage()."\n";
205    exit(1);
206}
207
208if ( $OPTS->has('h') or $OPTS->has('help') or !$OPTS->hasArgs() ) {
209    usage(getSuppliedArgument($OPTS,'h','help'));
210    exit(0);
211}
212
213if ( $OPTS->has('u') or $OPTS->has('user') ) {
214    $USERNAME = getSuppliedArgument($OPTS,'u','user');
215}
216
217if ( $OPTS->has('s') or $OPTS->has('system') ) {
218    $SYSTEM_ID = getSuppliedArgument($OPTS,'s','system');
219}
220
221#------------------------------------------------------------------------------
222switch ( $OPTS->arg(0) ) {
223
224    #----------------------------------------------------------------------
225    case 'checkout':
226
227        $WIKI_ID = $OPTS->arg(1);
228
229        if ( !$WIKI_ID ) {
230            fwrite( STDERR, "Wiki page ID required\n");
231            exit(1);
232        }
233
234        $WIKI_FN = wikiFN($WIKI_ID);
235
236        if ( !file_exists($WIKI_FN) ) {
237            fwrite( STDERR, "$WIKI_ID does not yet exist\n");
238            exit(1);
239        }
240
241        $TARGET_FN = $OPTS->arg(2);
242
243        if ( empty($TARGET_FN) ) {
244            $TARGET_FN = getcwd().'/'.basename($WIKI_FN);
245        }
246
247        if ( !file_exists(dirname($TARGET_FN)) ) {
248            fwrite( STDERR, "Directory ".dirname($TARGET_FN)." does not exist\n");
249            exit(1);
250        }
251
252        if ( stristr( realpath(dirname($TARGET_FN)), realpath($conf['datadir']) ) !== false ) {
253            fwrite( STDERR, "Attempt to check out file into data directory - not allowed\n");
254            exit(1);
255        }
256
257        if ( $OPTS->has('f') ) {
258            deleteLock($WIKI_ID);
259        }
260
261        obtainLock($WIKI_ID);
262
263        # Need to lock the file first?
264        if ( !copy($WIKI_FN, $TARGET_FN) ) {
265            fwrite( STDERR, "Unable to copy $WIKI_FN to $TARGET_FN\n");
266            clearLock($WIKI_ID);
267            exit(1);
268        }
269
270        print "$WIKI_ID > $TARGET_FN\n";
271        exit(0);
272
273    break;
274
275    #----------------------------------------------------------------------
276    case 'commit':
277
278        $TARGET_FN = $OPTS->arg(1);
279
280        if ( !$TARGET_FN ) {
281            fwrite( STDERR, "Target filename required\n");
282            exit(1);
283        }
284
285        if ( !file_exists($TARGET_FN) ) {
286            fwrite( STDERR, "$TARGET_FN does not exist\n");
287            exit(1);
288        }
289
290        if ( !is_readable($TARGET_FN) ) {
291            fwrite( STDERR, "Cannot read from $TARGET_FN\n");
292            exit(1);
293        }
294
295        $WIKI_ID = $OPTS->arg(2);
296
297        if ( !$WIKI_ID ) {
298            fwrite( STDERR, "Wiki page ID required\n");
299            exit(1);
300        }
301
302        if ( !$OPTS->has('m') ) {
303            fwrite( STDERR, "Summary message required\n");
304            exit(1);
305        }
306
307        if ( $OPTS->has('f') ) {
308            deleteLock($WIKI_ID);
309        }
310
311        $_SERVER['REMOTE_USER'] = $USERNAME;
312        if ( checklock($WIKI_ID) ) {
313            fwrite( STDERR, "$WIKI_ID is locked by another user\n");
314            exit(1);
315        }
316
317        obtainLock($WIKI_ID);
318
319        saveWikiText($WIKI_ID, file_get_contents($TARGET_FN), $OPTS->get('m'), $OPTS->has('t'));
320
321        clearLock($WIKI_ID);
322
323        exit(0);
324
325    break;
326
327    #----------------------------------------------------------------------
328    case 'lock':
329
330        $WIKI_ID = $OPTS->arg(1);
331
332        if ( !$WIKI_ID ) {
333            fwrite( STDERR, "Wiki page ID required\n");
334            exit(1);
335        }
336
337        if ( $OPTS->has('f') ) {
338            deleteLock($WIKI_ID);
339        }
340
341        obtainLock($WIKI_ID);
342
343        print "Locked : $WIKI_ID\n";
344        exit(0);
345
346    break;
347
348    #----------------------------------------------------------------------
349    case 'unlock':
350
351        $WIKI_ID = $OPTS->arg(1);
352
353        if ( !$WIKI_ID ) {
354            fwrite( STDERR, "Wiki page ID required\n");
355            exit(1);
356        }
357
358        if ( $OPTS->has('f') ) {
359            deleteLock($WIKI_ID);
360        } else {
361            clearLock($WIKI_ID);
362        }
363
364        print "Unlocked : $WIKI_ID\n";
365        exit(0);
366
367    break;
368
369    #----------------------------------------------------------------------
370    default:
371
372        fwrite( STDERR, "Invalid action ".$OPTS->arg(0)."\n" );
373        exit(1);
374
375    break;
376
377}
378
379