Location: PHPKode > projects > Sierra-php PHP Application Framework > sierra/lib/model/SRA_FileAttribute.php
<?php
// {{{ Header
/*
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | SIERRA : PHP Application Framework  http://code.google.com/p/sierra-php |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | Copyright 2005 Jason Read                                               |
 |                                                                         |
 | Licensed under the Apache License, Version 2.0 (the "License");         |
 | you may not use this file except in compliance with the License.        |
 | You may obtain a copy of the License at                                 |
 |                                                                         |
 |     http://www.apache.org/licenses/LICENSE-2.0                          |
 |                                                                         |
 | Unless required by applicable law or agreed to in writing, software     |
 | distributed under the License is distributed on an "AS IS" BASIS,       |
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.|
 | See the License for the specific language governing permissions and     |
 | limitations under the License.                                          |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 */
// }}}

// {{{ Imports

// }}}

// {{{ Constants
/**
 * the default decimal precision for the getSize* methods
 * @type int
 */
define('SRA_FILE_ATTRUBTE_DECIMAL_PRECISION', 2);

/**
 * identifies the "db" "file-handling" method
 * @type string
 */
define('SRA_FILE_ATTRIBUTE_TYPE_DB', 'db');

/**
 * identifies the "dir" "file-handling" method
 * @type string
 */
define('SRA_FILE_ATTRIBUTE_TYPE_DIR', 'dir');

/**
 * prefix for encrypted ids
 * @type string
 */
define('SRA_FILE_ATTRIBUTE_EID_PREFIX', 'sfa://');

/**
 * prefix to identify files that have been reset (will be automatically deleted 
 * when getInstanceFromEncryptedId is invoked (applies only when _fileHandling 
 * is SRA_FILE_ATTRIBUTE_TYPE_DIR)
 * @type string
 */
define('SRA_FILE_ATTRIBUTE_EID_REMOVE_PREFIX', 'REMOVE');

/**
 * the name of the ImageMagick "convert" cli utility used by the "resizeImage" 
 * and "toThumbnail" methods. in order to use those methods, ImageMagick must 
 * be installed and this utility must be present in the $PATH
 * @type string
 */
define('SRA_FILE_ATTRIBUTE_IMAGE_MAGICK_CONVERT', 'convert');
// }}}

// {{{ SRA_FileAttribute
/**
 * Used to represent an entity model "is-file" attribute. for more information, 
 * see the "entity-model_1_0.dtd". 
 * 
 * @author  Jason Read <hide@address.com>
 * @package sierra.model
 */
class SRA_FileAttribute {
  // {{{ Attributes
  // public attributes
	/**
	 * the app key that this SRA_FileAttribute belongs to
	 * @type string
	 * @access private
	 */
	var $_app;
  
	/**
	 * the name of the attribute that this SRA_FileAttribute belongs to
	 * @type string
	 * @access private
	 */
	var $_attribute;
	
	/**
	 * the attribute index for this SRA_FileAttribute (only applicable if the 
	 * attribute is an array)
	 * @type string
	 * @access private
	 */
	var $_attributeIndex;
	
	/**
	 * byte array representation of the file (only appies to files that are stored 
	 * in the database). cannot be set through instantiation.
	 * @type byte[]
	 * @access private
	 */
	var $_bytes;
  
	/**
	 * an optional custom uri for this file (use setCustomUri to set)
	 * @type string
	 * @access private
	 */
	var $_customUri;
	
	/**
	 * the name of the entity that this SRA_FileAttribute belongs to
	 * @type string
	 * @access private
	 */
	var $_entity;
	
	/**
	 * the id of the entity that this SRA_FileAttribute belongs to
	 * @type string
	 * @access private
	 */
	var $_entityId;
	
	/**
	 * if the SRA_FILE_ATTRIBUTE_TYPE_DIR file handling method is used, 
	 * specifies the directory where files should be stored
	 * for more information, see the documentation provided in entity-model_1_0.dtd
	 * @type string
	 * @access private
	 */
	var $_fileDir;
	
	/**
	 * if the SRA_FILE_ATTRIBUTE_TYPE_DIR file handling method is used, 
	 * specifies the uri where files should be referenced from the web server
	 * for more information, see the documentation provided in entity-model_1_0.dtd
	 * @type string
	 * @access private
	 */
	var $_fileDirUri;
	
	/**
	 * determines how this file attribute will be stored. will correspond with 
	 * one of the SRA_FILE_ATTRIBUTE_TYPE_* constants for more information, see 
	 * the documentation provided in entity-model_1_0.dtd
	 * @type string
	 * @access private
	 */
	var $_fileHandling;
	
	/**
	 * whether or not the _fileScriptUri should be rendered as an Apache RewriteRule
	 * for more information, see the documentation provided in entity-model_1_0.dtd
	 * @type string
	 * @access private
	 */
	var $_fileScriptRewrite;
	
	/**
	 * if the SRA_FILE_ATTRIBUTE_TYPE_DB file handling method is used, 
	 * specifies the Uri to the file-renderer.php script
	 * for more information, see the documentation provided in entity-model_1_0.dtd
	 * @type string
	 * @access private
	 */
	var $_fileScriptUri;
	
	/**
	 * the actual name of the file if the SRA_FILE_ATTRIBUTE_TYPE_DIR 
	 * file handling method is used, or a browser friendly name if the 
	 * SRA_FILE_ATTRIBUTE_TYPE_DB file handling method is used.
	 * @type string
	 * @access private
	 */
	var $_fileName;
  
	/**
	 * set this attribute to force this file attribute to use this file path to 
   * retrieve the file bytes (may be remote)
	 * @type string
	 * @access private
	 */
	var $_hardPath;
	
	/**
	 * whether or not existing database SRA_FileAttribute properties have been 
	 * initialized
	 * @type boolean
	 * @access private
	 */
	var $_initialized = FALSE;
	
	/**
	 * the original name of the file that was uploaded (if file was added from an 
	 * uploaded form)
	 * @type string
	 * @access private
	 */
	var $_name;
	
	/**
	 * whether or not the SRA_FileAttribute is new (new SRA_FileAttributes have not been 
	 * committed to the database or file system)
	 * @type boolean
	 * @access private
	 */
	var $_new = FALSE;
	
	/**
	 * the size, in bytes, of the file
	 * @type string
	 * @access private
	 */
	var $_size;
	
	/**
	 * the sql that can be performed on the $_db to return the attributes 
	 * associated with this SRA_FileAttribute. this query will be executed the 
	 * first time that the $_bytes, $_fileName, $_name, or $_size attributes 
	 * are requested through their corresponding getter methods
	 * @type string
	 * @access private
	 */
	var $_sql;
	
	/**
	 * the mime type of the file if the browser provided this information in the 
	 * original file upload
	 * @type string
	 * @access private
	 */
	var $_type;
  
	// private attributes	
	// }}}
  
	// {{{ Operations
	// constructor(s)
	// {{{ SRA_FileAttribute
	/**
	 * Instantiates a new instance of this object with the initial given 
	 * attributes
	 * @access  public
	 */
	function SRA_FileAttribute($fileName = NULL, $name = NULL, $size = NULL, $type = NULL, $new = NULL) {
		$this->setFileName($fileName);
		$this->setName($name);
		$this->setSize($size);
		$this->setType($type);
		$this->_setNew($new);
    $this->_app = SRA_Controller::getCurrentAppId();
	}
	// }}}
	
	
	// public operations
	// {{{ copy
	/**
	 * copies this file attribute
	 * @access  public
	 * @return SRA_FileAttribute
	 */
	function & copy() {
		return SRA_Util::copyObject($this);
	}
	// }}}
  
	// {{{ delete
	/**
	 * deletes the file represented by this SRA_FileAttribute instance IF the 
	 * _fileHandling is SRA_FILE_ATTRIBUTE_TYPE_DIR and the _fileName exists
	 * @access  public
	 * @return boolean TRUE on success, FALSE otherwise
	 */
	function delete() {
		if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DIR && file_exists($this->_fileName)) {
			unlink($this->_fileName);
			return TRUE;
		}
		return FALSE;
	}
	// }}}
	
	// {{{ equals
	/**
	 * Returns TRUE if this SRA_FileAttribute references the same file as the 
	 * $fileAttr parameter
	 * @param SRA_FileAttribute $fileAttr
	 * @access  public
	 * @return string
	 */
	function equals(& $fileAttr) {
		if (SRA_FileAttribute::isValid($fileAttr) && $this->getEncryptedId() == $fileAttr->getEncryptedId()) {
			return TRUE;
		}
		return FALSE;
	}
	// }}}
	
	// {{{ getApp
	/**
	 * Returns the _app attribute
	 * @access  public
	 * @return string
	 */
	function getApp() {
		return $this->_app;
	}
	// }}}
  
	// {{{ getAttribute
	/**
	 * Returns the _attribute attribute
	 * @access  public
	 * @return string
	 */
	function getAttribute() {
		return $this->_attribute;
	}
	// }}}
	
	// {{{ getAttributeIndex
	/**
	 * Returns the _attributeIndex attributeIndex
	 * @access  public
	 * @return string
	 */
	function getAttributeIndex() {
		return $this->_attributeIndex;
	}
	// }}}
	
	// {{{ getBytes
	/**
	 * Returns the _bytes attribute (returned by reference)
	 * @access  public
	 * @return byte[]
	 */
	function & getBytes() {
		$this->_init();
    if ($this->_hardPath && !isset($this->_bytes)) {
      $this->_bytes = file_get_contents($this->_hardPath);
    }
		return $this->_bytes;
	}
	// }}}
	
	// {{{ getData
	/**
	 * Returns an appropriately serialized version of this SRA_FileAttribute which 
	 * can be stored in the database column for the attribute that it pertains to. 
	 * Returns an SRA_Error object, if unsuccessful
	 * @param string $fileHandling see the $_fileHandling api comments (REQUIRED 
	 * if not already set)
	 * @param string $fileDir see the $_fileDir api comments (REQUIRED for 
	 * SRA_FILE_ATTRIBUTE_TYPE_DIR type SRA_FileAttribute instances if not already 
	 * set)
	 * @access  public
	 */
	function & getData($fileHandling = FALSE, $fileDir = FALSE) {
		if ($fileHandling) {
			$this->_setFileHandling($fileHandling);
		}
		if ($fileDir) {
			$this->_setFileDir($fileDir);
		}
		// new SRA_FileAttribute
		if ($this->isNew()) {
			if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DB) {
				if (file_exists($this->getFileName()) && is_readable($this->getFileName()) && !$this->_bytes) {
					$fp = fopen($this->getFileName(), 'rb');
					$this->_bytes = fread($fp, $this->getSize());
          $this->setSize(strlen($this->_bytes));
					fclose($fp);
				}
				else if (!$this->_bytes) {
					$msg = 'SRA_FileAttribute::getData: Failed - No _bytes exist for this file';
					return SRA_Error::logError($msg, __FILE__, __LINE__);
				}
			}
			// copy file to correct storage directory if necessary
			else if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DIR) {
				if (file_exists($this->getFileName()) && is_readable($this->getFileName()) && is_writable($this->_fileDir)) {
					$newFile = SRA_File::createRandomFile($this->_fileDir, SRA_Util::getFileNameWOExtension($this->getName(), TRUE), '.' . SRA_Util::getFileExtension($this->getName(), TRUE));
					SRA_File::move($this->getFileName(), $newFile);
					$this->_fileName = $newFile;
				}
				else {
					$msg = 'SRA_FileAttribute::getData: Failed - Either file does not exist or is not readable: ' . $this->getFileName() . ' or directory is not writable: ' . $this->_fileDir ;
					return SRA_Error::logError($msg, __FILE__, __LINE__);
				}
			}
			$this->_setNew(FALSE);
		}
		// existing SRA_FileAttribute
		else {
			$this->_init();
		}
		return serialize($this);
	}
	// }}}
	
	// {{{ getAppDbData
	/**
	 * Returns the data for this SRA_FileAttribute properly converted for insertion 
	 * into the current app database
	 * @access  public
	 * @return string
	 */
	function & getAppDbData(& $db) {
		if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DB) {
			return $db->convertBlob($this->getData());
		}
		else if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DIR) {
			return $db->convertText($this->getData());
		}
    
		return FALSE;
	}
	// }}}
	
	// {{{ getAppDbDataType
	/**
	 * Returns the correct database data type for this SRA_FileAttribute. This is 
	 * SRA_DATA_TYPE_BLOB if the _fileHandling is SRA_FILE_ATTRIBUTE_TYPE_DB 
	 * and SRA_DATA_TYPE_STRING if the _fileHandling is 
	 * SRA_FILE_ATTRIBUTE_TYPE_DIR
	 * @access  public
	 * @return string
	 */
	function getAppDbDataType() {
		if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DB) {
			return SRA_DATA_TYPE_BLOB;
		}
		else if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DIR) {
			return SRA_DATA_TYPE_STRING;
		}
		return FALSE;
	}
	// }}}
	
	// {{{ getEncryptedId
	/**
	 * Returns a unique encrypted identifier for this file attribute if the 
	 * SRA_FILE_ATTRIBUTE_TYPE_DB file handling method is used
   * @param boolean $encode whether or not to url encode the ecrypted id
	 * @access  public
	 * @return string
	 */
	function getEncryptedId($encode=TRUE) {
		$str = base64_encode(SRA_FILE_ATTRIBUTE_EID_PREFIX . $this->_app . '>' . $this->_entity . '>' . $this->_entityId . '>' . $this->_attribute . '>' . $this->_attributeIndex . '>' . $this->_fileDir . '>' . $this->_fileDirUri . '>' . $this->_fileHandling . '>' . $this->_fileName . '>' . $this->_size . '>' . $this->_type);
    return $encode ? urlencode($str) : $str;
	}
	// }}}
	
	// {{{ getEntity
	/**
	 * Returns the _entity entity
	 * @access  public
	 * @return string
	 */
	function getEntity() {
		return $this->_entity;
	}
	// }}}
	
	// {{{ getEntityId
	/**
	 * Returns the _entityId entityId
	 * @access  public
	 * @return string
	 */
	function getEntityId() {
		return $this->_entityId;
	}
	// }}}
	
	// {{{ getFileExtension
	/**
	 * Returns the file extension for this file
	 * @access  public
	 * @return string
	 */
	function getFileExtension() {
		if (strstr($this->getFileName(), '.')) {
			return SRA_Util::getFileExtension($this->getFileName());
		}
		else if (strstr($this->getName(), '.')){
			return SRA_Util::getFileExtension($this->getName());
		}
		return FALSE;
	}
	// }}}
	
	// {{{ getFileDir
	/**
	 * Returns the file extension for this file
	 * @access  public
	 * @return string
	 */
	function getFileDir() {
		return $this->_fileDir;
	}
	// }}}
	
	// {{{ getFileDirUri
	/**
	 * Returns the file extension for this file
	 * @access  public
	 * @return string
	 */
	function getFileDirUri() {
		return $this->_fileDirUri;
	}
	// }}}
	
	// {{{ getFileHandling
	/**
	 * Returns the file extension for this file
	 * @access  public
	 * @return string
	 */
	function getFileHandling() {
		return $this->_fileHandling;
	}
	// }}}
	
	// {{{ getFileScriptUri
	/**
	 * Returns the file extension for this file
	 * @access  public
	 * @return string
	 */
	function getFileScriptUri() {
		return $this->_fileScriptUri;
	}
	// }}}
	
	// {{{ getFileName
	/**
	 * Returns the _fileName attribute
	 * @access  public
	 * @return string
	 */
	function getFileName() {
		$this->_init();
		return $this->_fileName;
	}
	// }}}
  
	// {{{ getHardPath
	/**
	 * Returns the _hardPath attribute
	 * @access  public
	 * @return string
	 */
	function getHardPath() {
		return $this->_hardPath;
	}
	// }}}
  
	// {{{ getIcon
	/**
	 * returns the full path to the icon to use for this file based on it's mime 
   * type if found in $baseDir. this algorithm uses the following search order:
   *  1) check for [file extension].(png|jpg|gif)
   *  2) explode mimeType on '/', lowercase both pieces and remove leading 'x-'
   *  3) check for mimeType[1].(png|jpg|gif)
   *  4) check for mimeType[0].(png|jpg|gif)
   *  5) check for source_[file extension].(png|jpg|gif)
   *  6) remove trailing 's' from extension if applicable and check for source_[file extension].(png|jpg|gif)
   *  6) return NULL
   * @param string $baseDir the base directory containing the icon images. this 
   * directory may be either absolute or app relative
	 * @access  public
	 * @return string
	 */
	function getIcon($baseDir) {
    // convert app relative directory
    if (!file_exists($baseDir) && file_exists(SRA_Controller::getAppDir() . '/' . $baseDir)) { $baseDir = SRA_Controller::getAppDir() . '/' . $baseDir; }
    
    $ext = strtolower(SRA_Util::getFileExtension($this->getName()));
    $mimePieces = explode('/', $this->getType());
    if (count($mimePieces) == 2) {
      $mimePieces[0] = strtolower($mimePieces[0]);
      $mimePieces[1] = str_replace('x-', '', strtolower($mimePieces[1]));
    }
    else {
      $mimePieces = NULL;
    }
    $baseDir = SRA_Util::endsWith($baseDir, '/') ? $baseDir : $baseDir . '/';
    $file = $ext ? (file_exists($baseDir . $ext . '.png') ? $baseDir . $ext . '.png' : (file_exists($baseDir . $ext . '.jpg') ? $baseDir . $ext . '.jpg' : (file_exists($baseDir . $ext . '.gif') ? $baseDir . $ext . '.gif' : NULL))) : NULL;
    $file = !$file && $mimePieces ? (file_exists($baseDir . $mimePieces[1] . '.png') ? $baseDir . $mimePieces[1] . '.png' : (file_exists($baseDir . $mimePieces[1] . '.jpg') ? $baseDir . $mimePieces[1] . '.jpg' : (file_exists($baseDir . $mimePieces[1] . '.gif') ? $baseDir . $mimePieces[1] . '.gif' : NULL))) : $file;
    $file = !$file && $mimePieces ? (file_exists($baseDir . $mimePieces[0] . '.png') ? $baseDir . $mimePieces[0] . '.png' : (file_exists($baseDir . $mimePieces[0] . '.jpg') ? $baseDir . $mimePieces[0] . '.jpg' : (file_exists($baseDir . $mimePieces[0] . '.gif') ? $baseDir . $mimePieces[0] . '.gif' : NULL))) : $file;
    $file = !$file && $ext ? (file_exists($baseDir . 'source_' . $ext . '.png') ? $baseDir . 'source_' . $ext . '.png' : (file_exists($baseDir . 'source_' . $ext . '.jpg') ? $baseDir . 'source_' . $ext . '.jpg' : (file_exists($baseDir . 'source_' . $ext . '.gif') ? $baseDir . 'source_' . $ext . '.gif' : NULL))) : $file;
    $ext = !$file && SRA_Util::endsWith($ext, 's') ? substr($ext, 0, -1) : $ext;
    $file = !$file && $ext ? (file_exists($baseDir . 'source_' . $ext . '.png') ? $baseDir . 'source_' . $ext . '.png' : (file_exists($baseDir . 'source_' . $ext . '.jpg') ? $baseDir . 'source_' . $ext . '.jpg' : (file_exists($baseDir . 'source_' . $ext . '.gif') ? $baseDir . 'source_' . $ext . '.gif' : NULL))) : $file;
    $file = !$file ? (file_exists($baseDir . 'unknown.png') ? $baseDir . 'unknown.png' : (file_exists($baseDir . 'unknown.jpg') ? $baseDir . 'unknown.jpg' : (file_exists($baseDir . 'unknown.gif') ? $baseDir . 'unknown.gif' : NULL))) : $file;
    return $file;
	}
	// }}}
	
	// {{{ getName
	/**
	 * Returns the _name attribute
	 * @access  public
	 * @return string
	 */
	function getName() {
		$this->_init();
		return $this->_name;
	}
	// }}}
	
	// {{{ getSize
	/**
	 * Returns the _size attribute
	 * @access public
	 * @return int
	 */
	function getSize() {
		if (method_exists($this, '_init')) { $this->_init(); }
		return $this->_size;
	}
	// }}}
	
	// {{{ getSizeKb
	/**
	 * Returns the size of the file in KB
	 * @param int $decimalPrecision the decimal precision for the return value
   * @param float $size this method can be invoked statically by specifying this 
   * parameter which is the size in bytes
   * @access public
	 * @return float
	 */
	function getSizeKb($decimalPrecision = SRA_FILE_ATTRUBTE_DECIMAL_PRECISION, $size=NULL) {
    $size = isset($size) ? $size : (method_exists($this, 'getSize') ? $this->getSize() : NULL);
		return number_format($size/1024, $decimalPrecision);
	}
	// }}}
  
	// {{{ getSizeLabel
	/**
	 * returns the size label to use for this file attribute (or for $size if size
   * is specified). this label will be in gigabytes if > 1 gigabytes, megabytes 
   * if > 1 megabytes, kilobytes if > 1 kilobytes or bytes otherwise
	 * @param int $decimalPrecision the decimal precision for the return value
   * @param float $size this method can be invoked statically by specifying this 
   * parameter which is the size in bytes
	 * @access public
	 * @return string
	 */
	function getSizeLabel($decimalPrecision = SRA_FILE_ATTRUBTE_DECIMAL_PRECISION, $size=NULL) {
		$resources =& SRA_Controller::getSysResources();
    $size = isset($size) ? $size : (method_exists($this, 'getSize') ? $this->getSize() : NULL);
    $label = $size . ' ' . $resources->getString('text.size.bytes');
    if (($gb = SRA_FileAttribute::getSizeGb($decimalPrecision, $size)) > 1) {
      $label = $gb . ' ' . $resources->getString('text.size.gigabytes');
    }
    else if (($mb = SRA_FileAttribute::getSizeMb($decimalPrecision, $size)) > 1) {
      $label = $mb . ' ' . $resources->getString('text.size.megabytes');
    }
    else if (($kb = SRA_FileAttribute::getSizeKb($decimalPrecision, $size)) > 1) {
      $label = $kb . ' ' . $resources->getString('text.size.kilobytes');
    }
    return $label;
	}
	// }}}
	
	// {{{ getSizeMb
	/**
	 * Returns the size of the file in MB
	 * @param int $decimalPrecision the decimal precision for the return value
   * @param float $size this method can be invoked statically by specifying this 
   * parameter which is the size in bytes
	 * @access public
	 * @return float
	 */
	function getSizeMb($decimalPrecision = SRA_FILE_ATTRUBTE_DECIMAL_PRECISION, $size=NULL) {
    $size = isset($size) ? $size : (method_exists($this, 'getSize') ? $this->getSize() : NULL);
		return number_format($size/1048576, $decimalPrecision);
	}
	// }}}
  
	// {{{ getSizeGb
	/**
	 * Returns the size of the file in GB
	 * @param int $decimalPrecision the decimal precision for the return value
   * @param float $size this method can be invoked statically by specifying this 
   * parameter which is the size in bytes
	 * @access public
	 * @return float
	 */
	function getSizeGb($decimalPrecision = SRA_FILE_ATTRUBTE_DECIMAL_PRECISION, $size=NULL) {
    $size = isset($size) ? $size : (method_exists($this, 'getSize') ? $this->getSize() : NULL);
		return number_format($size/1073741824, $decimalPrecision);
	}
	// }}}
	
	// {{{ getSql
	/**
	 * Returns the _sql attribute
	 * @access  public
	 * @return string
	 */
	function getSql() {
		return $this->_sql;
	}
	// }}}
	
	// {{{ getType
	/**
	 * Returns the _type attribute
	 * @access  public
	 * @return string
	 */
	function getType() {
		$this->_init();
		return $this->_type;
	}
	// }}}
	
	// {{{ getUri
	/**
	 * Returns the _uri attribute
	 * @access  public
	 * @return string
	 */
	function getUri() {
    if ($this->_customUri) {
      return $this->_customUri;
    }
		else if (!$this->isNew()) {
			// uri is to file-renderer.php wo/ RewriteRule script
			if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DB && !$this->isFileScriptRewrite()) {
				return $this->_fileScriptUri . '/?eid=' . $this->getEncryptedId() . '/' . $this->getName();
			}
			// uri is to file-renderer.php w/ RewriteRule script
			if ($this->_fileHandling == SRA_FILE_ATTRIBUTE_TYPE_DB) {
				return $this->_fileScriptUri . '/' . $this->getEncryptedId() . '/' . $this->getName();
			}
			// uri is to actual file
			else {
				return $this->_fileDirUri . '/' . basename($this->getFileName());
			}
		}
		return FALSE;
	}
	// }}}
	
	// {{{ isFileScriptRewrite
	/**
	 * Returns the _fileScriptRewrite attribute
	 * @access  public
	 * @return boolean
	 */
	function isFileScriptRewrite() {
		return $this->_fileScriptRewrite;
	}
	// }}}
  
	// {{{ isImage
	/**
	 * Returns true if this file has an image mime type
	 * @access  public
	 * @return boolean
	 */
	function isImage() {
		return SRA_Util::beginsWith($this->getType(), 'image');
	}
	// }}}
	
	// {{{ isNew
	/**
	 * Returns the _new attribute
	 * @access  public
	 * @return boolean
	 */
	function isNew() {
		return $this->_new;
	}
	// }}}
  
	// {{{ isText
	/**
	 * Returns true if this file has a text mime type
	 * @access  public
	 * @return boolean
	 */
	function isText() {
		return SRA_Util::beginsWith($this->getType(), 'text');
	}
	// }}}
  
	// {{{ resizeImage
	/**
	 * if this file attribute represents an image, this method may be used to 
   * resize that image. in order to use this functionality, ImageMagick must be 
   * installed and executable (see SRA_FILE_ATTRIBUTE_IMAGE_MAGICK_CONVERT 
   * constant). at least 1, $height or $width must be specified. the return 
   * value will be the path to a temp file stored the resized image
	 * @param int $height the height of the thumbnail to generate
   * @param int $width the width of the thumbnail to generate
   * @param boolean $preserveAspect whether or not to preserve the aspect ratio 
   * when the resized image is created. if false, and both height and width are 
   * specified, the resized image will be modified in such a way to create the 
   * aspect ratio prescribed by those dimensions
	 * @access  public
	 * @return string
	 */
	function resizeImage($height, $width, $preserveAspect=TRUE) {
    if (($height || $width) && $this->isImage() && ($imageMagick = SRA_File::findInPath(SRA_FILE_ATTRIBUTE_IMAGE_MAGICK_CONVERT))) {
      $inputFile = SRA_File::createRandomFile(NULL, '', '.' . SRA_Util::getFileExtension($this->getName()));
      $outputFile = SRA_File::createRandomFile(NULL, '', '.' . SRA_Util::getFileExtension($this->getName()));
      $this->writeToFile($inputFile);
      
      $cmd = $imageMagick . ' -resize ' . ($width ? $width : '1600') . 'x' . ($height ? $height : '1200') . (!$preserveAspect ? '\!' : '') . ' ' . $inputFile . "\\'[0]\\'" . ' ' . $outputFile;
      system($cmd);
      
      SRA_File::unlink($inputFile);
      return $outputFile;
    }
	}
	// }}}
	
	// {{{ setBytes
	/**
	 * Sets the _bytes attribute
	 * @param string $bytes the bytes attribute to set (passed by reference)
	 * @access  public
	 * @return void
	 */
	function setBytes(& $bytes) {
		$this->_bytes =& $bytes;
	}
	// }}}
  
	// {{{ setCustomUri
	/**
	 * this method can be used to set a custom uri for this file
	 * @param string $uri the uri to set
	 * @access public
	 * @return void
	 */
	function setCustomUri($uri) {
		$this->_customUri = $uri;
	}
	// }}}
	
	// {{{ setFileName
	/**
	 * Sets the _fileName attribute
	 * @param string $fileName the fileName attribute to set
	 * @access  public
	 * @return void
	 */
	function setFileName($fileName) {
		$this->_fileName = $fileName;
	}
	// }}}
  
	// {{{ setHardPath
	/**
	 * sets a custom hard path for this file attribute. when set, this file will 
   * be used when the bytes are retrieved
	 * @param string $hardPath the path to set - may be remote
	 * @access public
	 * @return void
	 */
	function setHardPath($hardPath) {
		$this->_hardPath = $hardPath;
	}
	// }}}
	
	// {{{ setName
	/**
	 * Sets the _name attribute
	 * @param string $name the name attribute to set
	 * @access  public
	 * @return void
	 */
	function setName($name) {
		$this->_name = $name;
	}
	// }}}
	
	// {{{ setSize
	/**
	 * Sets the _size attribute
	 * @param int $size the size attribute to set
	 * @access  public
	 * @return void
	 */
	function setSize($size) {
		$this->_size = $size;
	}
	// }}}
	
	// {{{ setType
	/**
	 * Sets the _type attribute
	 * @param string $type the type attribute to set
	 * @access  public
	 * @return void
	 */
	function setType($type) {
		$this->_type = $type;
	}
	// }}}
  
	// {{{ toText
	/**
	 * this method is used to convert this file attribute to an indexable text 
   * representation when it is possible to do so. if a file uses a "text/*" 
   * mime-type (and that mime-type does not have a custom converter defined) the 
   * contents of that file will be returned directly. other mime-types require 
   * custom text converters. these can be defined in sierra-config.xml using the 
   * "param" element where the type is "file-converter", the id is a space 
   * separated list of mime-types supported by that converter (as defined in 
   * /etc/mime.types), and the value is the cli command for invoking that 
   * converter containing 2 tokens. the first is "${input}" which is the name of 
   * the file being input (STDIN is not supported) to the converter (a temp file 
   * created when this method is invoked), and the second is "${output}" which 
   * is the name of a temporary output file that the text will be written to 
   * (STDOUT is not supported, use > if the converter application does not 
   * support direct file output). When this method is invoked and a valid 
   * converter is found, the file will first be written to a temp file, an 
   * output file will be created, the converter will be invoked, and the output 
   * of that converter will be returned (both temp files are also deleted). 
   * these are a few examples of text converters defined in sierra-config.xml:
   *  <!-- PDF conversion using Xpdf (http://www.foolabs.com/xpdf/) -->
   *  <param id="application/pdf" type="file-converter" value="/usr/local/bin/pdftotext ${input} ${output}" />
	 * @access  public
	 * @return string
	 */
	function & toText() {
    if ($this->_type) {
      $converters = SRA_Controller::getSysParams(NULL, 'file-converter');
      foreach($converters as $mimeTypes => $converter) {
        $mimeTypes = explode(' ', $mimeTypes);
        if (in_array($this->_type, $mimeTypes)) {
          $input = SRA_File::createRandomFile();
          $this->writeToFile($input);
          $output = SRA_File::createRandomFile();
          $cmd = str_replace('${output}', $output, str_replace('${input}', $input, $converter));
          system($cmd);
          $text =& SRA_File::toString($output);
          SRA_File::unlink($input);
          SRA_File::unlink($output);
          return $text;
        }
      }
      // text mime type
      if (SRA_Util::beginsWith($this->_type, 'text/', FALSE)) {
        return $this->getBytes();
      }
    }
    $es = '';
    return $es;
	}
	// }}}
  
	// {{{ toThumbnail
	/**
	 * used to create a thumbnail image representation of this file where 
   * supported. in order to use this method, the ImageMagick utility 
   * SRA_FILE_ATTRIBUTE_IMAGE_MAGICK_CONVERT must be found in the path. 
   * Additionally, the file mime-type must be supported for conversion. the 
   * supported types include the image formats listed at 
   * http://www.imagemagick.org/script/formats.php as well as any other formats 
   * that can be converted to a supported format by a custom converter. These 
   * converters can be defined in sierra-config.xml using the "param" element 
   * where the type is "thumbnail-converter", the id is a space separated list 
   * of mime-types supported by that converter (as defined in /etc/mime.types), 
   * and the value is the cli command for invoking that converter containing 2 
   * tokens. the first is "${input}" which is the name of the original file  
   * (STDIN is not supported) for the converter (a temp file created when this 
   * method is invoked), and the second is "${output}" which is the name of a 
   * temporary output file that the new file will be written to (STDOUT is not 
   * supported, use > if the converter application does not support direct file 
   * output). if both height and width are specific, the aspect ratio of the 
   * source file may be changed as the resulting thumbnail will be generated 
   * using those exact dimensions. if either $height or $width or specified, 
   * then that will be the exact size for that dimension while the opposite 
   * dimension will be proportional according to the aspect ratio. at least 1, 
   * $height or $width MUST be provided. if multiple thumbnails are generated 
   * (i.e. if the file is a pdf will multiple pages), then the return value 
   * will be an array of file paths. otherwise, when successful a single file 
   * path will be returned. if a thumbnail could not be created, NULL will be 
   * returned
   * 
	 * @param int $height the height of the thumbnail to generate
   * @param int $width the width of the thumbnail to generate
   * @param string $format the format of the thumbnail to create. the default 
   * format is 'png'. alternate formats include 'gif', 'jpg' and any other 
   * output format (identified by it's file extension) supported by ImageMagick
   * @param boolean $preserveAspect whether or not to preserve the aspect ratio 
   * when the thumbnail is created. if false, and both height and width are 
   * specified, the thumbnail image will be modified in such a way to create the 
   * aspect ratio prescribed by those dimensions
   * @param array $includeTypes an array of regular expressions defining the 
   * mime-types for which thumbnails are allowed. if this file mime-type is not 
   * in that array, no thumbnail will be created
   * @param array $skipTypes an array of regular expressions defining the 
   * mime-types for which thumbnails are NOT allowed. if this file mime-type is  
   * in that array, no thumbnail will be created
	 * @access  public
	 * @return mixed
	 */
	function toThumbnail($height, $width, $format='png', $preserveAspect=TRUE, $includeTypes=NULL, $skipTypes=NULL) {
    $include = TRUE;
    if ($includeTypes) {
      $include = FALSE;
      foreach($includeTypes as $match) {
        if (ereg($match, $this->_type)) {
          $include = TRUE;
          break;
        }
      }
    }
    if ($skipTypes) {
      foreach($skipTypes as $match) {
        if (ereg($match, $this->_type)) {
          $include = FALSE;
          break;
        }
      }
    }
    if ($include && ($height || $width) && $this->_type && ($imageMagick = SRA_File::findInPath(SRA_FILE_ATTRIBUTE_IMAGE_MAGICK_CONVERT))) {
      $converters = SRA_Controller::getSysParams(NULL, 'thumbnail-converter');
      foreach($converters as $mimeTypes => $converter) {
        $mimeTypes = explode(' ', $mimeTypes);
        if (in_array($this->_type, $mimeTypes)) {
          $input = SRA_File::createRandomFile();
          $this->writeToFile($input);
          $inputFile = SRA_File::createRandomFile();
          $cmd = str_replace('${output}', $inputFile, str_replace('${input}', $input, $converter));
          exec($cmd);
          SRA_File::unlink($input);
          break;
        }
      }
      if (!file_exists($inputFile)) { 
        $inputFile = SRA_File::createRandomFile();
        $this->writeToFile($inputFile);
      }
      $file = SRA_File::createRandomFile(NULL, NULL, '.' . $format);
      $cmd = $imageMagick  . ' -thumbnail ' . ($width ? $width : '1600') . 'x' . ($height ? $height : '1200') . (!$preserveAspect ? '\!' : '') . ' ' . $inputFile . '[0] ' . $file;
      exec($cmd);
      SRA_File::unlink($inputFile);
      $multipageFile = substr($file, 0, strlen($file) - strlen($format) - 1) . '-{$n}.' . $format;
      if (!filesize($file)) { $file = NULL; }
      return $file;
    }
    $nl = NULL;
    return $nl;
	}
	// }}}
  
	// {{{ toXmlArray
	/**
	 * returns this file attribute in the form of an associative array containing 
   * 2 nested values: 'attributes': an array containing 3 sub-keys: 'name', 
   * 'size' and 'type', and $fileKey containing the base64 encoding of the bytes 
   * representing this file. this value will be preceded by "<![CDATA[" and 
   * postceded by "]]>"
	 * @access  public
	 * @return array
	 */
	function toXmlArray() {
		$arr = array('attributes' => array('name' => $this->getName(), 'size' => $this->getSize(), 'type' => $this->getType(), 'uri' => $this->getUri()));
    return $arr;
	}
	// }}}
  
  
	// {{{ writeToFile
	/**
	 * this method writes the bytes of this file to the new file name specified
	 * @param string $file the full path to the file to write to
	 * @access  public
	 * @return void
	 */
	function writeToFile($file) {
    if (!$bytes =& $this->getBytes()) {
			$msg = "SRA_FileAttribute::writeToFile: Failed - file contains no data";
			return SRA_Error::logError($msg, __FILE__, __LINE__);
    }
		if (!($fp = fopen($file, 'w'))) {
			$msg = "SRA_FileAttribute::writeToFile: Failed - id ${file} is not writeable";
			return SRA_Error::logError($msg, __FILE__, __LINE__);
    }
    fwrite($fp, $bytes);
    fclose($fp);
	}
	// }}}
	
	
	// private operations
	
	// {{{ _init
	/**
	 * Initializes the basic SRA_FileAttribute properties $_bytes (if applicable), 
	 * $_fileName, $_name, $_size and $_type based on the database query ($_sql) 
	 * specified when this SRA_FileAttribute was initialized. Returns TRUE if 
	 * successful, FALSE otherwise
	 * @access  private
	 * @return boolean
	 */
	function _init() {
		if (!$this->_initialized && !$this->isNew() && $this->_app && $this->_sql && !$this->_hardPath) {
			$currentApp = SRA_Controller::getCurrentAppId();
			SRA_Controller::init($this->_app);
			if (SRA_Database::isValid($db =& SRA_Controller::getAppDb())) {
				if (!SRA_Error::isError($results =& $db->fetch($this->_sql, array(SRA_DATA_TYPE_BLOB)))) {
					if ($row =& $results->next()) {
						$results = $this->_initData($row[0]);
					}
				}
			}
			SRA_Controller::init($currentApp);
		}
		if ($results) {
			return $results;
		}
		else {
			return FALSE;
		}
	}
	// }}}
	
	// {{{ _initData
	/**
	 * Initializes the basic SRA_FileAttribute properties $_bytes (if applicable), 
	 * $_fileName, $_name, $_size and $_type from the given $data extracted from 
	 * the corresponding database column for the file. returns TRUE if successful 
	 * FALSE otherwise
	 * @param byte[] $data the data containing those properties
	 * @access  private
	 * @return boolean
	 */
	function _initData(& $data) {
		if (SRA_FileAttribute::isValid($fileAttribute =& SRA_FileAttribute::getInstanceFromData($data))) {
			if ($fileAttribute->getBytes()) {
				$this->setBytes($fileAttribute->getBytes());
			}
			$this->setFileName($fileAttribute->getFileName());
			$this->setName($fileAttribute->getName());
			$this->setSize($fileAttribute->getSize());
			$this->setType($fileAttribute->getType());
			$this->_setInitialized(TRUE);
			$this->_setNew(FALSE);
			return TRUE;
		}
		return FALSE;
	}
	// }}}
	
	// {{{ _setAttribute
	/**
	 * Sets the _attribute attribute
	 * @param string $attribute see the $_attribute api comments
	 * @access  private
	 */
	function _setAttribute($attribute) {
		$this->_attribute = $attribute;
	}
	// }}}
	
	// {{{ _setAttributeIndex
	/**
	 * Sets the _attributeIndex attributeIndex
	 * @param string $attributeIndex see the $_attributeIndex api comments
	 * @access  private
	 */
	function _setAttributeIndex($attributeIndex) {
		$this->_attributeIndex = $attributeIndex;
	}
	// }}}
	
	// {{{ _setEntity
	/**
	 * Sets the _entity attribute
	 * @param string $entity see the $_entity api comments
	 * @access  private
	 */
	function _setEntity($entity) {
		$this->_entity = $entity;
	}
	// }}}
	
	// {{{ _setEntityId
	/**
	 * Sets the _entityId attribute
	 * @param string $entityId see the $_entityId api comments
	 * @access  private
	 */
	function _setEntityId($entityId) {
		$this->_entityId = $entityId;
	}
	// }}}
	
	// {{{ _setFileDir
	/**
	 * Sets the _fileDir attribute
	 * @param string $fileDir the fileDir attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setFileDir($fileDir) {
		if (is_dir($fileDir) && is_writable($fileDir)) {
			$this->_fileDir = $fileDir;
		}
	}
	// }}}
	
	// {{{ _setFileDirUri
	/**
	 * Sets the _fileDirUri attribute
	 * @param string $fileDirUri the fileDirUri attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setFileDirUri($fileDirUri) {
		$this->_fileDirUri = $fileDirUri;
	}
	// }}}
	
	// {{{ _setFileHandling
	/**
	 * Sets the _fileHandling attribute
	 * @param string $fileHandling see the $_fileHandling api comments
	 * @access  private
	 */
	function _setFileHandling($fileHandling) {
		if (SRA_FileAttribute::fileHandlingMethodIsValid($fileHandling)) {
			$this->_fileHandling = $fileHandling;
			return TRUE;
		}
		return FALSE;
	}
	// }}}
	
	// {{{ _setFileScriptRewrite
	/**
	 * Sets the _fileScriptRewrite attribute
	 * @param string $fileScriptRewrite the fileScriptRewrite attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setFileScriptRewrite($fileScriptRewrite) {
		$this->_fileScriptRewrite = $fileScriptRewrite;
	}
	// }}}
	
	// {{{ _setFileScriptUri
	/**
	 * Sets the _fileScriptUri attribute
	 * @param string $fileScriptUri the fileScriptUri attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setFileScriptUri($fileScriptUri) {
		$this->_fileScriptUri = $fileScriptUri;
	}
	// }}}
	
	// {{{ _setInitialized
	/**
	 * Sets the _initialized attribute
	 * @param string $initialized the initialized attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setInitialized($initialized) {
		$this->_initialized = $initialized;
	}
	// }}}
	
	// {{{ _setNew
	/**
	 * Sets the _new attribute
	 * @param string $new the new attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setNew($new) {
		$this->_new = $new;
	}
	// }}}
	
	// {{{ _setApp
	/**
	 * Sets the _app attribute
	 * @param string $app the app attribute to _set
	 * @access  private
	 * @return void
	 */
	function _setApp($app) {
		$this->_app = $app;
	}
	// }}}
	
	
	// Static methods
	
	// {{{ getInstanceFromDb
	/**
	 * Creates a new instance of SRA_FileAttribute given the following database 
	 * instance criteria
	 * @param byte[] $data can be either an sql query (beginning with SELECT) that 
	 * can be used to retrieve the actual properties of this SRA_FileAttribute, or the 
	 * actual data from the database column itself for the SRA_FileAttribute
	 * @param string $attribute see the $_attribute api comments
	 * @param string $attributeIndex see the $_attributeIndex api comments
	 * @param string $entity see the $_entity api comments
	 * @param string $entityId see the $_entityId api comments
	 * @param string $fileDir see the $_fileDir api comments
	 * @param string $fileDirUri see the $_fileDirUri api comments
	 * @param string $fileHandling see the $_fileHandling api comments
	 * @param string $fileScriptRewrite see the $_fileScriptRewrite api comments
	 * @param string $fileScriptUri see the $_fileScriptUri api comments
	 * @access  public
	 * @return SRA_FileAttribute or SRA_Error
	 */
	function & getInstanceFromDb(& $data, $attribute, $attributeIndex, $entity, $entityId, $fileDir, $fileDirUri, $fileHandling, $fileScriptRewrite, $fileScriptUri) {
		// data is a query
		if (strpos(trim(strtolower($data)), 'select') === 0) {
			$fileAttribute = new SRA_FileAttribute();
			$fileAttribute->_sql = $data;
		}
		// data is actual data from the database
		else if (!SRA_FileAttribute::isValid($fileAttribute =& SRA_FileAttribute::getInstanceFromData($data))) {
			return FALSE;
		}
		$fileAttribute->_setAttribute($attribute);
		$fileAttribute->_setAttributeIndex($attributeIndex);
		$fileAttribute->_setEntity($entity);
		$fileAttribute->_setEntityId($entityId);
		$fileAttribute->_setFileDir($fileDir);
		$fileAttribute->_setFileDirUri($fileDirUri);
		$fileAttribute->_setFileHandling($fileHandling);
		$fileAttribute->_setFileScriptRewrite($fileScriptRewrite);
		$fileAttribute->_setFileScriptUri($fileScriptUri);
		$fileAttribute->_setNew(FALSE);
		$fileAttribute->_setApp(SRA_Controller::getCurrentAppId());
		return $fileAttribute;
	}
	// }}}
	
	// {{{ getInstanceFromData
	/**
	 * Initializes and returns a SRA_FileAttribute object from serialized data. 
	 * returns an FALSE if the serialized data is not a SRA_FileAttribute 
	 * instance
	 * @param byte[] $data the serialized SRA_FileAttribute instance
	 * @access  public
	 * @return SRA_FileAttribute
	 */
	function & getInstanceFromData(& $data) {
		if (SRA_FileAttribute::isValid($fileAttribute = unserialize($data))) {
			return $fileAttribute;
		}
		else {
			return FALSE;
		}
	}
	// }}}
	
	// {{{ getInstanceFromEncryptedId
	/**
	 * Creates a new instance of SRA_FileAttribute based on an encrypted id generated 
	 * by the getEncryptedId method. Returns FALSE if the file was removed
	 * @param string $id the encrypted id to evaluate
	 * @param string $fileDir the directory where this file SHOULD exist. this 
	 * parameter should be specified if SRA_FILE_ATTRIBUTE_TYPE_DIR file handling 
	 * is used to avoid potential security risks. ONLY files in that directory 
	 * will be instantiated or removed
	 * @access  public
	 * @return SRA_FileAttribute, FALSE or SRA_Error
	 */
	function getInstanceFromEncryptedId($id, $fileDir = FALSE) {
		$removeFile = FALSE;
    $id = str_replace(' ', '+', $id);
		if (strstr($id, SRA_FILE_ATTRIBUTE_EID_REMOVE_PREFIX)) {
			$id = str_replace(SRA_FILE_ATTRIBUTE_EID_REMOVE_PREFIX, '', $id);
			$removeFile = TRUE;
		}
		$data = base64_decode($id);
		if (!strstr($data, SRA_FILE_ATTRIBUTE_EID_PREFIX)) {
			$msg = "SRA_FileAttribute::getInstanceFromEncryptedId: Failed - id ${id} is not appropriately prefixed: " . SRA_FILE_ATTRIBUTE_EID_PREFIX;
			return SRA_Error::logError($msg, __FILE__, __LINE__);
		}
		$data = explode('>', str_replace(SRA_FILE_ATTRIBUTE_EID_PREFIX, '', $data));
		if (count($data) != 11) {
			$msg = "SRA_FileAttribute::getInstanceFromEncryptedId: Failed - id ${id} does not have appropriate # of elements (11): " . count($data);
			return SRA_Error::logError($msg, __FILE__, __LINE__);
		}
		if ($data[7] == SRA_FILE_ATTRIBUTE_TYPE_DB) {
			$currentApp = SRA_Controller::getCurrentAppId();
			SRA_Controller::init($data[0]);
			if (SRA_Error::isError($dao =& SRA_DaoFactory::getDao($data[1]))) {
				SRA_Controller::init($currentApp);
				return $dao;
			}
			if (SRA_Error::isError($entity =& $dao->findByPk($data[2]))) {
				SRA_Controller::init($currentApp);
				return $entity;
			}
      if (is_array($entity)) {
        $entity =& $entity[0];
      }
      
			$attrs = explode('#', $data[3]);
			$attr =& $entity->getAttribute($attrs[0]);
			if ($attrs[1]) {
				$attr =& $attr->getAttribute($attrs[1]); 
			}
			if (is_array($attr) && $data[4]) {
				$attr =& $attr[$data[4]];
			}
			
			if (!SRA_FileAttribute::isValid($attr)) {
				SRA_Controller::init($currentApp);
				$msg = 'SRA_FileAttribute::getInstanceFromEncryptedId: Failed - Data did not provide a valid SRA_FileAttribute: app ' . $data[0] . ', entity ' . $data[1] . ', entityId ' . $data[2] . ', attribute ' . $data[3] . ', attributeIndex ' . $data[4];
				return SRA_Error::logError($msg, __FILE__, __LINE__);
			}
			SRA_Controller::init($currentApp);
			return $attr;
		}
		else if ($data[7] == SRA_FILE_ATTRIBUTE_TYPE_DIR) {
			// check directory
			if ($data[8] && !file_exists($data[8])) {
				$msg = "SRA_FileAttribute::getInstanceFromEncryptedId: Failed - SRA_File: $data[8] does not exist";
				return SRA_Error::logError($msg, __FILE__, __LINE__);
			}
			else if ($fileDir && dirname($data[8]) != $fileDir) {
				$msg = "SRA_FileAttribute::getInstanceFromEncryptedId: Failed - SRA_File: $data[8] is not in the specified file directory: $fileDir";
				return SRA_Error::logError($msg, __FILE__, __LINE__);
			}
			$attr = new SRA_FileAttribute();
			$attr->_setFileDir($data[5]);
			$attr->_setFileDirUri($data[6]);
			$attr->_setFileHandling($data[7]);
			$attr->setFileName($data[8]);
			$attr->setSize($data[9]);
			$attr->setType($data[10]);
			if ($removeFile) {
				$attr->delete();
				return FALSE;
			}
			return $attr;
		}
		else {
			$msg = "SRA_FileAttribute::getInstanceFromEncryptedId: Failed - id ${id} specifies an invalid file handling method: " . $data[7];
			return SRA_Error::logError($msg, __FILE__, __LINE__);
		}
	}
	// }}}
	
	// {{{ getInstanceFromUpload
	/**
	 * Creates a new instance of SRA_FileAttribute for a field from the current 
	 * $_FILES PHP global. Returns an FALSE if the $name is not present in that 
	 * variable
	 * @param string $name the name of the uploaded field or the actual $_FILES 
	 * array for that field
	 * @param string $attribute see the $_attribute api comments
	 * @param string $attributeIndex see the $_attributeIndex api comments
	 * @param string $entity see the $_entity api comments
	 * @param string $entityId see the $_entityId api comments
	 * @param string $fileDir see the $_fileDir api comments
	 * @param string $fileDirUri see the $_fileDirUri api comments
	 * @param string $fileHandling see the $_fileHandling api comments
	 * @param string $fileScriptRewrite see the $_fileScriptRewrite api comments
	 * @param string $fileScriptUri see the $_fileScriptUri api comments
   * @param string $fleProcessor see the entity-model dtd documentation for the attribute entity, file-processor attribute
	 * @access  public
	 * @return SRA_FileAttribute or SRA_Error
	 */
	function getInstanceFromUpload($data, $attribute = FALSE, $attributeIndex = FALSE, $entity = FALSE, $entityId = FALSE, $fileDir = FALSE, $fileDirUri = FALSE, $fileHandling = FALSE, $fileScriptRewrite = FALSE, $fileScriptUri = FALSE, $fileProcessor = FALSE) {
		if (is_scalar($data) && is_array($_FILES[$data])) {
			$data = $_FILES[$data];
		}
		if (is_array($data['tmp_name'])) {
			$fileName = $data['tmp_name'][0];
			$err =  $data['error'][0];
		}
		else {
			$fileName = $data['tmp_name'];
			$err =  $data['error'];
		}
		$fileAttribute = FALSE;
		if (is_array($data) && file_exists($fileName) && !$err) {
      if ($fileProcessor) {
        $tmp = exec(str_replace('{$file}', is_array($data['tmp_name']) ? $data['tmp_name'][0] : $data['tmp_name'], $fileProcessor));
      }
			if (is_array($data['tmp_name'])) {
				$fileAttribute = new SRA_FileAttribute($data['tmp_name'][0], $data['name'][0], $data['size'][0], $data['type'][0]);
			}
			else {
				$fileAttribute = new SRA_FileAttribute($data['tmp_name'], $data['name'], $data['size'], $data['type']);
			}
		}
		if ($fileAttribute) {
			$fileAttribute->_setAttribute($attribute);
			$fileAttribute->_setAttributeIndex($attributeIndex);
			$fileAttribute->_setEntity($entity);
			$fileAttribute->_setEntityId($entityId);
			$fileAttribute->_setFileDir($fileDir);
			$fileAttribute->_setFileDirUri($fileDirUri);
			$fileAttribute->_setFileHandling($fileHandling);
			$fileAttribute->_setFileScriptRewrite($fileScriptRewrite);
			$fileAttribute->_setFileScriptUri($fileScriptUri);
			$fileAttribute->_setNew(TRUE);
			$fileAttribute->_setApp(SRA_Controller::getCurrentAppId());
		}
		return $fileAttribute;
	}
	// }}}
	
	// {{{ fileHandlingMethodIsValid
	/**
	 * Static method that returns TRUE if a given file handling method is valid 
	 * (if it corresponds with one of the SRA_FILE_ATTRIBUTE_TYPE_* constants)
	 *
	 * @param  string $method the method to validate
	 * @access	public
	 * @return	boolean
	 */
	function fileHandlingMethodIsValid($method) {
		return ($method == SRA_FILE_ATTRIBUTE_TYPE_DB || $method == SRA_FILE_ATTRIBUTE_TYPE_DIR);
	}
	// }}}
	
	// {{{ isValid()
	/**
	 * Static method that returns true if the object parameter is a SRA_FileAttribute object.
	 *
	 * @param  Object $object The object to validate
	 * @access	public
	 * @return	boolean
	 */
	function isValid( & $object ) {
		return (is_object($object) && (!isset($object->err) || !SRA_Error::isError($object->err)) && strtolower(get_class($object)) == 'sra_fileattribute');
	}
	// }}}
	
  
	// private operations

  
}
// }}}
?>
Return current item: Sierra-php PHP Application Framework