1b08c3d51SMarkus Hoffrogge<?php 2b08c3d51SMarkus Hoffrogge 3*2762023dSMarkus Hoffroggenamespace woolfg\dokuwiki\plugin\gitbacked; 4*2762023dSMarkus Hoffrogge 5b08c3d51SMarkus Hoffrogge/* 6b08c3d51SMarkus Hoffrogge * GitBackedUtil.php 7b08c3d51SMarkus Hoffrogge * 8b08c3d51SMarkus Hoffrogge * PHP common utility function lib 9b08c3d51SMarkus Hoffrogge * 10b08c3d51SMarkus Hoffrogge * @package GitBackedUtil.php 11b08c3d51SMarkus Hoffrogge * @version 1.0 12b08c3d51SMarkus Hoffrogge * @author Markus Hoffrogge 13b08c3d51SMarkus Hoffrogge * @copyright Copyright 2023 Markus Hoffrogge 14b08c3d51SMarkus Hoffrogge * @repo https://github.com/woolfg/dokuwiki-plugin-gitbacked 15b08c3d51SMarkus Hoffrogge */ 16b08c3d51SMarkus Hoffrogge 17*2762023dSMarkus Hoffrogge// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols 18*2762023dSMarkus Hoffrogge// must be run within Dokuwiki 19*2762023dSMarkus Hoffroggeif (!defined('DOKU_INC')) die(); 20b08c3d51SMarkus Hoffrogge 21b08c3d51SMarkus Hoffrogge// ------------------------------------------------------------------------ 22b08c3d51SMarkus Hoffrogge 23b08c3d51SMarkus Hoffrogge/** 24b08c3d51SMarkus Hoffrogge * GitBacked Utility Class 25b08c3d51SMarkus Hoffrogge * 26b08c3d51SMarkus Hoffrogge * This class provides common utility functions. 27b08c3d51SMarkus Hoffrogge * 28b08c3d51SMarkus Hoffrogge * @class GitBackedUtil 29b08c3d51SMarkus Hoffrogge */ 30*2762023dSMarkus Hoffroggeclass GitBackedUtil 31*2762023dSMarkus Hoffrogge{ 32b08c3d51SMarkus Hoffrogge /** 33b08c3d51SMarkus Hoffrogge * GitBacked temp directory 34b08c3d51SMarkus Hoffrogge * 35b08c3d51SMarkus Hoffrogge * @var string 36b08c3d51SMarkus Hoffrogge */ 37b08c3d51SMarkus Hoffrogge protected static $temp_dir = ''; 38b08c3d51SMarkus Hoffrogge 39b08c3d51SMarkus Hoffrogge /** 40b08c3d51SMarkus Hoffrogge * Checks, if a given path name is an absolute path or not. 41b08c3d51SMarkus Hoffrogge * This function behaves like absolute path determination in dokuwiki init.php fullpath() method. 42b08c3d51SMarkus Hoffrogge * The relevant code has been copied from there. 43b08c3d51SMarkus Hoffrogge * 44b08c3d51SMarkus Hoffrogge * @access public 45b08c3d51SMarkus Hoffrogge * @param string $path a file path name 46b08c3d51SMarkus Hoffrogge * @return bool 47b08c3d51SMarkus Hoffrogge */ 48*2762023dSMarkus Hoffrogge public static function isAbsolutePath($path) 49*2762023dSMarkus Hoffrogge { 50b08c3d51SMarkus Hoffrogge $ret = false; 51b08c3d51SMarkus Hoffrogge 52b08c3d51SMarkus Hoffrogge $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || !empty($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'])); 53b08c3d51SMarkus Hoffrogge // check for the (indestructable) root of the path - keeps windows stuff intact 54b08c3d51SMarkus Hoffrogge if ($path[0] == '/') { 55b08c3d51SMarkus Hoffrogge $ret = true; 56b08c3d51SMarkus Hoffrogge } elseif ($iswin) { 57b08c3d51SMarkus Hoffrogge // match drive letter and UNC paths 58b08c3d51SMarkus Hoffrogge if (preg_match('!^([a-zA-z]:)(.*)!', $path, $match)) { 59b08c3d51SMarkus Hoffrogge $ret = true; 60b08c3d51SMarkus Hoffrogge } elseif (preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!', $path, $match)) { 61b08c3d51SMarkus Hoffrogge $ret = true; 62b08c3d51SMarkus Hoffrogge } 63b08c3d51SMarkus Hoffrogge } 64b08c3d51SMarkus Hoffrogge 65b08c3d51SMarkus Hoffrogge return $ret; 66b08c3d51SMarkus Hoffrogge } 67b08c3d51SMarkus Hoffrogge 68b08c3d51SMarkus Hoffrogge /** 69b08c3d51SMarkus Hoffrogge * Returns the $path as is, if it is an absolute path. 70b08c3d51SMarkus Hoffrogge * Otherwise it will prepend the base path appropriate 71b08c3d51SMarkus Hoffrogge * to the type of DW instance. 72b08c3d51SMarkus Hoffrogge * 73b08c3d51SMarkus Hoffrogge * @access public 74b08c3d51SMarkus Hoffrogge * @param string $path a file path name 75b08c3d51SMarkus Hoffrogge * @return string an appropriate absolute path 76b08c3d51SMarkus Hoffrogge */ 77*2762023dSMarkus Hoffrogge public static function getEffectivePath($path) 78*2762023dSMarkus Hoffrogge { 79b08c3d51SMarkus Hoffrogge $ret = $path; 80b08c3d51SMarkus Hoffrogge 81b08c3d51SMarkus Hoffrogge if (self::isAbsolutePath($ret)) { 82b08c3d51SMarkus Hoffrogge return $ret; 83b08c3d51SMarkus Hoffrogge } 84b08c3d51SMarkus Hoffrogge if (defined('DOKU_FARM')) { 85b08c3d51SMarkus Hoffrogge $ret = DOKU_CONF . '../' . $ret; 86b08c3d51SMarkus Hoffrogge } else { 87b08c3d51SMarkus Hoffrogge $ret = DOKU_INC . $ret; 88b08c3d51SMarkus Hoffrogge } 89b08c3d51SMarkus Hoffrogge return $ret; 90b08c3d51SMarkus Hoffrogge } 91b08c3d51SMarkus Hoffrogge 92b08c3d51SMarkus Hoffrogge /** 93b08c3d51SMarkus Hoffrogge * Returns the temp dir for GitBacked plugin. 94b08c3d51SMarkus Hoffrogge * It ensures that the temp dir will be created , if not yet existing. 95b08c3d51SMarkus Hoffrogge * 96b08c3d51SMarkus Hoffrogge * @access public 97b08c3d51SMarkus Hoffrogge * @return string the gitbacked temp directory name 98b08c3d51SMarkus Hoffrogge */ 99*2762023dSMarkus Hoffrogge public static function getTempDir() 100*2762023dSMarkus Hoffrogge { 101b08c3d51SMarkus Hoffrogge if (empty(self::$temp_dir)) { 102b08c3d51SMarkus Hoffrogge global $conf; 103b08c3d51SMarkus Hoffrogge self::$temp_dir = $conf['tmpdir'] . '/gitbacked'; 104b08c3d51SMarkus Hoffrogge io_mkdir_p(self::$temp_dir); 105b08c3d51SMarkus Hoffrogge } 106b08c3d51SMarkus Hoffrogge return self::$temp_dir; 107b08c3d51SMarkus Hoffrogge } 108b08c3d51SMarkus Hoffrogge 109b08c3d51SMarkus Hoffrogge /** 110b08c3d51SMarkus Hoffrogge * Creates a temp file and writes the $message to it. 111b08c3d51SMarkus Hoffrogge * It ensures that the temp dir will be created , if not yet existing. 112b08c3d51SMarkus Hoffrogge * 113b08c3d51SMarkus Hoffrogge * @access public 114b08c3d51SMarkus Hoffrogge * @param string $message the text message 115b08c3d51SMarkus Hoffrogge * @return string the temp filename created 116b08c3d51SMarkus Hoffrogge */ 117*2762023dSMarkus Hoffrogge public static function createMessageFile($message) 118*2762023dSMarkus Hoffrogge { 119b08c3d51SMarkus Hoffrogge $tmpfname = tempnam(self::getTempDir(), 'gitMessage_'); 120b08c3d51SMarkus Hoffrogge $handle = fopen($tmpfname, "w"); 121b08c3d51SMarkus Hoffrogge if (!empty($message)) { 122b08c3d51SMarkus Hoffrogge fwrite($handle, $message); 123b08c3d51SMarkus Hoffrogge } 124b08c3d51SMarkus Hoffrogge fclose($handle); 125b08c3d51SMarkus Hoffrogge return $tmpfname; 126b08c3d51SMarkus Hoffrogge } 127b08c3d51SMarkus Hoffrogge 128*2762023dSMarkus Hoffrogge /** 129*2762023dSMarkus Hoffrogge * Determine closest git repository path for a given path as absolute PHP realpath(). 130*2762023dSMarkus Hoffrogge * This search starts in $path - if $path does not contain .git, 131*2762023dSMarkus Hoffrogge * it will iterate the directories upwards as long as it finds a directory 132*2762023dSMarkus Hoffrogge * containing a .git folder. 133*2762023dSMarkus Hoffrogge * 134*2762023dSMarkus Hoffrogge * @access public 135*2762023dSMarkus Hoffrogge * @return string the next git repo root dir as absolute PHP realpath() 136*2762023dSMarkus Hoffrogge * or empty string, if no git repo found. 137*2762023dSMarkus Hoffrogge */ 138*2762023dSMarkus Hoffrogge public static function getClosestAbsoluteRepoPath($path) 139*2762023dSMarkus Hoffrogge { 140*2762023dSMarkus Hoffrogge $descriptorspec = array( 141*2762023dSMarkus Hoffrogge 1 => array('pipe', 'w'), 142*2762023dSMarkus Hoffrogge 2 => array('pipe', 'w'), 143*2762023dSMarkus Hoffrogge ); 144*2762023dSMarkus Hoffrogge $ret = ''; 145*2762023dSMarkus Hoffrogge $pipes = array(); 146*2762023dSMarkus Hoffrogge // Using --git-dir rather than --absolute-git-dir for a wider git versions compatibility 147*2762023dSMarkus Hoffrogge //$command = Git::getBin()." rev-parse --absolute-git-dir"; 148*2762023dSMarkus Hoffrogge $command = Git::getBin() . " rev-parse --git-dir"; 149*2762023dSMarkus Hoffrogge //dbglog("GitBacked - Command: ".$command); 150*2762023dSMarkus Hoffrogge $resource = proc_open($command, $descriptorspec, $pipes, $path); 151*2762023dSMarkus Hoffrogge $stdout = stream_get_contents($pipes[1]); 152*2762023dSMarkus Hoffrogge $stderr = stream_get_contents($pipes[2]); 153*2762023dSMarkus Hoffrogge foreach ($pipes as $pipe) { 154*2762023dSMarkus Hoffrogge fclose($pipe); 155*2762023dSMarkus Hoffrogge } 156*2762023dSMarkus Hoffrogge 157*2762023dSMarkus Hoffrogge $status = trim(proc_close($resource)); 158*2762023dSMarkus Hoffrogge if ($status == 0) { 159*2762023dSMarkus Hoffrogge $repo_git_dir = trim($stdout); 160*2762023dSMarkus Hoffrogge //dbglog("GitBacked - $command: '".$repo_git_dir."'"); 161*2762023dSMarkus Hoffrogge if (!empty($repo_git_dir)) { 162*2762023dSMarkus Hoffrogge if (strcmp($repo_git_dir, ".git") === 0) { 163*2762023dSMarkus Hoffrogge // convert to absolute path based on this command execution directory 164*2762023dSMarkus Hoffrogge $repo_git_dir = $path . '/' . $repo_git_dir; 165*2762023dSMarkus Hoffrogge } 166*2762023dSMarkus Hoffrogge $repo_path = dirname(realpath($repo_git_dir)); 167*2762023dSMarkus Hoffrogge $doku_inc_path = dirname(realpath(DOKU_INC)); 168*2762023dSMarkus Hoffrogge if (strlen($repo_path) < strlen($doku_inc_path)) { 169*2762023dSMarkus Hoffrogge // This code should never be reached! 170*2762023dSMarkus Hoffrogge // If we get here, then we are beyond DOKU_INC - so this not supposed to be for us! 171*2762023dSMarkus Hoffrogge return ''; 172*2762023dSMarkus Hoffrogge } 173*2762023dSMarkus Hoffrogge //dbglog('GitBacked - $repo_path: '.$repo_path); 174*2762023dSMarkus Hoffrogge if (file_exists($repo_path . "/.git") && is_dir($repo_path . "/.git")) { 175*2762023dSMarkus Hoffrogge return $repo_path; 176*2762023dSMarkus Hoffrogge } 177*2762023dSMarkus Hoffrogge } 178*2762023dSMarkus Hoffrogge } 179*2762023dSMarkus Hoffrogge return ''; 180*2762023dSMarkus Hoffrogge } 181b08c3d51SMarkus Hoffrogge} 182b08c3d51SMarkus Hoffrogge/* End of file */ 183