⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adodb-xmlschema.inc.php

📁 eGroupWare is a multi-user, web-based groupware suite developed on a custom set of PHP-based APIs. C
💻 PHP
📖 第 1 页 / 共 4 页
字号:
	* @access private
	*/
	function _tag_cdata( &$parser, $cdata ) {
	}
	
	/**
	* XML Callback to process end elements
	*
	* @access private
	* @internal
	*/
	function _tag_close( &$parser, $tag ) {
		
	}
	
	/**
	* Converts an XML schema string to the specified DTD version.
	*
	* Call this method to convert a string containing an XML schema to a different AXMLS
	* DTD version. For instance, to convert a schema created for an pre-1.0 version for 
	* AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version 
	* parameter is specified, the schema will be converted to the current DTD version. 
	* If the newFile parameter is provided, the converted schema will be written to the specified
	* file.
	* @see ConvertSchemaFile()
	*
	* @param string $schema String containing XML schema that will be converted.
	* @param string $newVersion DTD version to convert to.
	* @param string $newFile File name of (converted) output file.
	* @return string Converted XML schema or FALSE if an error occurs.
	*/
	function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
		
		// grab current version
		if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
			return FALSE;
		}
		
		if( !isset ($newVersion) ) {
			$newVersion = $this->schemaVersion;
		}
		
		if( $version == $newVersion ) {
			$result = $schema;
		} else {
			$result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
		}
		
		if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
			fwrite( $fp, $result );
			fclose( $fp );
		}
		
		return $result;
	}
	
	/**
	* Converts an XML schema file to the specified DTD version.
	*
	* Call this method to convert the specified XML schema file to a different AXMLS
	* DTD version. For instance, to convert a schema created for an pre-1.0 version for 
	* AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version 
	* parameter is specified, the schema will be converted to the current DTD version. 
	* If the newFile parameter is provided, the converted schema will be written to the specified
	* file.
	* @see ConvertSchemaString()
	*
	* @param string $filename Name of XML schema file that will be converted.
	* @param string $newVersion DTD version to convert to.
	* @param string $newFile File name of (converted) output file.
	* @return string Converted XML schema or FALSE if an error occurs.
	*/
	function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
		
		// grab current version
		if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
			return FALSE;
		}
		
		if( !isset ($newVersion) ) {
			$newVersion = $this->schemaVersion;
		}
		
		if( $version == $newVersion ) {
			$result = file_get_contents( $filename );
			
			// remove unicode BOM if present
			if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
				$result = substr( $result, 3 );
			}
		} else {
			$result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
		}
		
		if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
			fwrite( $fp, $result );
			fclose( $fp );
		}
		
		return $result;
	}
	
	function TransformSchema( $schema, $xsl, $schematype='string' )
	{
		// Fail if XSLT extension is not available
		if( ! function_exists( 'xslt_create' ) ) {
			return FALSE;
		}
		
		$xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
		
		// look for xsl
		if( !is_readable( $xsl_file ) ) {
			return FALSE;
		}
		
		switch( $schematype )
		{
			case 'file':
				if( !is_readable( $schema ) ) {
					return FALSE;
				}
				
				$schema = file_get_contents( $schema );
				break;
			case 'string':
			default:
				if( !is_string( $schema ) ) {
					return FALSE;
				}
		}
		
		$arguments = array (
			'/_xml' => $schema,
			'/_xsl' => file_get_contents( $xsl_file )
		);
		
		// create an XSLT processor
		$xh = xslt_create ();
		
		// set error handler
		xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
		
		// process the schema
		$result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); 
		
		xslt_free ($xh);
		
		return $result;
	}
	
	/**
	* Processes XSLT transformation errors
	*
	* @param object $parser XML parser object
	* @param integer $errno Error number
	* @param integer $level Error level
	* @param array $fields Error information fields
	*
	* @access private
	*/
	function xslt_error_handler( $parser, $errno, $level, $fields ) {
		if( is_array( $fields ) ) {
			$msg = array(
				'Message Type' => ucfirst( $fields['msgtype'] ),
				'Message Code' => $fields['code'],
				'Message' => $fields['msg'],
				'Error Number' => $errno,
				'Level' => $level
			);
			
			switch( $fields['URI'] ) {
				case 'arg:/_xml':
					$msg['Input'] = 'XML';
					break;
				case 'arg:/_xsl':
					$msg['Input'] = 'XSL';
					break;
				default:
					$msg['Input'] = $fields['URI'];
			}
			
			$msg['Line'] = $fields['line'];
		} else {
			$msg = array(
				'Message Type' => 'Error',
				'Error Number' => $errno,
				'Level' => $level,
				'Fields' => var_export( $fields, TRUE )
			);
		}
		
		$error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
					   . '<table>' . "\n";
		
		foreach( $msg as $label => $details ) {
			$error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
		}
		
		$error_details .= '</table>';
		
		trigger_error( $error_details, E_USER_ERROR );
	}
	
	/**
	* Returns the AXMLS Schema Version of the requested XML schema file.
	*
	* Call this method to obtain the AXMLS DTD version of the requested XML schema file.
	* @see SchemaStringVersion()
	*
	* @param string $filename AXMLS schema file
	* @return string Schema version number or FALSE on error
	*/
	function SchemaFileVersion( $filename ) {
		// Open the file
		if( !($fp = fopen( $filename, 'r' )) ) {
			// die( 'Unable to open file' );
			return FALSE;
		}
		
		// Process the file
		while( $data = fread( $fp, 4096 ) ) {
			if( preg_match( $this->versionRegex, $data, $matches ) ) {
				return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
			}
		}
		
		return FALSE;
	}
	
	/**
	* Returns the AXMLS Schema Version of the provided XML schema string.
	*
	* Call this method to obtain the AXMLS DTD version of the provided XML schema string.
	* @see SchemaFileVersion()
	*
	* @param string $xmlstring XML schema string
	* @return string Schema version number or FALSE on error
	*/
	function SchemaStringVersion( $xmlstring ) {
		if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
			return FALSE;
		}
		
		if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
			return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
		}
		
		return FALSE;
	}
	
	/**
	* Extracts an XML schema from an existing database.
	*
	* Call this method to create an XML schema string from an existing database.
	* If the data parameter is set to TRUE, AXMLS will include the data from the database
	* in the schema. 
	*
	* @param boolean $data Include data in schema dump
	* @return string Generated XML schema
	*/
	function ExtractSchema( $data = FALSE ) {
		$old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
		
		$schema = '<?xml version="1.0"?>' . "\n"
				. '<schema version="' . $this->schemaVersion . '">' . "\n";
		
		if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {
			foreach( $tables as $table ) {
				$schema .= '	<table name="' . $table . '">' . "\n";
				
				// grab details from database
				$rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );
				$fields = $this->db->MetaColumns( $table );
				$indexes = $this->db->MetaIndexes( $table );
				
				if( is_array( $fields ) ) {
					foreach( $fields as $details ) {
						$extra = '';
						$content = array();
						
						if( $details->max_length > 0 ) {
							$extra .= ' size="' . $details->max_length . '"';
						}
						
						if( $details->primary_key ) {
							$content[] = '<KEY/>';
						} elseif( $details->not_null ) {
							$content[] = '<NOTNULL/>';
						}
						
						if( $details->has_default ) {
							$content[] = '<DEFAULT value="' . $details->default_value . '"/>';
						}
						
						if( $details->auto_increment ) {
							$content[] = '<AUTOINCREMENT/>';
						}
						
						// this stops the creation of 'R' columns,
						// AUTOINCREMENT is used to create auto columns
						$details->primary_key = 0;
						$type = $rs->MetaType( $details );
						
						$schema .= '		<field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';
						
						if( !empty( $content ) ) {
							$schema .= "\n			" . implode( "\n			", $content ) . "\n		";
						}
						
						$schema .= '</field>' . "\n";
					}
				}
				
				if( is_array( $indexes ) ) {
					foreach( $indexes as $index => $details ) {
						$schema .= '		<index name="' . $index . '">' . "\n";
						
						if( $details['unique'] ) {
							$schema .= '			<UNIQUE/>' . "\n";
						}
						
						foreach( $details['columns'] as $column ) {
							$schema .= '			<col>' . $column . '</col>' . "\n";
						}
						
						$schema .= '		</index>' . "\n";
					}
				}
				
				if( $data ) {
					$rs = $this->db->Execute( 'SELECT * FROM ' . $table );
					
					if( is_object( $rs ) ) {
						$schema .= '		<data>' . "\n";
						
						while( $row = $rs->FetchRow() ) {
							foreach( $row as $key => $val ) {
								$row[$key] = htmlentities($row);
							}
							
							$schema .= '			<row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";
						}
						
						$schema .= '		</data>' . "\n";
					}
				}
				
				$schema .= '	</table>' . "\n";
			}
		}
		
		$this->db->SetFetchMode( $old_mode );
		
		$schema .= '</schema>';
		return $schema;
	}
	
	/**
	* Sets a prefix for database objects
	*
	* Call this method to set a standard prefix that will be prepended to all database tables 
	* and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
	*
	* @param string $prefix Prefix that will be prepended.
	* @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
	* @return boolean TRUE if successful, else FALSE
	*/
	function SetPrefix( $prefix = '', $underscore = TRUE ) {
		switch( TRUE ) {
			// clear prefix
			case empty( $prefix ):
				logMsg( 'Cleared prefix' );
				$this->objectPrefix = '';
				return TRUE;
			// prefix too long
			case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
			// prefix contains invalid characters
			case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
				logMsg( 'Invalid prefix: ' . $prefix );
				return FALSE;
		}
		
		if( $underscore AND substr( $prefix, -1 ) != '_' ) {
			$prefix .= '_';
		}
		
		// prefix valid
		logMsg( 'Set prefix: ' . $prefix );
		$this->objectPrefix = $prefix;
		return TRUE;
	}
	
	/**
	* Returns an object name with the current prefix prepended.
	*
	* @param string	$name Name
	* @return string	Prefixed name
	*
	* @access private
	*/
	function prefix( $name = '' ) {
		// if prefix is set
		if( !empty( $this->objectPrefix ) ) {
			// Prepend the object prefix to the table name
			// prepend after quote if used
			return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
		}
		
		// No prefix set. Use name provided.
		return $name;
	}
	
	/**
	* Checks if element references a specific platform
	*
	* @param string $platform Requested platform
	* @returns boolean TRUE if platform check succeeds
	*
	* @access private
	*/
	function supportedPlatform( $platform = NULL ) {
		$regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';
		
		if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {
			logMsg( "Platform $platform is supported" );
			return TRUE;
		} else {
			logMsg( "Platform $platform is NOT supported" );
			return FALSE;
		}
	}
	
	/**
	* Clears the array of generated SQL.
	*
	* @access private
	*/
	function clearSQL() {
		$this->sqlArray = array();
	}
	
	/**
	* Adds SQL into the SQL array.
	*
	* @param mixed $sql SQL to Add
	* @return boolean TRUE if successful, else FALSE.
	*
	* @access private
	*/	
	function addSQL( $sql = NULL ) {
		if( is_array( $sql ) ) {
			foreach( $sql as $line ) {
				$this->addSQL( $line );
			}
			
			return TRUE;
		}
		
		if( is_string( $sql ) ) {
			$this->sqlArray[] = $sql;
			
			// if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
			if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
				$saved = $this->db->debug;
				$this->db->debug = $this->debug;
				$ok = $this->db->Execute( $sql );
				$this->db->debug = $saved;
				
				if( !$ok ) {
					if( $this->debug ) {
						ADOConnection::outp( $this->db->ErrorMsg() );
					}
					
					$this->success = 1;
				}
			}
			
			return TRUE;
		}
		
		return FALSE;
	}
	
	/**
	* Gets the SQL array in the specified format.
	*
	* @param string $format Format
	* @return mixed SQL
	*	
	* @access private
	*/
	function getSQL( $format = NULL, $sqlArray = NULL ) {
		if( !is_array( $sqlArray ) ) {
			$sqlArray = $this->sqlArray;
		}
		
		if( !is_array( $sqlArray ) ) {
			return FALSE;
		}
		
		switch( strtolower( $format ) ) {
			case 'string':
			case 'text':
				return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
			case'html':
				return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
		}
		
		return $this->sqlArray;
	}
	
	/**
	* Destroys an adoSchema object.
	*
	* Call this method to clean up after an adoSchema object that is no longer in use.
	* @deprecated adoSchema now cleans up automatically.
	*/
	function Destroy() {
		set_magic_quotes_runtime( $this->mgq );
		unset( $this );
	}
}

/**
* Message logging function
*
* @access private
*/
function logMsg( $msg, $title = NULL, $force = FALSE ) {
	if( XMLS_DEBUG or $force ) {
		echo '<pre>';
		
		if( isset( $title ) ) {
			echo '<h3>' . htmlentities( $title ) . '</h3>';
		}
		
		if( is_object( $this ) ) {
			echo '[' . get_class( $this ) . '] ';
		}
		
		print_r( $msg );
		
		echo '</pre>';
	}
}
?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -