HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/PvdBoogaard/indoorski.nl/backup/oude-site/cms/lib/class.manifest.php
<?php

/**
 * Manifest
 * Class library for assisting with Manifest list generation and comparison.
 * This is meant to be portable, so several related classes are included in this file, and is coded for PHP4/5 (IWP4/5), which may cause some issues with PHP6 in future.
 *
 * @version		$Id$
 * @author		Gwilym Evans <gwilym.evans@interspire.com>
 * @package		Interspire
 * @subpackage	Manifest
 */

define('MANIFEST_RESULT_UNMODIFIED', 0);
define('MANIFEST_RESULT_NEW', 1);
define('MANIFEST_RESULT_MODIFIED', 2);
define('MANIFEST_RESULT_MISSING', 4);

/**
 * ManifestResult
 * Class for storing result information.
 *
 * @package Interspire
 * @subpackage Manifest
 */
class ManifestResult
{
	/**
	 * Relative path of file
	 *
	 * @var String
	 */
	var $path;

	/**
	 * Result, represented as a bit field of MANIFEST_RESULT_* flags
	 *
	 * @var Integer
	 */
	var $result;

	function ManifestResult ($path, $result)
	{
		$this->path = $path;
		$this->result = $result;
	}

	/**
	 * Return a string representation of the result
	 *
	 * @return String
	 */
	function resultAsString ()
	{
		$list = array();

		if ($this->result & MANIFEST_RESULT_UNMODIFIED)
			array_push($list, 'Unmodified');

		if ($this->result & MANIFEST_RESULT_NEW)
			array_push($list, 'New');

		if ($this->result & MANIFEST_RESULT_MODIFIED)
			array_push($list, 'Modified');

		if ($this->result & MANIFEST_RESULT_MISSING)
			array_push($list, 'Missing');

		return implode(', ', $list);
	}
}

/**
 * ManifestFile
 * Class for storing file information. Mainly used to represetnt a file in a data structure, rather than for file-oriented functionality.
 *
 */
class ManifestFile
{
	var $path;
	var $size;
	var $hash;

	function ManifestFile ($path, $size = 0, $hash = '')
	{
		$this->path = $path;
		$this->size = $size;
		$this->hash = $hash;
	}
}

/**
 * Manifest
 * Class containing main manifest functionality
 *
 */
class Manifest
{
	/**
	 * Default white list patterns
	 *
	 * @var Array
	 */
	var $defaultWhiteList = array('/^.*\/(\.|\.\.|cvs|\.svn|\.settings|\.cache|\.project|\.cvsignore|Thumbs\.db)$/i');

	/**
	 * Default text file extensions
	 *
	 * @var Array
	 */
	var $defaultTextExtensions = array('php', 'htm', 'html', 'tpl', 'txt', 'ini', 'js', 'css', 'htaccess', 'inc', 'log');

	/**
	 * White list patterns specific to this instance
	 *
	 * @var Array
	 */
	var $whiteList;

	/**
	 * Text extensions specific to this instance
	 *
	 * @var Array
	 */
	var $textExtensions;

	/**
	 * Directory to work from.
	 *
	 * @var String
	 */
	var $workingDirectory;

	function Manifest ()
	{
		$this->whiteList = $this->defaultWhiteList;
		$this->textExtensions = $this->defaultTextExtensions;
		$this->SetWorkingDirectory(getcwd());
	}

	/**
	 * Sets the current working (base) directory for the script, which is otherwise set to the result of getcwd()
	 *
	 * @param String $directory
	 */
	function setWorkingDirectory ($directory)
	{
		$this->workingDirectory = $directory;
	}

	/**
	 * Returns the current working directory for this Manifest instance
	 *
	 * @return String
	 */
	function getWorkingDirectory ()
	{
		return $this->workingDirectory;
	}

	/**
	 * Add an entry to this instance's text extension list
	 *
	 * @param String $extension
	 */
	function textExtensionAdd ($extension)
	{
		array_push($this->textExtensions, $extension);
	}

	/**
	 * Add an entry to this instance's white list patterns
	 *
	 * @param String $pattern
	 */
	function whiteListAdd ($pattern)
	{
		array_push($this->whiteList, $pattern);
	}

	/**
	 * Checks the given file path against this instance's white list patterns, returns true if the file is white-listed and should be ignored.
	 *
	 * @param String $check The relative file path to check.
	 * @return Boolean True if the file is white-listed and should be ignored.
	 */
	function inWhiteList ($check)
	{
		$match = false;
		foreach ($this->whiteList as $whiteItem)
		{
			if (preg_match($whiteItem, $check) > 0)
			{
				$match = true;
				break;
			}
		}
		return $match;
	}

	/**
	 * Checks the given file extension against this instance's text extension list, returns true if the extension is a known text extension
	 *
	 * @param String $ext
	 * @return Boolean True if the extension is a known text extension.
	 */
	function inTextExtensions ($ext)
	{
		return in_array($ext, $this->textExtensions);
	}

	/**
	 * Gets the file extension of a given filename / path.
	 *
	 * @param String $filename The filename or path to check.
	 * @return String The extension.
	 */
	function getFileExtension ($filename)
	{
		$pathinfo = pathinfo($filename);

		if (isset($pathinfo['extension']))
			return $pathinfo['extension'];
		else
			return '';
	}

	/**
	 * Returns the contents of a file with all line endings converted to UNIX \n line endings.
	 *
	 * @param String $filename
	 */
	function getTextFileContentsUnixLineEndings ($filename)
	{
		$contents = file_get_contents($filename);

		//	convert DOS \r\n to \n, will ignore MAC single \r
		$contents = str_replace("\r\n", "\n", $contents);

		//	convert remaining MAC \r to \n
		$contents = str_replace("\r", "\n", $contents);

		return $contents;
	}

	/**
	 * Generates a hash code
	 *
	 * @param String $filename
	 * @return String
	 */
	function generateHash ($filename)
	{
		$ext = iwp_strtolower($this->getFileExtension($filename));
		$size = filesize($filename);

		if ($size < 1048576 && $this->inTextExtensions($ext))	//	limit text files to 1mb
		{
			//	generate line-ending-neutral md5
			return md5($this->getTextFileContentsUnixLineEndings($filename));
		}
		else
		{
			//	generate binary md5
			return md5_file($filename);
		}
	}

	/**
	 * Serialize a given file list which can be unserialized with Manifest::unSerializeFileList
	 *
	 * @param Array $files
	 * @return String
	 */
	function serializeFileList (&$files)
	{
		//return serialize($files);
		$serialized = '';
		foreach ($files as $file)
		{
			$serialized .= $file->path ."\t". $file->size ."\t". $file->hash ."\n";
		}
		return $serialized;
	}

	/**
	 * Unserialize a given file list which was serialized with Manifest::serializeFileList
	 *
	 * @param String $serialized
	 * @return Array
	 */
	function unSerializeFileList ($serialized)
	{
		//return unserialize($serialized);
		$files = explode("\n", $serialized);
		foreach ($files as $index => $file)
		{
			if (!$file) {
				//	blank line, ignore and remove it
				unset($files[$index]);
				continue;
			}
			$row = explode("\t", $file);
			$files[$index] = new ManifestFile($row[0], intval($row[1]), $row[2]);
		}
		return $files;
	}

	/**
	 * Loads a file list from a given URL, unserializing it via UnSerializeFileList in the process
	 *
	 * @param String $uri Filename or URL of serialized file list.
	 * @return Array Array of ManifestFile objects
	 */
	function loadFileList ($url)
	{
		$serialized = '';

		if (ini_get('allow_url_fopen')) {
			//	try fopen-style stuff
			if (function_exists('file_get_contents')) {
				$serialized = file_get_contents($url);
			}
		} else if (function_exists('curl_init')) {
			//	try CURL
			$ch = curl_init($url);
			curl_setopt($ch, CURLOPT_HEADER, 0);
			ob_start();
			curl_exec($ch);
			curl_close($ch);
			$serialized = ob_get_contents();
			ob_end_clean();
		}

		if (!$serialized) {
			//	fall back to local stuff if it exists
			if (file_exists('manifest.txt')) {
				if (function_exists('file_get_contents')) {
					$serialized = file_get_contents('manifest.txt');
				}
			}
		}

		if (!$serialized) {
			die('loading file list from '. $url .' failed.');
		}

		return $this->unSerializeFileList($serialized);
	}

	/**
	 * Compares two file lists, returning an array of ManifestResult objects
	 *
	 * @param Array $mine File list array representing local manifest (subject for comparison)
	 * @param Array $theirs File list array representing 'standard' manifest (to be compared to)
	 */
	function compareFileLists ($mine, &$theirs)
	{
		$results = array();

		foreach ($theirs as $file)
		{
			$result = 0;



			if (isset($mine[$file->path]))
			{
				if ($file->hash == $mine[$file->path]->hash)
				{
					$result |= MANIFEST_RESULT_UNMODIFIED;
				}
				else
				{
					$result |= MANIFEST_RESULT_MODIFIED;
				}

				unset($mine[$file->path]);
			}
			else
			{
				$result |= MANIFEST_RESULT_MISSING;
			}

			if ($result)
				$results[$file->path] = new ManifestResult($file->path, $result);
		}

		foreach ($mine as $file)
		{
			 $results[$file->path] = new ManifestResult($file->path, MANIFEST_RESULT_NEW);
		}

		ksort($results);
		return $results;
	}

	/**
	 * Generates an array of ManifestFile objects populated with data for the current working directory.
	 *
	 * @param Boolean $ignoreWhiteList Set this to ignore the whitelist
	 * @return Array Array of ManifestFile objects
	 */
	function generateFileList ($ignoreWhiteList = false, $generateHashes = true)
	{
		$base = $this->workingDirectory;	//	base working directory
		$subdirectories = array('/');		//	subdirectory stack to check
		$files = array();					//	storage for list of files

		while (count($subdirectories))
		{
			$subdirectory = array_shift($subdirectories);
			$directoryPath = $base . $subdirectory;
			$directoryHandle = opendir($directoryPath);

			while (false !== ($fileName = readdir($directoryHandle)))
			{
				$fileRelativePath = $subdirectory . $fileName;
				$fileAbsolutePath = $directoryPath . $fileName;
				$fileIsDirectory = is_dir($fileAbsolutePath);

				if ($this->inWhiteList($fileRelativePath))
					continue;

				if ($fileIsDirectory)
				{
					array_push($subdirectories, $fileRelativePath .'/');
					continue;
				}

				$fileSize = filesize($fileAbsolutePath);
				$fileHash = $generateHashes ? $this->generateHash($fileAbsolutePath) : '';
				$files[$fileRelativePath] = new ManifestFile($fileRelativePath, $fileSize, $fileHash);
			}

    		closedir($directoryHandle);
		}

		ksort($files);
		return $files;
	}
}