Completed
Push — master ( 05e8ae...5c8da7 )
by Stefano
03:12
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 {
0 ignored issues
show
Coding Style Compatibility introduced by
Each trait must be in a namespace of at least one level (a top-level vendor name)

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
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
  protected 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;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
45
              case 's': $table = substr($s,0,-1).'es';  break;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
46
              default:  $table = $s.'s'; break;
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
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]) ){
1 ignored issue
show
Bug introduced by
The method single() does not exist on SQL. Did you maybe mean onSingle()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
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
    return SQL::insertOrUpdate($table,array_filter((array)$this),$options['key']);
169
  }
170
171
172
}
173