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