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