<?php

	
    
    

	define( "FILE_UPLOADS_NOT_ENABLED", -200 );

	/**
	 * \ingroup File
	 *
     * Handles file uploads in pLog.
	 * @see FileUpload
     */
	class FileUploads implements Iterator
	{

    	private $_files;
		private $_valid;

    	/**
         * Creates a new object to handle file uploads. $files is either the
         * contents of the $_FILES variable (if using PHP >= 4.1.0) or
         * $HTTP_POST_FILES if earlier version.
         *
         * @param files The contents of the array generated by php after a file
         * has been uploaded. If empty, the value will be fetched automatically from the request.
         */
    	function FileUploads( $files = null )
        {
			if( $files == null ) {
				
				$this->_files = HttpVars::getFiles();
			}
			else {
            	$this->_files = $files;
			}
        }
		
		/**
		 * processes only one FileUpload object instead of the whole bunch
		 *
		 * @param uplaod A FileUpload object
		 * @param destinationFolder the destination folder
		 * @return true if successful or false otherwise
		 */
		function processFile( $upload, $destinationFolder ) 
		{
        	// first, check if the upload feature is available
            $config =& Config::getConfig();

            if( !$config->getValue( "uploads_enabled" )) {
            	return FILE_UPLOADS_NOT_ENABLED;
            }
			
            if( $destinationFolder[strlen($destinationFolder)-1] != "/" )
            	$destinationFolder .= "/";
				
			$destFileName = basename( $upload->getTmpName() );

			if( $this->my_move_uploaded_file( $upload->getTmpName(), $destinationFolder.$destFileName ) ) {
               	$upload->setFolder( $destinationFolder );
				$error = 0;
            }
            else {
				$error = 1;
			}
			
			$upload->setError( $error );
			
			return $error;
		}

        /**
         * Goes through the array of files and processes them accordingly.
         * The result is an array of the appropiate Resource class that has been
         * created using the ResourceFactory class.
         *
         * @return An array of Upload objects that have already been moved to a safer
         * location.
         */
        function process( $destinationFolder )
        {
        	// first, check if the upload feature is available
            $config =& Config::getConfig();

            if( !$config->getValue( "uploads_enabled" )) {
            	return FILE_UPLOADS_NOT_ENABLED;
            }

        	// array used to store the files that have already been saved
        	$uploads = Array();

            if( $destinationFolder[strlen($destinationFolder-1)] != "/" )
            	$destinationFolder .= "/";

        	foreach( $this->_files as $file ) {
                $upload = new FileUpload( $file );

				$destFileName = $upload->getFileName();

                if( $this->my_move_uploaded_file( $upload->getTmpName(), $destinationFolder.$destFileName ) ) {
                	$upload->setFolder( $destinationFolder );
                    $upload->setError( 0 );
                }
                else {
                	$upload->setError( 1 );
                }
                array_push( $uploads, $upload );
            }

            return $uploads;
        }
        
        /**
         * Implements the a move_uploaded_file that handles multiple partitions.
         *
         * @return a boolean that indicates if the file was successfully moved.  This will 
         * return false if the file is not an uploaded file.
         */
         function my_move_uploaded_file( $filename, $destination )
         {
            // first check to make sure that this file is an uploaded file
            if ( !is_uploaded_file($filename) )
            {
                // This file was not an uploaded file, return false
                return FALSE;
            }
            
            return File::rename( $filename, $destination );
         }

		//----------
		// Implemented for the Iterator interface, so that we can access the files inside the
		// list of uploads as a normal array that returns FileUpload objects
		//----------

		/**
		 * Implemented from the Iterator::current interface. Returns a FileUpload reference
		 * to the current object
		 */
		function current()
		{
			return( new FileUpload( current( $this->_files )));
		}
		
		/**
		 * Implemented from the Iterator::key interface. Returns the key of the current object
		 */
		function key()
		{
			return( key( $this->_files ));
		}
		
		/**
		 * Implemented from the Iterator::next() interface.
		 * Moves the pointer to the next FileUpload object.
		 */
		function next()
		{
			$this->_valid = ( next( $this->_files ) !== FALSE );
		}		
		
		/**
		 * Implemented from Iterator::rewind()
		 * Resets the pointer in the array to the first position.
		 */
		function rewind()
		{
			$this->_valid = ( reset( $this->_files ) !== FALSE );
		}
		
		/**
		 * Implemented from Iterator::valid()
		 * Returns true if the current element is valid.
		 */
		function valid()
		{
			return( $this->_valid );
		}
    }
?>