*/ if(!defined('DOKU_INC')) die(); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'git/lib/Git.php'); require_once(DOKU_INC.'inc/search.php'); require_once(DOKU_INC.'/inc/DifferenceEngine.php'); function git_callback_search_wanted(&$data,$base,$file,$type,$lvl,$opts) { global $conf; if($type == 'd'){ return true; // recurse all directories, but we don't store namespaces } if(!preg_match("/.*\.txt$/", $file)) { // Ignore everything but TXT return true; } // get id of this file $id = pathID($file); $item = &$data["$id"]; if(! isset($item)) { $data["$id"]= array('id' => $id, 'file' => $file); } } class helper_plugin_git extends DokuWiki_Plugin { var $dt = null; var $sqlite = null; function getMethods(){ $result = array(); $result[] = array( 'name' => 'cloneRepo', 'desc' => 'Creates a new clone of a repository', 'params' => array( 'destination' => 'string'), 'return' => array('result' => 'array'), ); // and more supported methods... return $result; } function rebuild_data_plugin_data() { // Load the data plugin only if we need to if(!$this->dt) { $this->dt =& plugin_load('syntax', 'data_entry'); if(!$this->dt) { msg('Error loading the data table class from GIT Helper. Make sure the data plugin is installed.',-1); return; } } global $conf; $result = ''; $data = array(); search($data,$conf['datadir'],'git_callback_search_wanted',array('ns' => $ns)); $output = array(); foreach($data as $entry) { // Get the content of the file $filename = $conf['datadir'].$entry['file']; if (strpos($filename, 'syntax') > 0) continue; // Skip instructional pages $body = @file_get_contents($filename); // Run the regular expression to get the dataentry section $pattern = '/----.*dataentry.*\R----/s'; if (preg_match($pattern, $body, $matches) === false) { continue; } foreach ($matches as $match) { // Re-use the handle method to get the formatted data $cleanedMatch = htmlspecialchars($match); $dummy = ""; $formatted = $this->dt->handle($cleanedMatch, null, null, $dummy); $output['id'.count($output)] = $formatted; // Re-use the save_data method to .... (drum roll) save the data. // Ignore the returned html, just move on to the next file $html = $this->dt->_saveData($formatted, $entry['id'], 'Title'.count($output)); } } msg('Data entry plugin found and refreshed all '.count($output).' entries.'); } /** * Resets a GIT cache by setting the timestamp to ZERO (1st of jan 1970) * * @param string repository name. Either: 'Local' or 'upstream' */ function resetGitStatusCache($repo) { $res = $this->loadSqlite(); if (!$res) { msg('Error loading sqlite'); return; } // Set the time to zero, so the first alert msg will set the correct status $sql = "INSERT OR REPLACE INTO git (repo, timestamp, status ) VALUES ('".$repo."', 0, 'clean');"; $this->sqlite->query($sql); } function haveChangesBeenSubmitted() { $changesAwaiting = true; $res = $this->loadSqlite(); if (!$res) return; $res = $this->sqlite->query("SELECT status FROM git WHERE repo = 'local'"); $rows = $this->sqlite->res2arr($res); $status = $rows[0]['status']; if ($status !== 'submitted' ) $changesAwaiting = false; return $changesAwaiting; } function submittChangesForApproval() { $res = $this->loadSqlite(); if (!$res) return; // Set the time to zero, so the first alert msg will set the correct status $hundred_years_into_future = time() + (60 * 60 * 24 * 365 * 100); $sql = "INSERT OR REPLACE INTO git (repo, timestamp, status ) VALUES ('local', ".$hundred_years_into_future.", 'submitted');"; $this->sqlite->query($sql); $this->changeReadOnly(true); $this->sendNotificationEMail(); } function sendNotificationEMail() { global $conf; $this->getConf(''); $notify = $conf['plugin']['git']['commit_notifcations']; $local_status_page = wl($conf['plugin']['git']['local_status_page'],'',true); $mail = new Mailer(); $mail->to($notify); $mail->subject('An improvement has been submitted for approval!'); $mail->setBody('Please review the proposed changes before the next meeting: '.$local_status_page); return $mail->send(); } function cloneRepo($origin, $destination) { global $conf; $this->getConf(''); $git_exe_path = $conf['plugin']['git']['git_exe_path']; try { $repo = new GitRepo($destination, true, false); $repo->git_path = $git_exe_path; $repo->clone_from($origin); } catch (Exception $e) { msg($e->getMessage()); } } function changeReadOnly($readonly = true) { global $config_cascade; $AUTH_ACL = file($config_cascade['acl']['default']); $lines = array(); foreach($AUTH_ACL as $line){ if(strpos(strtolower($line), strtolower('@USER')) === FALSE) { $lines[] = $line; continue; } if ($readonly) { $lines[] = '* @user '.AUTH_READ; } else { $lines[] = '* @user '.AUTH_DELETE; } $lines[] = $replaced; } // save it io_saveFile($config_cascade['acl']['default'], join('',$lines)); } function render_commit_selector($renderer, $commits) { // When viewing file content differences, the hash gets set in the html request, so we can select the correct option $selected_hash = trim($_REQUEST['hash']); if ($selected_hash === '') $selected_hash = 'all'; // By default select "all". $renderer->doc .= "'; } function render_changed_files_table($renderer, $commits, $repo) { $selected_hash = trim($_REQUEST['hash']); if ($selected_hash === '') $selected_hash = 'all'; // By default select "all". foreach($commits as $commit) { $hash = $commit['hash']; if($hash === $selected_hash || $hash === 'new') $divVisibility = ""; // Show the selected else $divVisibility = " display:none;"; // Hide the rest $renderer->doc .= "
No files have changed for the selected item. If a merge is selected, then no conflicts were detected.
Change type | Page | Changes |
---|---|---|
"; $change = substr($file, 0, 2); if (strpos($change, '?') !== false) $renderer->doc .= "Added:"; else if (strpos($change, 'M') !== false) $renderer->doc .= "Modified:"; else if (strpos($change, 'A') !== false) $renderer->doc .= "Added:"; else if (strpos($change, 'D') !== false) $renderer->doc .= "Removed:"; else if (strpos($change, 'R') !== false) $renderer->doc .= "Removed:"; else if (strpos($change, 'r') !== false) $renderer->doc .= "Removed:"; $renderer->doc .= " | "; $file = trim(substr($file, 2)); $page = $this->getPageFromFile($file); $renderer->doc .= ''.$page.''; $renderer->doc .= " | "; $renderer->doc .= ' '; $renderer->doc .= " | "; $renderer->doc .= "
Left = The current page in Live
';
else $renderer->doc .= '
Left = The page before the selected commited retrieved from GIT
';
$renderer->doc .= 'Right = The page after the selected commit
Left = The last page commited to GIT
';
$renderer->doc .= 'Right = Current wiki content
Left = Current wiki content
';
$renderer->doc .= 'Right = Upstream changes to be merged