<?php if (!defined('PmWiki')) exit();

/*  === MovePage ===
 *  Copyright 2009 Eemeli Aro <eemeli@gmail.com>
 *
 *  Move and copy wiki pages
 *
 *  Developed and tested using PmWiki 2.2.x/2.3.x
 *
 *  To use, add the following to a configuration file:

  if (($action=='copy') || ($action=='move') || ($action=='rename')) 
    include_once("$FarmD/cookbook/movepage.php");

 *  For more information, please see the online documentation at
 *    http://www.pmwiki.org/wiki/Cookbook/MovePage
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  Script maintained by Petko Yotov www.pmwiki.org/petko
 */

$RecipeInfo['MovePage']['Version'] = '20240428';

SDVA($HandleActions, array( 
  'copy' => 'HandleMovePage', 
  'move' => 'HandleMovePage', 
  'rename' => 'HandleMovePage'
));
SDVA($HandleAuth, array(
  'copy' => 'edit', 
  'move' => 'edit', 
  'rename' => 'edit'
));
SDVA($ActionTitleFmt, array( 
  'copy' => '| $[Copy/move]', 
  'move' => '| $[Copy/move]', 
  'rename' => '| $[Copy/move]'
));

function MovePage($pagename, &$tgtname, &$page, $auth) {
  global $action, $FmtPV, $ChangeSummary, $Now, $MovePageFmt, $Charset, 
  $EnableMovePageUploads;
  
  if(! pmtoken(1)) return XL('Token invalid or missing');

  if ($Charset != 'UTF-8' && preg_match('/[\\x80-\\xbf]/', $tgtname)) $tgtname = utf8_decode($tgtname);
  $tgtname = MakePageName($pagename, $tgtname);
  if (empty($tgtname))
    return 'invalid target';
  $FmtPV['$MoveTargetName'] = "'$tgtname'";
  if (PageExists($tgtname))
    return "target page ($tgtname) exists";

  $tgt = RetrieveAuthPage($tgtname, $auth, FALSE);
  if (!$tgt)
    return "cannot read target location ($tgtname); insufficient authority?";

  $new = $page;
  $new['csum'] = $ChangeSummary = FmtPageName($MovePageFmt["$action-csum"], $pagename);
  if ($ChangeSummary) $new["csum:$Now"] = $ChangeSummary;
  if (!UpdatePage($tgtname, $page, $new))
    return "error writing page ($tgtname)";

  if ($action == 'move') {
    $new = $page;
    $new['text'] = FmtPageName($MovePageFmt['old-text'], $pagename);
    $new['csum'] = $ChangeSummary = FmtPageName($MovePageFmt['old-csum'], $pagename);
    if ($ChangeSummary) $new["csum:$Now"] = $ChangeSummary;
    if (!UpdatePage($pagename, $page, $new))
      return "target ($tgtname) written ok, error writing to source page ($pagename)";
  } else if ($action == 'rename') {
    global $WikiDir, $LastModFile;
    $page = RetrieveAuthPage($pagename, $auth, false, READPAGE_CURRENT);
    if (!$page) 
      return "?cannot delete $pagename";
    $WikiDir->delete($pagename);
  }

  return false;
}

function HandleMovePage($pagename, $auth='edit') {
  global
    $PageStartFmt, $PageEndFmt, $ActionTitleFmt, $action, $FmtPV,
    $Now, $ChangeSummary, $MessagesFmt, $MovePageFmt, 
    $UploadFileFmt, $EnableMovePageUploads, $Now, $HTMLStylesFmt;
  if (isset($_REQUEST['cancel'])) Redirect($pagename);
  Lock(2);
  if (!PageExists($pagename)) Abort("MovePage: source page ($pagename) doesn't exist");
  $page = RetrieveAuthPage($pagename, $auth, TRUE);
  if (!$page) Abort("MovePage: cannot read source ($pagename)");
  
  $EnableMovePageUploads = 0;
  $uploadpagedir = FmtPageName($UploadFileFmt, $pagename);
  if(preg_match('!\\$(Full)?Name!', $UploadFileFmt)) {
    if(is_dir($uploadpagedir)) 
      $EnableMovePageUploads = 1;
  }
  
  SDVA($HTMLStylesFmt, array('checked-label-bold' => '
    #wikimove input:checked + label { font-weight: bold; }
  '));
    
  SDVA($MovePageFmt, array(
    'copy-csum' => 'Page copied to {$MoveTargetName} from {$FullName}',
    'move-csum' => 'Page moved to {$MoveTargetName} from {$FullName}',
    'rename-csum' => 'Page renamed to {$MoveTargetName} from {$FullName}',
    'old-csum' => 'Page moved to {$MoveTargetName}',
    'old-text' => '(:redirect {$MoveTargetName}:)(:Summary:$[Redirects to] {$MoveTargetName}:)',
    'form' => array(
      "<div id='wikimove'>",
      "markup:!! %block wikiaction% $[Copy/move/rename] [[{\$FullName}]] $[to:]
(:messages:)
(:input form method=post action={\$PageUrl} :)
(:input default request=1:)(:input default to $pagename:)
(:input hidden n $pagename:)(:input pmtoken:)
'''$[New page name]:'''\\\\
(:input text to placeholder=\"$[New page name]\":)

(:input radio action copy \"$[Copy]: $[Make a copy of the page with a new name, without modifying the original]\":)\\\\
(:input radio action move \"$[Move]: $[Move the page to the new name, leaving a redirect to the new page at the old name]\":)\\\\
(:input radio action rename \"$[Rename]: $[Move the page to the new name, leaving nothing at the old name]\":)

(:if enabled EnableMovePageUploads:)
(:input checkbox includeuploads 1 \"$[Also include the upload directory] '$uploadpagedir'\":)

(:ifend:)
(:if enabled EnablePostAuthorRequired:)
'''$[Author]:'''\\\\
(:input e_author:)

(:ifend:)
(:input submit go \"$[Go]\":) (:input submit cancel \"$[Cancel]\":) 
(:input end:)
",
      "</div>" ),
    'print' => array( &$PageStartFmt, &$MovePageFmt['form'], &$PageEndFmt )
    ));
  $to = @$_GET['to'] ? stripmagic(preg_replace('![<>${}\'"\\\\]+!', '', $_GET['to'])) : $pagename;
  $FmtPV['$MoveTargetName'] = "'$to'";

  if (empty($_POST['to'])) {
    Lock(0);
    PrintFmt($pagename, $MovePageFmt['print']);
    return;
  }
  $tgtname = $_POST['to']; // &$tgtname edited by ref in MovePage()
  $error = MovePage($pagename, $tgtname, $page, $auth);
  Lock(0);
  if ($error) {
    $MessagesFmt[] = "<div class='wikimessage'>MovePage: $error</div>";
    PrintFmt($pagename, $MovePageFmt['print']);
  } else {
    if($EnableMovePageUploads && @$_POST['includeuploads']) {
      $uploadnewdir = FmtPageName($UploadFileFmt, $tgtname);
      if(file_exists($uploadnewdir)) {
        rename($uploadnewdir, "$uploadnewdir,$Now");
      }      
      if($action == 'rename' || $action == 'move') {
        mkdirp(dirname($uploadnewdir));
        rename($uploadpagedir, $uploadnewdir);
      }
      else {
        mp_copy_recursive($uploadpagedir, $uploadnewdir);
      }
    }
    Redirect($tgtname);
  }
}

function mp_copy_recursive($old, $new) {
  mkdirp($new);
  $dirp = @opendir($old);
  if(!$dirp) return false;
  while (($file=readdir($dirp)) !== false) {
    if ($file=='.'|| $file=='..') continue;
    $oldpath = "$old/$file";
    $newpath = "$new/$file";
    if(is_dir($oldpath)) mp_copy_recursive($oldpath, $newpath);
    else @copy($oldpath, $newpath);
  }
  closedir($dirp);
}