Completed
Push — master ( caf349...3543bb )
by Stefano
02:57
created

Persistence::persistenceLoad()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Persistence trait
5
 *
6
 * Provides a way to persist a class on a storage.
7
 *
8
 * @package core
9
 * @author [email protected]
10
 * @copyright Caffeina srl - 2015 - http://caffeina.it
11
 */
12
13
trait Persistence {
14
15
  /**
16
   * [Internal] : Retrieve/Set persistence options
17
   * This function can be used to get all options passing null, setting options passing an associative
18
   * array or retrieve a single value passing a string
19
   *
20
   * @param  mixed $options The options passed to the persistence layer.
21
   * @return mixed          All options array or a single value
22
   */
23
  public static function persistenceOptions($options=null){
24
    static $_options = ['table'=>null,'key'=>'id'];
25
    if ($options === null) return $_options;
26
27
    if (is_array($options)) {
28
      foreach ($_options as $key => &$value) {
29
        if (isset($options[$key])) $value = $options[$key];
30
      }
31
      return $_options;
32
    } else {
33
      if (empty($_options['table'])) {
34
        $self = get_called_class();
35
        if (defined("$self::_PRIMARY_KEY_")){
36
          $x = explode('.', $self::_PRIMARY_KEY_);
37
          $_options = [
38
            'table' => current($x),
39
            'key'   => isset($x[1])?$x[1]:'id',
40
          ];
41
        } else {
42
          // User pluralized class name as default table
43
          switch(substr($s = strtolower($self),-1)){
44
              case 'y': $table = substr($s,0,-1).'ies'; break;
45
              case 's': $table = substr($s,0,-1).'es';  break;
46
              default:  $table = $s.'s'; break;
47
          }
48
          // Default ID
49
          $_options = [
50
            'table' => $table,
51
            'key'   => 'id',
52
          ];
53
        }
54
      }
55
      return isset($_options[$options]) ? $_options[$options] : '';
56
    }
57
  }
58
59
  /**
60
   * [Internal] : Assigns or retrieve the Save callback
61
   * The save callback interface is
62
   *   function($table, array $options)
63
   *
64
   * @param  callable $callback The callback to use on model save
65
   * @return callable           Current save callback
66
   */
67
  protected static function persistenceSave(callable $callback=null){
68
    static $save_cb = null;
69
    return $callback ? $save_cb = $callback : $save_cb;
70
  }
71
72
  /**
73
   * [Internal] : Assigns or load the Load callback
74
   * The load callback interface is
75
   *   function($table, array $options)
76
   *
77
   * @param  callable $callback The callback to use on model load
78
   * @return callable           Current load callback
79
   */
80
  protected static function persistenceLoad(callable $callback=null){
81
    static $retrieve_cb = null;
82
    return $callback ? $retrieve_cb = $callback : $retrieve_cb;
83
  }
84
85
86
  /**
87
   * Enable peristence on `$table` with `$options`
88
   *   Avaiable options:
89
   *     `key` : The column name of the primary key, default to `id`.
90
   *
91
   * @param  string $table   The table name
92
   * @param  array $options An associative array with options for the persistance layer.
93
   * @return void
94
   */
95
  public static function persistOn($table, array $options=[]){
96
    $options['table'] = $table;
97
    static::persistenceOptions($options);
98
  }
99
100
101
  /**
102
   * Override standard save function with a new callback
103
   * @param  callable $callback The callback to use on model save
104
   * @return void
105
   */
106
  public static function onSave(callable $callback){
107
    static::persistenceSave($callback);
108
  }
109
110
  /**
111
   * Override standard load function with a new callback
112
   * @param  callable $callback The callback to use on model load
113
   * @return void
114
   */
115
  public static function onLoad(callable $callback){
116
    static::persistenceLoad($callback);
117
  }
118
119
  /**
120
   * Load the model from the persistence layer
121
   * @return mixed The retrieved object
122
   */
123
  public static function load($pk){
124
    $table = static::persistenceOptions('table');
125
    $cb    = static::persistenceLoad();
126
    $op    = static::persistenceOptions();
127
128
    // Use standard persistence on DB layer
129
    return ( false == is_callable($cb) ) ?
130
      static::persistenceLoadDefault($pk,$table,$op) : $cb($pk,$table,$op);
131
  }
132
133
  /**
134
   * Private Standard Load Method
135
   */
136
  private static function persistenceLoadDefault($pk, $table, $options){
137
    if ( $data = SQL::single("SELECT * FROM $table WHERE {$options['key']}=? LIMIT 1",[$pk]) ){
138
       $obj = new static;
139
       foreach ((array)$data as $key => $value) {
140
         $obj->$key = $value;
141
       }
142 View Code Duplication
       if (is_callable(($c=get_called_class())."::trigger")) $c::trigger("load", $obj, $table, $options['key']);
143
       return $obj;
144
     } else {
145
       return null;
146
     }
147
  }
148
149
  /**
150
   * Save the model to the persistence layer
151
   * @return mixed The results from the save callback. (default: lastInsertID)
152
   */
153
  public function save(){
154
    $table  = static::persistenceOptions('table');
155
    $op     = static::persistenceOptions();
156
    $cb     = static::persistenceSave();
157
158
    // Use standard persistence on DB layer
159
    $cb = $cb ? Closure::bind($cb, $this) : [$this,'persistenceSaveDefault'];
160
    return $cb($table,$op);
161
  }
162
163
  /**
164
   * Private Standard Save Method
165
   */
166
  private function persistenceSaveDefault($table,$options){
167 View Code Duplication
    if (is_callable(($c=get_called_class())."::trigger")) $c::trigger("save", $this, $table, $options['key']);
168
    $id = SQL::insertOrUpdate($table,array_filter((array)$this, function($var) {
169
      return !is_null($var);
170
    }),$options['key']);
171
    // Populate retrieved primary key in Models.
172
    if (null !== $id && is_a($this, 'Model')) $this->{$options['key']} = $id;
173
    return $id;
174
  }
175
176
177
}
178