<?php

class Model_Cms_Backups {

  /**
   * the backup directory
   * @var String
   */
  private $backupDir;

  public function  __construct() {
    // try to increse memory limit
    ini_set('memory_limit', '1024M');

    // increase time execution
    ini_set('max_execution_time', 300);

    // setup the backup dir
    $this->backupDir = BASE_PATH."/uploads/backups/";
  }

  /**
   * List the items based on filters
   * @param Array $filters
   * @return Zend_Paginator
   */
  public function adminList($filters) {

    // open directory
    $dir = dir($this->backupDir);

    // array of files
    $files = array();

    // read dir
    while (false !== ($f= $dir->read())) {
      // check if its a directory
      if(is_dir($f) || !strstr($f, ".sql")) {
        continue;
      }
      // get file info
      $file_parts = explode("-", $f);
      $params = explode("_", str_replace("backup-", "",(str_replace(".sql.gz", "",$file_parts[1]))));
      // setup file date
      $file_time = mktime($params[3], $params[4], $params[5], $params[1], $params[2], $params[0]);

      // create the object
      $file = new stdClass();
      $file->name = $f;
      $file->time = $file_time;
      // add to array
      $files[] = $file;
    }

    // reverse the array
    $files = array_reverse($files);

    // setup the paginator
    $paginator = Zend_Paginator::factory($files);
    $paginator->setCurrentPageNumber($filters['p']);
    $paginator->setDefaultItemCountPerPage($filters['t']);

    return $paginator;
  }

  /**
   * creates a backup file
   * @return stdClass
   */
  public function add() {
    $return = new stdClass();
    $return->error = FALSE;
    $return->message = '';

    try {

      // the dump string
      $dump = '';

      // get db adapter
      $db = Zend_Db_Table_Abstract::getDefaultAdapter();

      // query for tables
      $tables = $db->listTables();

      foreach($tables as $table) {
        // setup the dump table sql
        $dump .= "\n\n". "DROP TABLE IF EXISTS {$table};";

        // get the table creation sql
        $create_sql = $db->fetchAssoc("SHOW CREATE TABLE " . $table);

        // add to dump
        $dump .= "\n\n" . $create_sql[$table]['Create Table'] . ";\n\n";

        // find all content from the given table
        $contents = $db->fetchAssoc("SELECT * FROM {$table}");
        foreach($contents as $c) {

          // add the insert to the dump
          $dump .= "INSERT INTO {$table} VALUES (";

          $values = array();

          foreach($c as $value) {
            $value = stripslashes($value);
            $value = addslashes($value);
            $value = ereg_replace("\n","\\n",$value);

            if(isset($value)) {
              $values[] = '"'.$value.'"';
            } else {
              $values[] = '""';
            }
          }

          // add to dump
          $dump .= join(",", $values);

          // finish the dump
          $dump .= ");\n";
        }
      }

      // create the file name
      $file_name = sprintf("backup-%s.sql.gz", date("Y_m_d_H_i_s"));

      // setup file path
      $file_path = $this->backupDir.$file_name;

      // check if file exists
      while(is_file($file_path)) {
        // create the file name
        $file_name = sprintf("backup-%s.sql.gz", date("Y_m_d_H_i_s"));
        // setup file path
        $file_path = $this->backupDir.$file_name;
      }

      // open file
      $file_handle = fopen($file_path, "w+");
      // write to file
      if(!fwrite($file_handle, gzencode($dump))){
        throw new Exception("Error writing file");
      }
      // close handler
      fclose($file_handle);
      // chmod file
      chmod($file_path, 0777);


    } catch (Exception $exc) {
      $return->error = TRUE;
      $return->message = $exc->getMessage();
    }
    return $return;
  }

  public function deleteFromName($filename = ''){
    $return = new stdClass();
    $return->error = FALSE;
    $return->message = '';

    try {
      // create the file path
      $filepath = $this->backupDir.$filename;

      if(empty($filename) || !is_file($filepath)){
        throw new Exception("Invalid file name");
      }

      unlink($filepath);
    } catch (Exception $exc) {
      $return->error = TRUE;
      $return->message = $exc->getMessage();
    }

    return $return;
  }

}