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

/*	=== MoveCopyDelGroup ===
 * 
 * implemented by Harco Kuppens
 *
 * Move/copy/delete wiki groups
 *
 *   MoveCopyDelGroup provides a simple form and simple actions to copy, move, or delete an entire pmwiki group. 
 *   Copy duplicates the group, Move renames the group and Delete deletes the entire group.
 * 
 *   Assumes uploads are grouped per pmwiki group into one directory.
 *
 *   To use, add the following to a configuration file:
 *
 * 		if (($action=='groupcopy') || ($action=='groupmove') || ($action=='groupdelete')) include_once("$FarmD/cookbook/movecopydelgroup.php");
 *
 *	Based on ideas and code from : MovePage, src: http://www.pmwiki.org/wiki/Cookbook/MovePage
 
 *  Copyright (c) 2023, Harco Kuppens        
 *
 *	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.
 *         
 *          	
 */

$RecipeInfo['HandleMoveCopyDelGroup']['Version'] = '2023-04-19';

SDVA($HandleActions, array('groupcopy' => 'HandleMoveCopyDelGroup', 'groupmove' => 'HandleMoveCopyDelGroup', 'groupdelete' => 'HandleMoveCopyDelGroup'));
SDVA($HandleAuth, array('groupcopy' => 'admin', 'groupmove' => 'admin', 'groupdelete' => 'admin'));

SDVA($ActionTitleFmt, array('groupcopy' => '| $[GroupCopy]', 'groupmove' => '| $[GroupMove]', 'groupdelete' => '| $[GroupDelete]'));


function HandleMoveCopyDelGroup($pagename, $auth='admin') {
	global
		$PageStartFmt, $PageEndFmt, $ActionTitleFmt, $action, $FmtPV,
		$Now, $ChangeSummary, $MessagesFmt, $MovePageFmt;
	if (isset($_REQUEST['cancel'])) Redirect($pagename);
	Lock(2);
	if (!PageExists($pagename)) Abort("$action: source page ($pagename) doesn't exist");
	$page = RetrieveAuthPage($pagename, $auth, TRUE);
	if (!$page) Abort("$action: cannot read source ($pagename)");

    // page name and group
    $name = PageVar($pagename, '$Name');
    $group = PageVar($pagename, '$Group');
    $FmtPV['$MoveTargetName'] = "'$group'";

    $extra_msg=" $group to:";
    if ($action=="groupdelete")  {
        $extra_msg=":";
        $submit_buttons="
                <input type='hidden' name='to' size='60' value='\$MoveTargetName' />
                <input type='text' name='to' size='60' value='\$MoveTargetName' />
                <input type='submit' name='groupdelete' value='$[GroupDelete]' />
        ";        
        $operation="$[GroupDelete]";
    } else if ($action=="groupmove")  {
        $submit_buttons="
                <input type='text' name='to' size='60' value='\$MoveTargetName' />
                <input type='submit' name='groupmove' value='$[GroupMove]' />
        ";        
        $operation="$[GroupMove]";
    } else {
        $submit_buttons="
                <input type='text' name='to' size='60' value='\$MoveTargetName' />
                <input type='submit' name='groupcopy' value='$[GroupCopy]' />
        ";        
        $operation="$[GroupCopy]";
    }    


    $form=array("<div id='wikimove'>
			<h2 class='wikiaction'>$operation$extra_msg</h2>
			<form method='post' rel='nofollow' action='\$PageUrl?action=$action'>
			<input type='hidden' name='n' value='\$FullName' />		
            $submit_buttons
            <input type='submit' name='cancel' value='$[Cancel]' />",
			'markup:(:messages:)',
			"\n</form></div>");

	if (empty($_POST['to'])) {
		Lock(0);
		PrintFmt($pagename, array(&$PageStartFmt, &$form, &$PageEndFmt));
		return;
	}
    $targetGroup = $_POST['to'];
    if (!empty($_REQUEST['copy'])) {
        $mp_action = 'copy';
    } else if (!empty($_REQUEST['delete'])) {
        $mp_action = 'delete';
    } else if (!empty($_REQUEST['move'])) {
        $mp_action = 'move';
    } else $mp_action = $action;
	$errormsg = MoveCopyDelGroup($group,$targetGroup,$mp_action, $operation);
	Lock(0);
	if ($errormsg) {
        // error 
		$MessagesFmt[] = "<div class='wikimessage'>$action: $errormsg</div>";
		PrintFmt($pagename, array(&$PageStartFmt, &$form, &$PageEndFmt));
	} else {
        // successfull move,copy or deleted group
		Redirect("{$targetGroup}.{$name}");
    }    
}
// copies files and non-empty directories
function rcopy($src, $dst) {
    global $errorMsg;
    if (is_dir($src)) {
      if (!mkdir($dst)) {
        $errorMsg="cannot create directory $dst";
        return false;
      }
      $files = scandir($src);
      foreach ($files as $file) {
         if ($file != "." && $file != "..") {
            if( ! rcopy("$src/$file", "$dst/$file") ) return false; 
         }   
      }
    } else {
        if (file_exists($src)) {
           if (!copy($src, $dst)) {
            $errorMsg="cannot copy file $src to $dst";
            return false;          
           }
        }    
    }    
    return true;
  }

function delTree($dir) {
    global $errorMsg;
    $files = array_diff(scandir($dir), array('.','..'));
    foreach ($files as $file) {
       if (is_dir("$dir/$file")) {
            if (!delTree("$dir/$file")) return false;
       } else {   
            if (! unlink("$dir/$file")) {
                $errorMsg="cannot delete file $dir/$file";
                return false;
            }   
       }    
    }
    if (! rmdir($dir)) {
        $errorMsg="cannot delete directory $dir";
        return false;
    }   
    return true;
}

function MoveCopyDelGroup($sourceGroup, $targetGroup,$action,$operation) {
	global  $errorMsg,$FarmD;
    $pagesDir="$FarmD/wiki.d";
    $uploadDir="$FarmD/uploads";
    $source_uploadsdir="$uploadDir/$sourceGroup";
    $target_uploadsdir="$uploadDir/$targetGroup";

    
    if ($action=='groupmove' || $action=='groupcopy') {
        // check source group (sourceGroup) exist
        $foundsource=false;
        foreach (glob("$pagesDir/{$sourceGroup}.*") as $filename) {
            $foundsource=true;
            break;
        }   
        if (is_dir($source_uploadsdir)) {
            $foundsource=true;
        }    
        if ( $foundsource == false ) return "Cannot do $operation because group $sourceGroup does not exist!";

        // check target group (targetGroup) does not already exist
        if (is_dir($target_uploadsdir)) {  
            return "cannot do $operation from '$sourceGroup' to '$targetGroup' because latter already exist";
        }    
        foreach (glob("$pagesDir/{$targetGroup}.*") as $filename) {
            return "cannot do $operation from '$sourceGroup' to '$targetGroup' because latter already exist";
        }   
    } elseif ($action=='groupdelete'  ) {
        // check group you want to delete really exist
        $found=false;
        foreach (glob("$pagesDir/{$targetGroup}.*") as $filename) {
            $found=true;
            break;
        }   
        if (is_dir($target_uploadsdir)) {
            $found=true;
        }    
        if ( $found == false ) return "Cannot do $operation because group $targetGroup does not exist!";
    } else {
        return "unknown action '$action'";
    }

    if ($action=='groupmove' ) {
        // do move
        foreach (glob("$pagesDir/{$sourceGroup}.*") as $filename) {
            // substr_replace() replaces a copy of string delimited by the offset and (optionally) length parameters with the string given in replace
            $newfilename=substr_replace($filename,"$pagesDir/{$targetGroup}",0,strlen("$pagesDir/{$sourceGroup}"));
            if (!rename("$filename","$newfilename")){
                return "ERROR: cannot move page $filename to $newfilename" ;
            }
        }
        if (is_dir($source_uploadsdir)) {
            if (!rename("$source_uploadsdir","$target_uploadsdir")){
                return "ERROR: cannot move directory $source_uploadsdir to $target_uploadsdir" ;
            }
        } 
    } elseif ($action=='groupcopy' ) {
        // do copy
        foreach (glob("$pagesDir/{$sourceGroup}.*") as $filename) {
            // substr_replace() replaces a copy of string delimited by the offset and (optionally) length parameters with the string given in replace
            $newfilename=substr_replace($filename,"$pagesDir/{$targetGroup}",0,strlen("$pagesDir/{$sourceGroup}"));
            if (!copy("$filename","$newfilename")) {
                return "ERROR: cannot copy page $filename to $newfilename" ;
            }
        }
 
        if (is_dir($source_uploadsdir)) {   
            if (!rcopy("$source_uploadsdir","$target_uploadsdir")){
                return "ERROR: cannot copy directory $source_uploadsdir to $target_uploadsdir because: $errorMsg"; 
            }
        } 
    } elseif ($action=='groupdelete'  ) {
        // do delete
        foreach (glob("$pagesDir/{$targetGroup}.*") as $filename) {
            if (! unlink("$filename") ) {
                return "ERROR: cannot delete page $filename";
            }
        }
        if (is_dir($target_uploadsdir)) {
           if (!delTree($target_uploadsdir)){
               return "ERROR: cannot delete directory $target_uploadsdir because: $errorMsg";
           }
        } 
    } else {
        return "unknown action '$action'";
    }
    
    // succesfull operation does not return error
	return FALSE;
}