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