<?php
/**
 * File containing the ezcCacheStorageFileApcArray class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 * @package Cache
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @filesource
 */

/**
 * This class is a replacement for the {@link ezcCacheStorageFileArray} class. Tries
 * to serve data from a local APC cache if possible.
 *
 * Options for this class are defined in {@link ezcCacheStorageFileApcArrayOptions}.
 *
 * @apichange This class might be removed in future versions. Please use
 *            {@link ezcCacheStack} to achieve the desired behaior.
 * @package Cache
 * @version //autogentag//
 */
class ezcCacheStorageFileApcArray extends ezcCacheStorageApc
{
    /**
     * Creates a new cache storage in the given location. The location in case
     * of this storage class must a valid file system directory.
     *
     * Options can contain the 'ttl' (Time-To-Live). This is per default set
     * to 1 day. The option 'permissions' can be used to define the file
     * permissions of created cache items.
     *
     * For details about the options see {@link ezcCacheStorageFileApcArrayOptions}.
     *
     * @throws ezcBasePropertyNotFoundException
     *         If you tried to set a non-existent option value.
     *
     * @param string $location Path to the cache location. Must be a valid path
     * @param array(string=>string) $options Options for the cache storage
     */
    public function __construct( $location, array $options = array() )
    {
        parent::__construct( $location, array() );

        // Overwrite parent set options with new ezcCacheStorageFileApcArrayOptions
        $this->properties['options'] = new ezcCacheStorageFileApcArrayOptions( $options );
    }

    /**
     * Fetches the data from the cache.
     * 
     * @param string $filename The ID/filename from where to fetch the object
     * @param bool $useApc Use APC or the file system
     * @return mixed The fetched data or false on failure
     */
    protected function fetchData( $filename, $useApc = false )
    {
        if ( $useApc === true )
        {
            $data = $this->backend->fetch( $filename );
            return ( is_object( $data ) ) ? $data->data : false;
        }
        else
        {
            return ( include $filename );
        }
    }

    /**
     * Fetches the object from the cache.
     *
     * @param string $filename The ID/filename from where to fetch the data
     * @return mixed The fetched object or false on failure
     */
    protected function fetchObject( $filename )
    {
        $data = $this->backend->fetch( $filename );
        return ( is_object( $data ) ) ? $data : false;
    }

    /**
     * Wraps the data in order to be stored in APC ($useApc = true) or on the
     * file system ($useApc = false).
     *
     * @throws ezcCacheInvalidDataException
     *         If the data submitted can not be handled by this storage (object,
     *         resource).
     *
     * @param mixed $data Simple type or array
     * @param bool $useApc Use APC or not
     * @return mixed Prepared data
     */
    protected function prepareData( $data, $useApc = false )
    {
        if ( $useApc === true )
        {
            if ( is_resource( $data ) )
            {
                throw new ezcCacheInvalidDataException( gettype( $data ), array( 'simple', 'array', 'object' ) );
            }
            return new ezcCacheStorageFileApcArrayDataStruct( $data, $this->properties['location'] );
        }
        else
        {
            if ( is_object( $data )
                 || is_resource( $data ) )
            {
                throw new ezcCacheInvalidDataException( gettype( $data ), array( 'simple', 'array' ) );
            }
            return "<?php\nreturn " . var_export( $data, true ) . ";\n?>\n";
        }
    }

    /**
     * Stores data to the cache storage.
     *
     * @throws ezcBaseFilePermissionException
     *         If the directory to store the cache file could not be created.
     *         This exception means most likely that your cache directory
     *         has been corrupted by external influences (file permission
     *         change).
     * @throws ezcBaseFileIoException
     *         If an error occured while writing the data to the cache. If this
     *         exception occurs, a serious error occured and your storage might
     *         be corruped (e.g. broken network connection, file system broken,
     *         ...).
     * @throws ezcCacheInvalidDataException
     *         If the data submitted can not be handled by the implementation
     *         of {@link ezcCacheStorageFile}. Most implementations can not
     *         handle objects and resources.
     * @throws ezcCacheApcException
     *         If the data could not be stored in APC.
     *
     * @param string $id Unique identifier
     * @param mixed $data The data to store
     * @param array(string=>string) $attributes Attributes describing the cached data
     * @return string The ID string of the newly cached data
     */
    public function store( $id, $data, $attributes = array() )
    {
        // Generates the identifier
        $filename = $this->properties['location'] . $this->generateIdentifier( $id, $attributes );

        // Purges the Registry Cache
        if ( isset( $this->registry[$filename] ) )
        {
            unset( $this->registry[$filename] );
        }

        // Deletes the files if it already exists on the filesystem
        if ( file_exists( $filename ) )
        {
            if ( unlink( $filename ) === false )
            {
                throw new ezcBaseFilePermissionException( $filename, ezcBaseFileException::WRITE, 'Could not delete existing cache file.' );
            }
        }

        // Deletes the data from APC if it already exists
        $this->backend->delete( $filename );

        // Prepares the data for filesystem storage
        $dataStr = $this->prepareData( $data );

        // Tries to create the directory on the filesystem
        $dirname = dirname( $filename );
        if ( !is_dir( $dirname )
             && !mkdir( $dirname, 0777, true ) )
        {
            throw new ezcBaseFilePermissionException( $dirname, ezcBaseFileException::WRITE, 'Could not create directory to store cache file.' );
        }

        // Tries to write the file the filesystem
        if ( @file_put_contents( $filename, $dataStr ) !== strlen( $dataStr ) )
        {
            throw new ezcBaseFileIoException( $filename, ezcBaseFileException::WRITE, 'Could not write data to cache file.' );
        }

        // Tries to set the file permissions
        if ( ezcBaseFeatures::os() !== "Windows" )
        {
            chmod( $filename, $this->options->permissions );
        }

        // Prepares the data for APC storage
        $dataObj = $this->prepareData( $data, true );
        $dataObj->mtime = @filemtime( $filename );
        $dataObj->atime = time();

        // Stores it in APC
        $this->registerIdentifier( $id, $attributes, $filename );
        if ( !$this->backend->store( $filename, $dataObj, $this->properties['options']['ttl'] ) )
        {
            throw new ezcCacheApcException( "APC store failed." );
        }

        // Returns the ID for no good reason
        return $id;
    }

    /**
     * Restores the data from the cache.
     *
     * @param string $id The item ID to restore
     * @param array(string=>string) $attributes Attributes describing the data to restore
     * @param bool $search Whether to search for items if not found directly
     * @return mixed The cached data on success, otherwise false
     */
    public function restore( $id, $attributes = array(), $search = false )
    {
        // Generates the identifier
        $filename = $this->properties['location'] . $this->generateIdentifier( $id, $attributes );

        // Grabs the data object from the APC
        $dataObj = $this->fetchObject( $filename );
        $useApc = false;

        // Checks the APC object exists
        if ( $dataObj !== false
             && is_object( $dataObj )
             && isset( $dataObj->atime ) )
        {
            $useApc = true;
        }

        // Checks the APC object is still valid
        if ( !isset( $this->registry[$filename] )
             && $useApc === true
             && time() === $dataObj->atime )
        {
            // Make sure the FileSystem still has the file and that it hasn't changed
            if ( file_exists( $filename ) !== false
                 && @filemtime( $filename ) === $dataObj->mtime )
            {
                $dataObj->atime = time();
                $this->backend->store( $filename, $dataObj, $this->properties['options']['ttl'] );
            }
            else
            {
                $useApc = false;
                $this->backend->delete( $filename );
            }
        }

        // Searches the filesystem for the file
        if ( !isset( $this->registry[$filename] )
             && $useApc === false
             && file_exists( $filename ) === false )
        {
            if ( $search === true
                 && count( $files = $this->search( $id, $attributes ) ) === 1 )
            {
                $filename = $files[0][2];
            }
            else
            {
                // There are more elements found during search, so false is returned
                return false;
            }
        }

        // Returns false if no data is stored anywhere
        if ( $useApc === false
             && file_exists( $filename ) === false )
        {
            // Purges APC
            $this->backend->delete( $filename );

            // Purges Registry Cache
            if ( isset( $this->registry[$filename] ) )
            {
                unset( $this->registry[$filename] );
            }

            return false;
        }

        // Creates a Registry Object -- should only happen once per page load
        if ( !isset( $this->registry[$filename] ) )
        {
            $this->registry[$filename] = new stdClass();
            $this->registry[$filename]->data = false;
            $this->registry[$filename]->mtime = $useApc ? $dataObj->mtime : null;
            $this->registry[$filename]->lifetime = $this->calcLifetime( $filename, $useApc );
        }

        // Purges the data if it is expired
        if ( $this->properties['options']['ttl'] !== false
             && $this->calcLifetime( $filename, $useApc ) > $this->properties['options']['ttl'] )
        {
            $this->delete( $id, $attributes, false ); // don't search
            return false;
        }

        // Returns the data from the Registry Cache
        if ( $this->registry[$filename]->data !== false )
        {
            return ( $this->registry[$filename]->data );
        }

        // Returns data from APC
        else if ( $useApc === true
                  && ( isset( $dataObj->data ) || is_null( $dataObj->data ) ) )
        {
            $this->registry[$filename]->data = $dataObj->data; // primes the Registry cache
            return ( $dataObj->data );
        }

        // Returns data from the filesystem
        else if ( file_exists( $filename ) !== false )
        {
            // Grabs the data from the filesystem
            $dataStr = $this->fetchData( $filename );

            // Stores it in the Registry Cache
            $this->registry[$filename]->data = $dataStr;

            // Prepares the data for APC storage
            $dataObj = $this->prepareData( $dataStr, true );
            $dataObj->mtime = @filemtime( $filename );
            $dataObj->atime = time();

            // Stores it in APC
            $this->backend->store( $filename, $dataObj, $this->properties['options']['ttl'] );

            // Returns the data
            return ( $dataStr );
        }
        else
        {
            return false;
        }
    }

    /**
     * Deletes the data associated with $id or $attributes from the cache.
     *
     * @throws ezcBaseFilePermissionException
     *         If an already existsing cache file could not be unlinked.
     *         This exception means most likely that your cache directory
     *         has been corrupted by external influences (file permission
     *         change).
     *
     * @param string $id The item ID to purge
     * @param array(string=>string) $attributes Attributes describing the data to restore
     * @param bool $search Whether to search for items if not found directly
     */
    public function delete( $id = null, $attributes = array(), $search = false )
    {
        $location = $this->properties['location'];
        // Generates the identifier
        $filename = $location . $this->generateIdentifier( $id, $attributes );

        // Initializes the array
        $delFiles = array();

        clearstatcache();

        // Checks if the file exists on the filesystem
        if ( file_exists( $filename ) )
        {
            $delFiles[] = array( $id, $attributes, $filename );
        }
        else if ( $search === true )
        {
            $delFiles = $this->search( $id, $attributes );
        }

        $deletedIds = array();
        // Deletes the files
        foreach ( $delFiles as $count => $filename )
        {
            // Deletes from Registry Cache
            if ( isset( $this->registry[$filename[2]] ) )
            {
                unset( $this->registry[$filename[2]] );
            }

            // Deletes from APC
            $this->backend->delete( $filename[2] );
            $this->unRegisterIdentifier( $filename[0], $filename[1], $filename[2], true );
            if ( isset( $this->registry[$location][$filename[0]][$filename[2]] ) )
            {
                unset( $this->registry[$location][$filename[0]][$filename[2]] );
            }

            // Deletes from the filesystem
            if ( @unlink( $filename[2] ) === false )
            {
                throw new ezcBaseFilePermissionException(
                    $filename,
                    ezcBaseFileException::WRITE,
                    'Could not unlink cache file.'
                );
            }
            $deletedIds[] = $filename[0];
        }
        $this->storeSearchRegistry();
        return $deletedIds;
    }

    /**
     * Checks the path in the location property exists, and is read-/writable. It
     * throws an exception if not.
     *
     * @throws ezcBaseFileNotFoundException
     *         If the storage location does not exist. This should usually not 
     *         happen, since {@link ezcCacheManager::createCache()} already
     *         performs sanity checks for the cache location. In case this 
     *         exception is thrown, your cache location has been corrupted 
     *         after the cache was configured.
     * @throws ezcBaseFileNotFoundException
     *         If the storage location is not a directory. This should usually 
     *         not happen, since {@link ezcCacheManager::createCache()} already
     *         performs sanity checks for the cache location. In case this 
     *         exception is thrown, your cache location has been corrupted 
     *         after the cache was configured.
     * @throws ezcBaseFilePermissionException
     *         If the storage location is not writeable. This should usually not 
     *         happen, since {@link ezcCacheManager::createCache()} already
     *         performs sanity checks for the cache location. In case this 
     *         exception is thrown, your cache location has been corrupted 
     *         after the cache was configured.
     */
    protected function validateLocation()
    {
        if ( file_exists( $this->properties['location'] ) === false )
        {
            throw new ezcBaseFileNotFoundException( $this->properties['location'], 'cache location' );
        }

        if ( is_dir( $this->properties['location'] ) === false ) 
        {
            throw new ezcBaseFileNotFoundException( $this->properties['location'], 'cache location', 'Cache location not a directory.' );
        }

        if ( is_writeable( $this->properties['location'] ) === false ) 
        {
            throw new ezcBaseFilePermissionException( $this->properties['location'], ezcBaseFileException::WRITE, 'Cache location is not a directory.' );
        }
    }

    /**
     * Calculates the lifetime remaining for a cache object.
     *
     * If the TTL option is set to false, this method will always return 1 for
     * existing items.
     *
     * @param string $filename The file to calculate the remaining lifetime for
     * @param bool $useApc Use APC or not
     * @return int The remaining lifetime in seconds (0 if no time remaining)
     */
    protected function calcLifetime( $filename, $useApc = false )
    {
        $ttl = $this->options->ttl;
        // Calculate when the APC object was created
        if ( $useApc === true )
        {
            // we've likely already looked this thing up in APC, so we'll grab the local object
            if ( isset( $this->registry[$filename] ) )
            {
                $dataObj = $this->registry[$filename];
            }
            else // otherwise we'll grab it from APC
            {
                $dataObj = $this->fetchObject( $filename );
            }

            if ( is_object( $dataObj ) )
            {
                if ( $ttl === false )
                {
                    return 1;
                }
                return (
                    ( $lifeTime = ( time() - $dataObj->mtime ) ) > $ttl
                    ? $ttl - $lifeTime 
                    : 0
                );
            }
            else
            {
                return 0;
            }
        }

        // Calculate when the filesystem file was created
        else
        {
            if ( ( file_exists( $filename ) !== false )
                 && ( ( $modTime = @filemtime( $filename ) ) !== false ) )
            {
                if ( $ttl === false )
                {
                    return 1;
                }
                return (
                    ( $lifeTime = ( time() - $modTime ) ) < $ttl
                    ? $ttl - $lifeTime 
                    : 0
                );
            }
            else
            {
                return 0;
            }
        }
    }
}
?>
