Commits

Anonymous committed 46961a5

Pulled the OFL out of hgphp and hgconf2ini method signatures in favor of 'transaction' order of method calls

  • Participants
  • Parent commits e8959f5

Comments (0)

Files changed (5)

-Mercurial Repository Manager for PHP
+phpHgAdmin - Mercurial Repository Manager for PHP
 for
 Mercurial Shared-server (hgwebdir.cgi) Deployments
 Mercurial 1.3.1-compliant
 Must revise and edit these configuration files before installation is complete. In /admin/application/config/:
 	* config.php - standard CodeIgniter setup
 	* hgphp.php - Mercurial-related defaults
-	* mantis_auth.php - in future, for Mantis BT session integration. 
-						As of this release, moderates permitted basic-authenticated users.
 						
 This system was designed for use with the quick Hg installation guide available at:
 http://redirect.joshjcarrier.com/?r=hgwebinstall
 Web: http://redirect.joshjcarrier.com/?r=hgphp
 
 Changelog:
-1.0.20100603
+1.0.2010xxxx
 - hgweb.config and the repositories can now exist in separate directories
 - error suppression when invalid absolute paths set
 - auto-insertion bug which re-added all folders in the repo directory on create/delete, even if not formally registered
 - blacklists creation of a repo derived from config 'base_url' instead of value "admin"
 	where $config['base_url'] = http://www.contoso.com/hgadmin will blacklist "hgadmin"
 - missed translation items in hgdir controller
+- installation portability
+- rebranded to phpHgAdmin
 Upgrade warning: there are new items in hgphp.php configuration file, and some revised existing parameters.
 
 1.0.20100519

admin/application/controllers/hgdir.php

 		
 		$this->template->title(lang('hgphp_title_directory'), 'Mercurial Repository Manager');
 
-		$lsdir = $this->hgphp->lsdir($this->ofl_lock_hgwebconf);
+		$this->hgphp->start_transaction($this->ofl_lock_hgwebconf, $dummy='');
+		$lsdir = $this->hgphp->lsdir();
+		$this->hgphp->end_transaction();
 		
 		if(!is_array($lsdir))
 		{
 		}
 		else
 		{
-			$ofl_dummylock_hgrc = '';
-			$action_status = $this->hgphp->create_repository($r_name, $this->ofl_lock_hgwebconf, $ofl_dummylock_hgrc);
+			$this->hgphp->start_transaction($this->ofl_lock_hgwebconf, $dummy='');
+			$action_status = $this->hgphp->create_repository($r_name);
+			$this->hgphp->end_transaction();
 			
 			switch($action_status){
 				case HGPHP_OK:
 		}
 		else
 		{
-			$action_status = $this->hgphp->delete_repository($r_name, $this->ofl_lock_hgwebconf);
+			$this->hgphp->start_transaction($this->ofl_lock_hgwebconf, $dummy='');
+			$action_status = $this->hgphp->delete_repository($r_name);
+			$this->hgphp->end_transaction();
 			
 			switch($action_status){
 				case HGPHP_OK:

admin/application/controllers/hgrepo.php

 			
 			if($valid)
 			{
-				$save_status = $this->hgphp->update_repository($repositoryName, $hgrc_form, $ofl_lock_hgrc);
+				$this->hgphp->start_transaction($dummy='', $ofl_lock_hgrc);
+				$save_status = $this->hgphp->update_repository($repositoryName, $hgrc_form);
+				$this->hgphp->end_transaction();
 				
 				switch($save_status)
 				{
 		
 		$this->template->title($repositoryName, 'Mercurial Repository Editor');
 		
-		$hgrc = $this->hgphp->stat_repository($repositoryName, $ofl_lock_hgrc);
+		$this->hgphp->start_transaction($dummy='', $ofl_lock_hgrc);
+		$hgrc = $this->hgphp->stat_repository($repositoryName);
+		$this->hgphp->end_transaction();
 		
 		if(!is_array($hgrc))
 		{

admin/application/libraries/hgconf2ini.php

 class HgConf2Ini
 {
 	private $_ci;
+	private $_ofl_lock;
 	private $cache_hgwebconf;
 	private $cache_hgrc = array();
 	
 		}
 	}
 	
+	/**
+	 * Registers OFL lock
+	 */
+	function register_OFL(&$ofl_lock)
+	{
+		$this->_ofl_lock = &$ofl_lock;
+	}
+	
+	function unregister_OFL()
+	{
+		$dummy = '';
+		$this->_ofl_lock = &$dummy;
+	}
 	
 	/**
 	 * getHgWebDirConfig
 	 * Scans Mercurial's hgweb.conf configuration file and returns
 	 * representation in key/value pairs.
-	 * @param $ofl_lock_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return multi-dimensional array representing Hg directory config file (see PHP ini parsing), status code otherwise
 	 */
-	function getHgWebDirConfig(&$ofl_lock_hgwebconf)
+	function getHgWebDirConfig()
 	{
 		// check if need to create cache
 		if(!is_array($this->cache_hgwebconf))
 		{
-			$hgwebconf_all = $this->__hgwebconf_compat_load($ofl_lock_hgwebconf);
+			$hgwebconf_all = $this->__hgwebconf_compat_load();
 			$this->cache_hgwebconf = $hgwebconf_all;
 		}
 
 	 * setHgWebDirConfig
 	 * Converts a multi-dimensional array representing a Hg directory config file (see PHP ini parsing) to file
 	 * @param hgwebconf_data multi-dimensional array representing a Hg directory config file
-	 * @param ofl_lock_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function setHgWebDirConfig($hgwebconf_data, &$ofl_lock_hgwebconf)
+	function setHgWebDirConfig($hgwebconf_data)
 	{
-		$hgwebconf_status = $this->__hgwebconf_compat_persist($hgwebconf_data, $ofl_lock_hgwebconf);
+		$hgwebconf_status = $this->__hgwebconf_compat_persist($hgwebconf_data);
 		
 		if($hgwebconf_status == HGPHP_OK)
 		{
 	 * getHgWebDirCollections
 	 * Scans Mercurial's hgweb.conf configuration file and returns
 	 * a single associative array whose key/value pairs are the names of each listed repository
-	 * @param ofl_lock_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return a single associative array whose key/value pairs are the names of each listed repository, status code otherwise
 	 */
-	function getHgWebDirCollections(&$ofl_lock_hgwebconf)
+	function getHgWebDirCollections()
 	{
-		$hgwebconf_all = $this->getHgWebDirConfig($ofl_lock_hgwebconf);
+		$hgwebconf_all = $this->getHgWebDirConfig();
 		
 		if(!is_integer($hgwebconf_all))
 		{
 	 * Replaces the current directory config collections with ones represented by a single associative array whose key/value pairs 
 	 * are the names of each listed repository
 	 * @param hgwebconf_collections a single associative array whose key/value pairs are the names of each listed repository
-	 * @param ofl_lock_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function setHgWebDirCollections($hgwebconf_collections, &$ofl_lock_hgwebconf)
+	function setHgWebDirCollections($hgwebconf_collections)
 	{
-		$ofl_dummylock_hgwebconf = '';
-		$hgwebconf_all = $this->getHgWebDirConfig($ofl_dummylock_hgwebconf); // no need to update lock yet
+		$hgwebconf_all = $this->getHgWebDirConfig(); // no need to update lock yet
 		
 		if(is_array($hgwebconf_all))
 		{
 			$hgwebconf_all['collections'] = $hgwebconf_collections;
-			return $this->setHgWebDirConfig($hgwebconf_all, $ofl_lock_hgwebconf);
+			return $this->setHgWebDirConfig($hgwebconf_all);
 		}
 		else
 		{
 	 * Scans a Mercurial repository's HGRC configuration file into a multi-dimensional array representing 
 	 * Hg directory config file (see PHP ini parsing)
 	 * @param r_name name of the repository containing the target HGRC file
-	 * @param $ofl_lock_hgrc (updated by reference) the current optimistic file lock value
 	 * @return a multi-dimensional array representing HGRC configuration file, status code otherwise
 	 */
-	function getHGRC($r_name, &$ofl_lock_hgrc)
+	function getHGRC($r_name)
 	{
 		// check if need to create cache
 		if(!isset($this->cache_hgrc[$r_name]))
 		{
-			$hgrc_data = $this->__hgrc_compat_load($r_name, $ofl_lock_hgrc);
+			$hgrc_data = $this->__hgrc_compat_load($r_name);
 			if(is_array($hgrc_data))
 			{
 				$this->cache_hgrc[$r_name] = $hgrc_data;
 	 * Replaces the current HGRC file with one generated represented by a multi-dimensional array
 	 * @param r_name name of the repository containing the target HGRC file
 	 * @param hgrc_data multi-array representation of the new HGRC file
-	 * @param $ofl_lock_hgrc (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function setHGRC($r_name, $hgrc_data, &$ofl_lock_hgrc)
+	function setHGRC($r_name, $hgrc_data)
 	{
 		// always update cache
 		$this->cache_hgrc[$r_name] = $hgrc_data;
 		
 		// always persist updated cache
-		return $this->__hgrc_compat_persist($r_name, $this->cache_hgrc[$r_name], $ofl_lock_hgrc);
+		return $this->__hgrc_compat_persist($r_name, $this->cache_hgrc[$r_name]);
 	}
 	
 	/**
 	 * touchHGRC
 	 * Generates a new HGRC file in a given repository directory, with default values
 	 * @param r_name name of the repo folder which will have an HGRC file added to
-	 * @param ofl_lock_hgrc (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function touchHGRC($r_name, &$ofl_lock_hgrc)
+	function touchHGRC($r_name)
 	{
 		$hgrc_path = $this->_repositories_abs_dir . $r_name . '/.hg/hgrc';
 		
 		// create file
-		$touch_status = $this->_ci->optimisticflock->ofl_touch($hgrc_path, $ofl_lock_hgrc);
+		$touch_status = $this->_ci->optimisticflock->ofl_touch($hgrc_path, $this->_ofl_lock);
 		if($touch_status == HGPHP_OK)
 		{
 			$blank_hgrc = $this->__blank_hgrc($r_name);
 			
 			// update touch status for setHGRC return code
-			$touch_status = $this->setHGRC($r_name, $blank_hgrc, $ofl_lock_hgrc);
+			$touch_status = $this->setHGRC($r_name, $blank_hgrc);
 		}
 		return $touch_status;
 	}
 	function unlinkHGRC($r_name)
 	{
 		$hgrc_path = $this->_repositories_abs_dir . $r_name . '/.hg/hgrc';
-		$ofl_dummylock_hgrc = '';
+		
 		// design decision - force deletion of repository always
-		return $this->_ci->optimisticflock->ofl_unlink($hgrc_path, $ofl_dummylock_hgrc, TRUE);
+		return $this->_ci->optimisticflock->ofl_unlink($hgrc_path, $this->_ofl_lock, TRUE);
 	}
 	
 	/**
 	 * Compatibility layer for Mercurial PHP config files,
 	 * which contain forward slashes '\' as key values.
 	 * 
-	 * @param ofl_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return contents of a php_ini array compatible representation, status code otherwise
 	 */
-	function __hgwebconf_compat_load(&$ofl_hgwebconf)
+	function __hgwebconf_compat_load()
 	{
 		// load the PHP to file
 		$hgwebconf = $this->_hgwebconf_abs_filepath;
 
 		// concurrency-safe get contents
 		$hgwebconf_err_code = '';
-		$hgwebconf_str = $this->_ci->optimisticflock->ofl_file_get_contents($hgwebconf, $ofl_hgwebconf, $hgwebconf_err_code);
+		$hgwebconf_str = $this->_ci->optimisticflock->ofl_file_get_contents($hgwebconf, $this->_ofl_lock, $hgwebconf_err_code);
 		
 		if($hgwebconf_err_code == HGPHP_OK)
 		{
 			// replace all occurances of the forward slash '/'
 			$hgwebconf_str = str_replace('/', $this->_compatability_delimiter, $hgwebconf_str);
 			
+			// FIXME replace this with PHP version-independent and improved parser
 			// write to private temporary file (no concurrency worry)	
 			// prepare a temp file in scratch space for compatability conversion
 			$hgwebconf_tmp_name = $this->_lock_dir . uniqid('hgweb.config.lock.', TRUE);
 	 * __hgwebconf_compat_persist (private method)
 	 * Takes a PHP-compatable php_ini array and converts it back into the original file.
 	 * 
-	 * @param ofl_lock (updated by reference) the current optimistic file lock value
 	 * @param status code
 	 */
-	function __hgwebconf_compat_persist($hgwebconf_all, &$ofl_lock)
+	function __hgwebconf_compat_persist($hgwebconf_all)
 	{
 		$hgwebconf_new_ini = ';Generated by Hg-PHP Mercurial Repository Manager v'.HGPHP_VERSION;
 		// generate ini string
 		$hgwebconf_new_ini = str_replace($this->_compatability_delimiter, '/', $hgwebconf_new_ini);
 		
 		// concurrent-safe write
-		$put_status = $this->_ci->optimisticflock->ofl_file_put_contents($this->_hgwebconf_abs_filepath, $hgwebconf_new_ini, $ofl_lock);
+		$put_status = $this->_ci->optimisticflock->ofl_file_put_contents($this->_hgwebconf_abs_filepath, $hgwebconf_new_ini, $this->_ofl_lock);
 		
 		return $put_status;
 	}
 	 * Scans a Mercurial repository's HGRC configuration file into a multi-dimensional array representing 
 	 * Hg directory config file (see PHP ini parsing)
 	 * @param r_name name of the repository containing the target HGRC file
-	 * @param ofl_lock_hgrc (updated by reference) the current optimistic file lock value
 	 * @return a multi-dimensional array representing HGRC configuration file, FALSE otherwise
 	 */
-	function __hgrc_compat_load($r_name, &$ofl_lock_hgrc)
+	function __hgrc_compat_load($r_name)
 	{
 		$hgrc = $this->_repositories_abs_dir . $r_name . '/.hg/hgrc';
 		
 		// concurrency-safe ini parse
 		$hgrc_err_code = '';
-		$hgrc_all = $this->_ci->optimisticflock->ofl_parse_ini_file($hgrc, true, $ofl_lock_hgrc, $hgrc_err_code);
+		$hgrc_all = $this->_ci->optimisticflock->ofl_parse_ini_file($hgrc, true, $this->_ofl_lock, $hgrc_err_code);
 
 		if($hgrc_err_code == HGPHP_OK)
 		{
 	 * Replaces the current HGRC file with one generated represented by a multi-dimensional array
 	 * @param r_name name of the repository containing the target HGRC file
 	 * @param hgrc_data multi-array representation of the new HGRC file
-	 * @param ofl_lock_hgrc (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function __hgrc_compat_persist($r_name, $hgrc_data, &$ofl_lock_hgrc)
+	function __hgrc_compat_persist($r_name, $hgrc_data)
 	{
 		$hgrc_path = $this->_repositories_abs_dir . $r_name . '/.hg/hgrc';
 		
 			$hgrc_new_ini .= "\n;End generated HGRC\n";
 			
 			// concurrency-safe persist to disk
-			return $this->_ci->optimisticflock->ofl_file_put_contents($hgrc_path, $hgrc_new_ini, $ofl_lock_hgrc, false);
+			return $this->_ci->optimisticflock->ofl_file_put_contents($hgrc_path, $hgrc_new_ini, $this->_ofl_lock, false);
 		}
 		else
 		{

admin/application/libraries/hgphp.php

 class HgPHP
 {
 	private $_ci;
+	private $_ofl_lock_hgweb;
+	private $_ofl_lock_hgrc;
 	
 	function __construct($config = array())
 	{
 	 */
 	
 	/**
+	 * Associates OFL locks
+	 */
+	function start_transaction(&$ofl_lock_hgweb, &$ofl_lock_hgrc)
+	{
+		$this->_ofl_lock_hgweb = &$ofl_lock_hgweb;
+		$this->_ofl_lock_hgrc = &$ofl_lock_hgrc;
+	}
+	
+	/**
+	 * Disassociates OFL locks
+	 */
+	function end_transaction()
+	{
+		$dummy = '';
+		$this->_ofl_lock_hgweb = &$dummy;
+		$this->_ofl_lock_hgrc = &$dummy;
+	}
+	
+	/**
 	 * Returns a list of available repositories.
 	 * Will show up if: detected in repo directory
 	 * Will have status "enabled" if: detected in hgweb.config
 	 * 
-	 * @param ofl_lock_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return an array of 0 or more detected repositories
 	 */
-	function lsdir(&$ofl_lock_hgwebconf)
+	function lsdir()
 	{
 		$realdir = $this->__realdirscan();
-		$hgwebdir_compat = $this->_ci->hgconf2ini->getHgWebDirCollections($ofl_lock_hgwebconf);
+		$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgweb);
+		$hgwebdir_compat = $this->_ci->hgconf2ini->getHgWebDirCollections();
 				
 		$allrepo = $realdir;
 		if(!is_integer($hgwebdir_compat))
 	 * - adding an entry in hgrc if not present
 	 * - creating a bare repository if not present
 	 * @param r_name name of the new repository to create, used as folder name
-	 * @param hg_lock_hgwebconf (updated by reference) the last known optimistic file lock value of hgwebconf
-	 * @param hg_lock_hgrc (updated by reference) value of hgrc's lock value
 	 * @return status code
 	 */
-	function create_repository($r_name, &$ofl_lock_hgwebconf, &$hg_lock_hgrc)
+	function create_repository($r_name)
 	{
 		if(!$this->can_create($r_name))
 		{
 		}
 		
 		$create_status = HGPHP_OK;
-		$ofl_dummylock_hgwebconf = '';
-		$lsdir = $this->_ci->hgconf2ini->getHgWebDirCollections($ofl_dummylock_hgwebconf); // don't want to update the lock yet
+		
+		$lsdir = $this->_ci->hgconf2ini->getHgWebDirCollections(); 
 
 		// simplifies repo list into array where name is both key and value
 		// this is how hgweb.config wants it
 		{
 			// edit the directory
 			$existingdir[$r_name] = $r_name;
-			$create_status = $this->_ci->hgconf2ini->setHgWebDirCollections($existingdir, $ofl_lock_hgwebconf);
+			$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgweb);
+			$create_status = $this->_ci->hgconf2ini->setHgWebDirCollections($existingdir);
 			if($create_status == HGPHP_OK)
 			{
 				// then create the repository
-				$create_status = $this->create_repository_dir($r_name, $hg_lock_hgrc);
+				$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgrc);
+				$create_status = $this->create_repository_dir($r_name);
 			}
 		}
 		else
 	 * Update repository's hgrc
 	 * @param r_name name of the repository to update hgrc for
 	 * @param hgrc_data array representing new hgrc file
-	 * @param ofl_lock_hgrc (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function update_repository($r_name, $hgrc_data, &$ofl_lock_hgrc)
+	function update_repository($r_name, $hgrc_data)
 	{
 		if(!$this->can_update($r_name))
 		{
 			return HGPHP_ERR_PERM_USR;
 		}
-		
-		return $this->_ci->hgconf2ini->setHGRC($r_name, $hgrc_data, $ofl_lock_hgrc);
+		$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgrc);
+		return $this->_ci->hgconf2ini->setHGRC($r_name, $hgrc_data);
 	}
 	
 	/**
 	 * delete_repository
 	 * Deletes a repository from the file system and unregisters it from hgweb.config
 	 * @param r_name name of the repo to delete permanently
-	 * @param $ofl_lock_hgwebconf (updated by reference) the current optimistic file lock value
 	 * @return status code
 	 */
-	function delete_repository($r_name, &$ofl_lock_hgwebconf)
+	function delete_repository($r_name)
 	{
 		if(!$this->can_delete($r_name))
 		{
 		}
 		
 		$del_status = HGPHP_OK;
-		$ofl_dummylock_hgwebconf = '';
-		$lsdir = $this->_ci->hgconf2ini->getHgWebDirCollections($ofl_dummylock_hgwebconf); // don't want to update lock yet
+		$lsdir = $this->_ci->hgconf2ini->getHgWebDirCollections(); 
 		
 		// simplifies repo list into array where name is both key and value
 		// this is how hgweb.config wants it
 			// edit the directory
 			unset($existingdir[$r_name]);
 			// remove hgweb.config
-			$del_status = $this->_ci->hgconf2ini->setHgWebDirCollections($existingdir, $ofl_lock_hgwebconf);
+			$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgweb);
+			$del_status = $this->_ci->hgconf2ini->setHgWebDirCollections($existingdir);
 				
 			// remove from hgweb.config
 			if($del_status == HGPHP_OK)
 				if($lsdir[$r_name]['status'] != HGPHP_REPO_STATUS_MISSING)
 				{
 					// unregister hgrc from transaction manager to keep index small
+					$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgrc);
 					$del_status = $this->_ci->hgconf2ini->unlinkHGRC($r_name);
 					
 					if($del_status == HGPHP_OK)
 	 * stat_repository
 	 * Returns the HGRC represented as an array for the specified repository
 	 * @param r_name name of the project whose hgrc to retrieve
-	 * @param ofl_lock_hgrc (updated by reference) the current optimistic file lock value will be updated
 	 * @return array representing hgrc or status code
 	 */
-	function stat_repository($r_name, &$ofl_lock_hgrc)
+	function stat_repository($r_name)
 	{
 		if(!$this->can_view($r_name))
 		{
 			return HGPHP_ERR_PERM_USR;
 		}
-		
-		return $this->_ci->hgconf2ini->getHGRC($r_name, $ofl_lock_hgrc);
+		$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgrc);
+		return $this->_ci->hgconf2ini->getHGRC($r_name);
 	}
 	 
 
 	 * create_repository_dir
 	 * Creates a whole repository directory, with hgrc
 	 * @param r_name name of repository to create directory for
-	 * @param ofl_lock_hgrc (updated by reference) the current optimistic file lock value will be updated
 	 * @return status code
 	 */
-	function create_repository_dir($r_name, &$ofl_lock_hgrc)
+	function create_repository_dir($r_name)
 	{
 		if(!$this->can_create($r_name))
 		{
 		if($create_status == TRUE)
 		{
 			// create hgrc
-			$create_status = $this->_ci->hgconf2ini->touchHGRC($r_name, $ofl_lock);
+			$this->_ci->hgconf2ini->register_OFL($this->_ofl_lock_hgrc);
+			$create_status = $this->_ci->hgconf2ini->touchHGRC($r_name);
 		}
 		else
 		{