<?php
/* SVN FILE: $Id: File.php 563 2008-06-07 14:39:39Z bb_yujiro $ */
/**
 * ファイル形式で保存
 *
 * PHP versions 5
 *
 *      hitSuji : Social Network Service <http://rakuto.net/rktSNS/>
 *      Copyright (c) 2007 Yujiro Takahashi
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @filesource
 * @package         hitSuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 563 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-06-07 23:39:39 +0900 (土, 07 6 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */

/**
 * BLOB_Fileクラス
 *
 * @category        Binary Large OBject
 * @package         hitSuji
 * @copyright       Copyright (c) 2007 Yujiro Takahashi
 * @link            http://rakuto.net/
 * @author          Yujiro Takahashi <yujiro@rakuto.net>
 * @version         $Revision: 563 $
 * @modifiedby      $LastChangedBy: bb_yujiro $
 * @lastmodified    $Date: 2008-06-07 23:39:39 +0900 (土, 07 6 2008) $
 * @license         http://opensource.org/licenses/mit-license.php The MIT License
 */
class BLOB_File extends BLOB_Common
{
    /**
     * 基礎ディレクトリ
     * @var string
     */
    protected $base_dir = '';

    /**
     * 基礎ディレクトリ
     * @var string
     */
    protected $idpos = 2;

    /**
     * コンストラクタ
     *
     * @access public
     * @param string $dir
     * @return void
     */
    public function __construct($dir='')
    {
        $this->base_dir = $dir;
    }

    /**
     * 対象データのコピー
     *
     * @access public
     * @param string $source
     * @param string $dest
     * @return boolean
     */
    public function copy($source, $dest)
    {
        $source_origin = $this->getOrigin($source);
        if (!file_exists($source_origin)){
            return false;
        }

        $dest_origin = $this->getOrigin($dest);
        /* ディレクトリ判定 */
        $dir = dirname($dest_origin);
        if (!file_exists($dir)){
            mkdir($dir, 0755, true);
        }
        
        return copy($source_origin, $dest_origin);
    }

    /**
     * アーカイブディレクトリ削除処理
     *
     * @access private
     * @param array $params
     * @return boolean
     */
    public function delete($params)
    {
        extract($params);
        $wheres = array();
        if (!empty($uid)){
            $dir = MEMBER_DIR.$this->_getIdDir($uid).DS.$uid.DS;
            return self::rmOpRF($dir);
        } elseif (!empty($gid)){
            $dir = COMMUNITY_DIR.$this->_getIdDir($gid).DS.$gid.DS;
            return self::rmOpRF($dir);
        }
        return false;
    }

    /**
     * ファイル名の実態を取得
     *
     * @access public
     * @return binary
     */
    public function getOrigin($filename)
    {
        $filename = str_replace('archives.php?', 'archives', $filename);
        $files    = explode('/', $filename);
        $namepos  = count($files) - 1;

        /* IDのグループ分け */
        $idpack              = intval($files[$this->idpos] / 1000);
        $files[$this->idpos] = $idpack.'000'.DS.$files[$this->idpos];

        /* ファイル名のグループ分け */
        $initial         = substr($files[$namepos], 0, 1);
        $files[$namepos] = $initial.DS.$files[$namepos];

        return $this->base_dir.implode(DS, $files);
    }

    /**
     * 対象データの読み込み
     *
     * @access public
     * @param string $filename
     * @return boolean
     */
    public function load($filename)
    {
        $this->origin = $this->getOrigin($filename);
        $this->readfile($this->origin);
        $this->name = basename($filename);

        return true;
    }

    /**
     * 取得キーの変更
     *
     * @access public
     * @param string $oldname
     * @param string $newname
     * @return boolean
     */
    public function rename($oldname, $newname)
    {
        $old_origin = $this->getOrigin($oldname);
        if (!file_exists($old_origin)){
            return false;
        }
        $new_origin = $this->getOrigin($newname);
        /* ディレクトリ判定 */
        $dir = dirname($new_origin);
        if (!file_exists($dir)){
            mkdir($dir, 0755, true);
        }
        return rename($old_origin,$new_origin);
    }

    /**
     * 連続削除処理
     *
     * @access public
     * @param string $path
     * @return boolean
     */
    public static function rmOpRF($dir)
    {
        $files   = glob($dir.'{*}', GLOB_BRACE);
        $deleted = true;

        foreach ($files as $filename){
            if (is_dir($filename)){
                $deleted = self::rmOpRF($filename.DS);
            } else {
                if (is_writable($filename)){
                    unlink($filename);
                } else {
                    $deleted = false;
                }
            }
        } // foreach ($files as $filename)
        if (is_writable($dir) && $deleted){
            rmdir($dir);
        }
        return $deleted;
    }

    /**
     * 対象データの保存
     *
     * @access public
     * @param string $filename
     * @return boolean
     */
    public function save($filename)
    {
        $this->origin = $this->getOrigin($filename);

        /* ディレクトリ判定 */
        $dir = dirname($this->origin);
        if (!file_exists($dir)){
            mkdir($dir, 0755, true);
        }

        /* ファイルの中身を取得 */
        $handle = fopen($this->origin, 'wb');
        if (!is_resource($handle)) {
            return false;
        }
        $result = fwrite($handle, $this->buffer);
        fclose($handle);
        
        return $result;
    }

    /**
     * IDの位置を設定
     *
     * @access public
     * @param integer $idpos
     * @return void
     */
    public function setIDPos($idpos)
    {
        $this->idpos = $idpos;
    }

    /**
     * ファイル削除処理
     *
     * @access private
     * @param array $values
     * @return boolean
     */
    public function unlink($filename)
    {
        $this->origin = $this->getOrigin($filename);
        if (!is_writable($this->origin)){
            return false;
        }
        return unlink($origin);
    }

    /**
     * 所持バッファーの取得
     *
     * @access public
     * @return binary
     */
    private function _getIdDir($id)
    {
        $idpack = intval($id / 1000);
        return $idpack.'000';
    }
} // BLOB_fileの終了
?>
