API Docs for: 1.0.1
Show:

File: src/server/php/Store/Repository/Memory.php

<?php namespace Store\Repository;

// TODO: 
// - thread-safety » file locks
// - load($data/collection)
// - persist » throw error? -> retrieve data from memory and store by external logic *
// - externalize sendResponse

use Store\Store;
use Store\Repository;
use Store\Repository\FileSystem;
use Store\Resource;
use Store\Resource\File;

/**
* Memory Store 
*
* @class Memory
* @module Server
*/
class Memory extends Repository {

  // file format(s)
  private $format = null;
  private $formats = array();

  /**
  * Encode to format
  *
  * @method encode
  * @param {String} $datastore context identifier
  * @void
  */ 
  protected function encode($data){
    $format = $this->format;
    return $format::Encode(new File($data));
  }

  /**
  * Decode from format 
  *
  * @method decode
  * @param {String} $datastore context identifier
  * @void
  */ 
  protected function decode($data){
    $format = $this->format;    
    return $format::Decode(new File($data));  
  }

  /**
  * Load repository 
  *
  * @method load
  * @param {String} $DSN
  * @void
  */ 

  // TODO: data ...
  public function load($dsn){

    // store *
    $this->datastore = $datastore = $dsn;

    // TODO: get format by file extension -> load into static property in function

    // determine/attach formatting helper (TODO: implement 4 real)    
    $this->format = 'Store\Format\Json'; // "Store\Format\\".(strpos($datastore, '.'.($jsonFormat::FILE_EXTENSION!==false?'Json':'Object')));

    // load from disk if exists
    if(file_exists($dsn)) { 

      // convert object data
      $this->items = $this->decode(file_get_contents($dsn)); 

      // handle format err
      if(!is_array($this->items)) { 
        $err = json_encode(array(Store::RESPONSE_ERROR => array("500" => Store::MESSAGE_ERROR_DATASTORE_CORRUPT)));
        die('console.error('.$err.');');        
      }
    }     
  }

  /**
  * Insert or update resource data in datastore
  *
  * @method update
  * @param {Object} $resource what it's about
  * @return {Boolean} Returns true on success
  */ 
  public function update(Resource $resource){

    // Quick Hack > TODO: solve properly
    $instance = $resource->data();

    $this->pending(true);

    // existing vs new
    if(is_numeric($index=$this->find($resource))) {

      // preserve files if empty *
      $preservefiles = $this->files($_FILES, $instance);
      foreach($preservefiles as $prop){
        if(trim($instance[$prop])==="") {
          $instance[$prop] = $this->items[$index][$prop];
        }         
      }
      $this->items[$index] = $instance;
      return $index;
    } else {
      if(!isset($instance[Store::ENTITY_IDENTIFIER]) && strlen(trim($instance[Store::ENTITY_IDENTIFIER]))==0) {
        $instance[Store::ENTITY_IDENTIFIER] = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
      }
      $this->files($_FILES, $instance);
      $this->items[] = $instance;
      
      return array(Store::ENTITY_COUNT => sizeof($this->items)-1);      
    }   
    return false;
  }

  /**
  * Removes a resource from datastore
  *
  * @method remove
  * @param {Object} $resource what it's about
  * @return {Boolean} Returns true on success
  */ 
  public function remove(Resource $resource){
    $instance = $resource->data();
    if(is_numeric($index=$this->find($resource))) {
      array_splice($this->items, $index, 1);
      $this->pending(true);
      return array(Store::ENTITY_COUNT => sizeof($this->items)-1);
    }
  }

  /**
  * Get resource data
  *
  * @method get
  * @param {Object} $resource what it's about
  * @return {Object} resource instance
  */ 
  public function get(Resource $resource=null){
    
    $instance = $resource!=null ? $resource->data() : null;

    if($instance==null) return $this->items;

    if(is_numeric($index=$this->find($resource))) {
      return $this->items[$index];
    }
    return false;
  }  

  /**
  * Find resource (currently just: UUID - TODO: enhance signature w/UUID as default / Widespread Merge ?!)
  *
  * @method find
  * @return {Array} List of item instances
  */ 
  public function find(Resource $resource){
    $instance = $resource->data();

    if(!isset($instance[Store::ENTITY_IDENTIFIER])) return false;
    $this->items = (array) $this->items;
    foreach($this->items as $index => $resource) {
      $resource = (array) $resource;
      if($resource[Store::ENTITY_IDENTIFIER]===$instance[Store::ENTITY_IDENTIFIER]) {
        return $index;
      }
    }  
    return false;
  } 

  /**
  * Filter resources
  *
  * @method find
  * @return {Array} List of matching resource instances
  */ 
  public function filter($filter){
    // TODO: implement
    return array();
  }  

  /**
  * Process HTTP file uploads
  *
  * @method files
  * @param {Object} $files actually just $_FILES ...
  * @void
  */ 
  public function files(&$files, &$instance) {
    
    // handle files *
    $preservefiles = array();
    if(array_key_exists(Store::REQUEST_DATA, $files) && is_array($files[Store::REQUEST_DATA][Store::TRANSFER_TARGET])){
      $filesx = array_keys($files[Store::REQUEST_DATA][Store::TRANSFER_TARGET]);
      if(is_array($filesx)){
        foreach($filesx as $file){
          array_push($preservefiles, $file);
          if(strlen(trim($files[Store::REQUEST_DATA][Store::TRANSFER_SOURCE][$file]))){
            $instance[$file]='data: '.mime_content_type($files[Store::REQUEST_DATA][Store::TRANSFER_SOURCE][$file]).';base64,'.base64_encode(file_get_contents($files[Store::REQUEST_DATA][Store::TRANSFER_SOURCE][$file]));
          }
        }
      }
    }
    return $preservefiles;
  }

  /**
  * Persist data
  * 
  * @method persist
  * @param {String} filepath
  * @param {String} contents
  * @void
  */ 
  public function persist($filepath, $content=null){

    $file = new File();
    $file->path($filepath);
    $file->content($content==null ? $this->encode($this->items) : $content);

    // ...
    return FileSystem::persistToDisk($file);
  }   
}