1<?php 2/** 3 * DokuWiki Plugin farmsync (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Michael Große <dokuwiki@cosmocode.de> 7 */ 8 9if (!defined('DOKU_INC')) die(); 10 11use dokuwiki\Form\Form; 12use dokuwiki\plugin\farmsync\meta\FarmSyncUtil; 13 14class action_plugin_farmsync_ajax extends DokuWiki_Action_Plugin { 15 16 /** 17 * Registers a callback function for a given event 18 * 19 * @param Doku_Event_Handler $controller DokuWiki's event controller object 20 * @return void 21 */ 22 public function register(Doku_Event_Handler $controller) { 23 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax'); 24 } 25 26 private $farm_util; 27 28 function __construct() { 29 $this->farm_util = new FarmSyncUtil(); 30 } 31 32 /** 33 * Pass Ajax call to a type 34 * 35 * @param Doku_Event $event event object by reference 36 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 37 * handler was registered] 38 */ 39 public function handle_ajax(Doku_Event $event, $param) { 40 if ($event->data != 'plugin_farmsync') return; 41 $event->preventDefault(); 42 $event->stopPropagation(); 43 44 global $INPUT; 45 46 $sectok = $INPUT->str('sectok'); 47 if (!checkSecurityToken($sectok)) { 48 $this->sendResponse(403, "Security-Token invalid!"); 49 return; 50 } 51 52 53 54 $target = $INPUT->str('farmsync-animal'); 55 $page = $INPUT->str('farmsync-page'); 56 $source = $INPUT->str('farmsync-source'); 57 $action = $INPUT->str('farmsync-action'); 58 59 if ($INPUT->has('farmsync-getstruct')) { 60 $schemas = $this->farm_util->getAllStructSchemasList($source); 61 $form = new Form(); 62 $form->addTagOpen('div')->addClass('structsync'); 63 foreach ($schemas as $schema) { 64 $form->addTagOpen('div')->addClass('lineradio'); 65 $form->addHTML("<label>$schema</label>"); 66 $form->addTagOpen('div')->addClass('container'); 67 $form->addCheckbox("farmsync_struct[schema_$schema]", "Schema"); 68 $form->addCheckbox("farmsync_struct[assign_$schema]", "Replace assignments"); 69 $form->addTagClose('div'); 70 $form->addTagClose('div'); 71 } 72 $form->addTagClose('div'); 73 $this->sendResponse(200, $form->toHTML()); 74 return; 75 } 76 77 if ($action == 'diff') { 78 $targetText = $this->farm_util->readRemotePage($target, $page, false); 79 $sourceText = $this->farm_util->readRemotePage($source, $page, false); 80 $diff = new \Diff(explode("\n", $targetText), explode("\n", $sourceText)); 81 $diffformatter = new \TableDiffFormatter(); 82 $result = '<table class="diff">'; 83 $result .= '<tr>'; 84 $result .= '<th colspan="2">' . $this->getLang('diff:animal') . '</th>'; 85 $result .= '<th colspan="2">' . $this->getLang('diff:source') . '</th>'; 86 $result .= '</tr>'; 87 $result .= $diffformatter->format($diff); 88 $result .= '</table>'; 89 $this->sendResponse(200, $result); 90 return; 91 } 92 93 if ($action == 'overwrite') { 94 $type = $INPUT->str('farmsync-type'); 95 if (!$INPUT->has('farmsync-content')) { 96 if ($type == 'media') { 97 $this->farm_util->saveRemoteMedia($source, $target, $page); 98 } elseif ($type == 'page') { 99 $this->overwriteRemotePage($source, $target, $page); 100 } elseif ($type == 'struct') { 101 $json = $this->farm_util->getAnimalStructSchemasJSON($source, array($page)); 102 $this->farm_util->importAnimalStructSchema($target, $page, $json[$page]); 103 } else { 104 $targetFN = $this->farm_util->getRemoteFilename($target, $page, null, false); 105 $sourceFN = $this->farm_util->getRemoteFilename($source, $page, null, false); 106 107 $this->farm_util->replaceRemoteFile($targetFN, io_readFile($sourceFN), filemtime($sourceFN)); 108 } 109 $this->farm_util->clearAnimalCache($target); 110 $this->sendResponse(200, ""); 111 return; 112 } 113 114 if ($INPUT->has('farmsync-content')) { 115 $content = $INPUT->str('farmsync-content'); 116 $this->writeManualMerge($source, $target, $page, $content); 117 $this->farm_util->clearAnimalCache($target); 118 $this->sendResponse(200, ""); 119 return; 120 } 121 } 122 $this->sendResponse(400, "malformed request"); 123 } 124 125 /** 126 * @param int $code 127 * @param string $msg 128 */ 129 private function sendResponse($code, $msg) { 130 header('Content-Type: application/json'); 131 http_status($code); 132 $json = new JSON; 133 echo $json->encode($msg); 134 } 135 136 public function overwriteRemotePage($source, $target, $page) { 137 $sourceModTime = $this->farm_util->getRemoteFilemtime($source, $page); 138 $this->farm_util->saveRemotePage($target, $page, $this->farm_util->readRemotePage($source, $page), $sourceModTime); 139 } 140 141 public function writeManualMerge($source, $target, $page, $content) { 142 global $INPUT; 143 $sourceModTime = $this->farm_util->getRemoteFilemtime($source, $page); 144 $targetArchiveFileName = $this->farm_util->getRemoteFilename($target, $page, $sourceModTime); 145 $changelogline = join("\t", array($sourceModTime, clientIP(true), DOKU_CHANGE_TYPE_MINOR_EDIT, $page, $INPUT->server->str('REMOTE_USER'), "Revision inserted due to manual merge")); 146 $this->farm_util->addRemotePageChangelogRevision($target, $page, $changelogline, false); 147 $this->farm_util->replaceRemoteFile($targetArchiveFileName, $this->farm_util->readRemotePage($source, $page)); 148 $this->farm_util->saveRemotePage($target, $page, $content); 149 } 150} 151