4 use splitbrain\phpcli\CLI
;
5 use splitbrain\phpcli\Options
;
7 if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__
) . '/../') . '/');
8 define('NOSESSION', 1);
9 require_once(DOKU_INC
. 'inc/init.php');
12 * Checkout and commit pages from the command line while maintaining the history
14 class PageCLI
extends CLI
{
16 protected $force = false;
17 protected $username = '';
20 * Register options and arguments on the given $options object
22 * @param Options $options
25 protected function setup(Options
$options) {
27 $options->registerOption(
29 'force obtaining a lock for the page (generally bad idea)',
32 $options->registerOption(
34 'work as this user. defaults to current CLI user',
39 'Utility to help command line Dokuwiki page editing, allow ' .
40 'pages to be checked out for editing then committed after changes'
43 /* checkout command */
44 $options->registerCommand(
46 'Checks out a file from the repository, using the wiki id and obtaining ' .
47 'a lock for the page. ' . "\n" .
48 'If a working_file is specified, this is where the page is copied to. ' .
49 'Otherwise defaults to the same as the wiki page in the current ' .
52 $options->registerArgument(
54 'The wiki page to checkout',
58 $options->registerArgument(
60 'How to name the local checkout',
66 $options->registerCommand(
68 'Checks in the working_file into the repository using the specified ' .
69 'wiki id, archiving the previous version.'
71 $options->registerArgument(
73 'The local file to commit',
77 $options->registerArgument(
79 'The wiki page to create or update',
83 $options->registerOption(
85 'Summary describing the change (required)',
90 $options->registerOption(
99 $options->registerCommand(
101 'Obtains or updates a lock for a wiki page'
103 $options->registerArgument(
105 'The wiki page to lock',
111 $options->registerCommand(
113 'Removes a lock for a wiki page.'
115 $options->registerArgument(
117 'The wiki page to unlock',
126 * Arguments and options have been parsed when this is run
128 * @param Options $options
131 protected function main(Options
$options) {
132 $this->force
= $options->getOpt('force', false);
133 $this->username
= $options->getOpt('user', $this->getUser());
135 $command = $options->getCmd();
136 $args = $options->getArgs();
139 $wiki_id = array_shift($args);
140 $localfile = array_shift($args);
141 $this->commandCheckout($wiki_id, $localfile);
144 $localfile = array_shift($args);
145 $wiki_id = array_shift($args);
146 $this->commandCommit(
149 $options->getOpt('message', ''),
150 $options->getOpt('trivial', false)
154 $wiki_id = array_shift($args);
155 $this->obtainLock($wiki_id);
156 $this->success("$wiki_id locked");
159 $wiki_id = array_shift($args);
160 $this->clearLock($wiki_id);
161 $this->success("$wiki_id unlocked");
164 echo $options->help();
171 * @param string $wiki_id
172 * @param string $localfile
174 protected function commandCheckout($wiki_id, $localfile) {
177 $wiki_id = cleanID($wiki_id);
178 $wiki_fn = wikiFN($wiki_id);
180 if(!file_exists($wiki_fn)) {
181 $this->fatal("$wiki_id does not yet exist");
184 if(empty($localfile)) {
185 $localfile = getcwd() . '/' . \dokuwiki\Utf8\PhpString
::basename($wiki_fn);
188 if(!file_exists(dirname($localfile))) {
189 $this->fatal("Directory " . dirname($localfile) . " does not exist");
192 if(stristr(realpath(dirname($localfile)), realpath($conf['datadir'])) !== false) {
193 $this->fatal("Attempt to check out file into data directory - not allowed");
196 $this->obtainLock($wiki_id);
198 if(!copy($wiki_fn, $localfile)) {
199 $this->clearLock($wiki_id);
200 $this->fatal("Unable to copy $wiki_fn to $localfile");
203 $this->success("$wiki_id > $localfile");
207 * Save a file as a new page revision
209 * @param string $localfile
210 * @param string $wiki_id
211 * @param string $message
214 protected function commandCommit($localfile, $wiki_id, $message, $minor) {
215 $wiki_id = cleanID($wiki_id);
216 $message = trim($message);
218 if(!file_exists($localfile)) {
219 $this->fatal("$localfile does not exist");
222 if(!is_readable($localfile)) {
223 $this->fatal("Cannot read from $localfile");
227 $this->fatal("Summary message required");
230 $this->obtainLock($wiki_id);
232 saveWikiText($wiki_id, file_get_contents($localfile), $message, $minor);
234 $this->clearLock($wiki_id);
236 $this->success("$localfile > $wiki_id");
240 * Lock the given page or exit
242 * @param string $wiki_id
244 protected function obtainLock($wiki_id) {
245 if($this->force
) $this->deleteLock($wiki_id);
247 $_SERVER['REMOTE_USER'] = $this->username
;
249 if(checklock($wiki_id)) {
250 $this->error("Page $wiki_id is already locked by another user");
256 if(checklock($wiki_id)) {
257 $this->error("Unable to obtain lock for $wiki_id ");
258 var_dump(checklock($wiki_id));
264 * Clear the lock on the given page
266 * @param string $wiki_id
268 protected function clearLock($wiki_id) {
269 if($this->force
) $this->deleteLock($wiki_id);
271 $_SERVER['REMOTE_USER'] = $this->username
;
272 if(checklock($wiki_id)) {
273 $this->error("Page $wiki_id is locked by another user");
279 if(file_exists(wikiLockFN($wiki_id))) {
280 $this->error("Unable to clear lock for $wiki_id");
286 * Forcefully remove a lock on the page given
288 * @param string $wiki_id
290 protected function deleteLock($wiki_id) {
291 $wikiLockFN = wikiLockFN($wiki_id);
293 if(file_exists($wikiLockFN)) {
294 if(!unlink($wikiLockFN)) {
295 $this->error("Unable to delete $wikiLockFN");
302 * Get the current user's username from the environment
306 protected function getUser() {
307 $user = getenv('USER');
309 $user = getenv('USERNAME');
321 $cli = new PageCLI();