Release preparation
[dokuwiki.git] / bin / dwpage.php
blob1c1a1c10ee6f38cb5e41e75e51a31829600c97ec
1 #!/usr/bin/php
2 <?php
3 if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
4 define('NOSESSION', 1);
5 require_once(DOKU_INC.'inc/init.php');
7 /**
8 * Checkout and commit pages from the command line while maintaining the history
9 */
10 class PageCLI extends DokuCLI {
12 protected $force = false;
13 protected $username = '';
15 /**
16 * Register options and arguments on the given $options object
18 * @param DokuCLI_Options $options
19 * @return void
21 protected function setup(DokuCLI_Options $options) {
22 /* global */
23 $options->registerOption(
24 'force',
25 'force obtaining a lock for the page (generally bad idea)',
26 'f'
28 $options->registerOption(
29 'user',
30 'work as this user. defaults to current CLI user',
31 'u',
32 'username'
34 $options->setHelp(
35 'Utility to help command line Dokuwiki page editing, allow '.
36 'pages to be checked out for editing then committed after changes'
39 /* checkout command */
40 $options->registerCommand(
41 'checkout',
42 'Checks out a file from the repository, using the wiki id and obtaining '.
43 'a lock for the page. '."\n".
44 'If a working_file is specified, this is where the page is copied to. '.
45 'Otherwise defaults to the same as the wiki page in the current '.
46 'working directory.'
48 $options->registerArgument(
49 'wikipage',
50 'The wiki page to checkout',
51 true,
52 'checkout'
54 $options->registerArgument(
55 'workingfile',
56 'How to name the local checkout',
57 false,
58 'checkout'
61 /* commit command */
62 $options->registerCommand(
63 'commit',
64 'Checks in the working_file into the repository using the specified '.
65 'wiki id, archiving the previous version.'
67 $options->registerArgument(
68 'workingfile',
69 'The local file to commit',
70 true,
71 'commit'
73 $options->registerArgument(
74 'wikipage',
75 'The wiki page to create or update',
76 true,
77 'commit'
79 $options->registerOption(
80 'message',
81 'Summary describing the change (required)',
82 'm',
83 'summary',
84 'commit'
86 $options->registerOption(
87 'trivial',
88 'minor change',
89 't',
90 false,
91 'commit'
94 /* lock command */
95 $options->registerCommand(
96 'lock',
97 'Obtains or updates a lock for a wiki page'
99 $options->registerArgument(
100 'wikipage',
101 'The wiki page to lock',
102 true,
103 'lock'
106 /* unlock command */
107 $options->registerCommand(
108 'unlock',
109 'Removes a lock for a wiki page.'
111 $options->registerArgument(
112 'wikipage',
113 'The wiki page to unlock',
114 true,
115 'unlock'
120 * Your main program
122 * Arguments and options have been parsed when this is run
124 * @param DokuCLI_Options $options
125 * @return void
127 protected function main(DokuCLI_Options $options) {
128 $this->force = $options->getOpt('force', false);
129 $this->username = $options->getOpt('user', $this->getUser());
131 $command = $options->getCmd();
132 switch($command) {
133 case 'checkout':
134 $wiki_id = array_shift($options->args);
135 $localfile = array_shift($options->args);
136 $this->commandCheckout($wiki_id, $localfile);
137 break;
138 case 'commit':
139 $localfile = array_shift($options->args);
140 $wiki_id = array_shift($options->args);
141 $this->commandCommit(
142 $localfile,
143 $wiki_id,
144 $options->getOpt('message', ''),
145 $options->getOpt('trivial', false)
147 break;
148 case 'lock':
149 $wiki_id = array_shift($options->args);
150 $this->obtainLock($wiki_id);
151 $this->success("$wiki_id locked");
152 break;
153 case 'unlock':
154 $wiki_id = array_shift($options->args);
155 $this->clearLock($wiki_id);
156 $this->success("$wiki_id unlocked");
157 break;
158 default:
159 echo $options->help();
164 * Check out a file
166 * @param string $wiki_id
167 * @param string $localfile
169 protected function commandCheckout($wiki_id, $localfile) {
170 global $conf;
172 $wiki_id = cleanID($wiki_id);
173 $wiki_fn = wikiFN($wiki_id);
175 if(!file_exists($wiki_fn)) {
176 $this->fatal("$wiki_id does not yet exist");
179 if(empty($localfile)) {
180 $localfile = getcwd().'/'.utf8_basename($wiki_fn);
183 if(!file_exists(dirname($localfile))) {
184 $this->fatal("Directory ".dirname($localfile)." does not exist");
187 if(stristr(realpath(dirname($localfile)), realpath($conf['datadir'])) !== false) {
188 $this->fatal("Attempt to check out file into data directory - not allowed");
191 $this->obtainLock($wiki_id);
193 if(!copy($wiki_fn, $localfile)) {
194 $this->clearLock($wiki_id);
195 $this->fatal("Unable to copy $wiki_fn to $localfile");
198 $this->success("$wiki_id > $localfile");
202 * Save a file as a new page revision
204 * @param string $localfile
205 * @param string $wiki_id
206 * @param string $message
207 * @param bool $minor
209 protected function commandCommit($localfile, $wiki_id, $message, $minor) {
210 $wiki_id = cleanID($wiki_id);
211 $message = trim($message);
213 if(!file_exists($localfile)) {
214 $this->fatal("$localfile does not exist");
217 if(!is_readable($localfile)) {
218 $this->fatal("Cannot read from $localfile");
221 if(!$message) {
222 $this->fatal("Summary message required");
225 $this->obtainLock($wiki_id);
227 saveWikiText($wiki_id, file_get_contents($localfile), $message, $minor);
229 $this->clearLock($wiki_id);
231 $this->success("$localfile > $wiki_id");
235 * Lock the given page or exit
237 * @param string $wiki_id
239 protected function obtainLock($wiki_id) {
240 if($this->force) $this->deleteLock($wiki_id);
242 $_SERVER['REMOTE_USER'] = $this->username;
244 if(checklock($wiki_id)) {
245 $this->error("Page $wiki_id is already locked by another user");
246 exit(1);
249 lock($wiki_id);
251 if(checklock($wiki_id)) {
252 $this->error("Unable to obtain lock for $wiki_id ");
253 var_dump(checklock($wiki_id));
254 exit(1);
259 * Clear the lock on the given page
261 * @param string $wiki_id
263 protected function clearLock($wiki_id) {
264 if($this->force) $this->deleteLock($wiki_id);
266 $_SERVER['REMOTE_USER'] = $this->username;
267 if(checklock($wiki_id)) {
268 $this->error("Page $wiki_id is locked by another user");
269 exit(1);
272 unlock($wiki_id);
274 if(file_exists(wikiLockFN($wiki_id))) {
275 $this->error("Unable to clear lock for $wiki_id");
276 exit(1);
281 * Forcefully remove a lock on the page given
283 * @param string $wiki_id
285 protected function deleteLock($wiki_id) {
286 $wikiLockFN = wikiLockFN($wiki_id);
288 if(file_exists($wikiLockFN)) {
289 if(!unlink($wikiLockFN)) {
290 $this->error("Unable to delete $wikiLockFN");
291 exit(1);
297 * Get the current user's username from the environment
299 * @return string
301 protected function getUser() {
302 $user = getenv('USER');
303 if(empty ($user)) {
304 $user = getenv('USERNAME');
305 } else {
306 return $user;
308 if(empty ($user)) {
309 $user = 'admin';
311 return $user;
316 // Main
317 $cli = new PageCLI();
318 $cli->run();