These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * This file contains only a single class. |
||
4 | * |
||
5 | * @file |
||
6 | * @package Tabulate |
||
7 | */ |
||
8 | |||
9 | namespace WordPress\Tabulate\DB; |
||
10 | |||
11 | /** |
||
12 | * A record is a single row from a database table. |
||
13 | */ |
||
14 | class Record { |
||
15 | |||
16 | /** |
||
17 | * The table that this record belongs to. |
||
18 | * |
||
19 | * @var Table |
||
20 | */ |
||
21 | protected $table; |
||
22 | |||
23 | /** |
||
24 | * The raw data of this database row. |
||
25 | * |
||
26 | * @var \stdClass |
||
27 | */ |
||
28 | protected $data; |
||
29 | |||
30 | /** |
||
31 | * The suffix that is added to foreign keys when we want to get their |
||
32 | * 'title' value instead of their raw integer (or whatever) form. |
||
33 | */ |
||
34 | const FKTITLE = 'FKTITLE'; |
||
35 | |||
36 | /** |
||
37 | * Create a new Record object. |
||
38 | * |
||
39 | * @param Table $table The table object. |
||
40 | * @param array $data The data of this record. |
||
41 | */ |
||
42 | public function __construct( $table, $data = array() ) { |
||
43 | $this->table = $table; |
||
44 | $this->data = (object) $data; |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * Magic method to set one item in the data object. |
||
49 | * |
||
50 | * @param string $name The name of the column. |
||
51 | * @param mixed $value The value to set. |
||
52 | */ |
||
53 | public function __set( $name, $value ) { |
||
54 | $this->data->{$name} = $value; |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Set multiple columns' values. |
||
59 | * |
||
60 | * @param mixed[] $data An array of column names to data values. |
||
61 | */ |
||
62 | public function set_multiple( $data ) { |
||
63 | if ( ! is_array( $data ) ) { |
||
64 | return; |
||
65 | } |
||
66 | foreach ( $data as $col => $datum ) { |
||
67 | $this->$col = $datum; |
||
68 | } |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Get a column's value. If suffixed with 'FKTITLE', then get the title of |
||
73 | * the foreign record (where applicable). |
||
74 | * |
||
75 | * @param string $name The column name. |
||
76 | * @param mixed [] $args Parameter not used. |
||
77 | * @return string|boolean |
||
78 | * @throws Exception If any arguments are passed (as there should never be any). |
||
79 | */ |
||
80 | public function __call( $name, $args ) { |
||
81 | if ( ! empty( $args ) ) { |
||
82 | throw new Exception( 'Record::colname() functions take no arguments.' ); |
||
83 | } |
||
84 | |||
85 | // Foreign key 'title' values. |
||
86 | $use_title = substr( $name, -strlen( self::FKTITLE ) ) === self::FKTITLE; |
||
87 | if ( $use_title ) { |
||
88 | $name = substr( $name, 0, -strlen( self::FKTITLE ) ); |
||
89 | $col = $this->get_col( $name ); |
||
90 | if ( $col->is_foreign_key() && ! empty( $this->data->$name ) ) { |
||
91 | $referenced_table = $col->get_referenced_table(); |
||
92 | $fk_record = $referenced_table->get_record( $this->data->$name ); |
||
93 | $fk_title_col = $referenced_table->get_title_column(); |
||
94 | $fk_title_col_name = $fk_title_col->get_name(); |
||
95 | if ( $fk_title_col->is_foreign_key() ) { |
||
96 | // Use title if the FK's title column is also an FK. |
||
97 | $fk_title_col_name .= self::FKTITLE; |
||
98 | } |
||
99 | return $fk_record->$fk_title_col_name(); |
||
100 | } |
||
101 | } |
||
102 | $col = $this->get_col( $name ); |
||
103 | |||
104 | // Booleans. |
||
105 | if ( $col->is_boolean() ) { |
||
106 | // Numbers are fetched from the DB as strings. |
||
107 | if ( '1' === $this->data->$name ) { |
||
108 | return true; |
||
109 | } elseif ( '0' === $this->data->$name ) { |
||
110 | return false; |
||
111 | } else { |
||
112 | return null; |
||
113 | } |
||
114 | } |
||
115 | |||
116 | // Standard column values. |
||
117 | if ( isset( $this->data->$name ) ) { |
||
118 | return $this->data->$name; |
||
119 | } |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * Get a column of this record's table, optionally throwing an Exception if |
||
124 | * it doesn't exist. |
||
125 | * |
||
126 | * @param string $name The name of the column. |
||
127 | * @param boolean $required True if this should throw an Exception. |
||
128 | * @return \WordPress\Tabulate\DB\Column The column. |
||
129 | * @throws \Exception If the column named doesn't exist. |
||
130 | */ |
||
131 | protected function get_col( $name, $required = true ) { |
||
132 | $col = $this->table->get_column( $name ); |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||
133 | if ( $required && false === $col ) { |
||
134 | throw new \Exception( "Unable to get column $name on table " . $this->table->get_name() ); |
||
135 | } |
||
136 | return $col; |
||
137 | } |
||
138 | |||
139 | /** |
||
140 | * Get a string representation of this record. |
||
141 | * |
||
142 | * @return string |
||
143 | */ |
||
144 | public function __toString() { |
||
145 | return join( ', ', $this->data ); |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * Get the value of this record's primary key, or false if it doesn't have |
||
150 | * one. |
||
151 | * |
||
152 | * @return string|false |
||
153 | */ |
||
154 | public function get_primary_key() { |
||
155 | if ( $this->table->get_pk_column() ) { |
||
156 | $pk_col_name = $this->table->get_pk_column()->get_name(); |
||
157 | if ( isset( $this->data->$pk_col_name ) ) { |
||
158 | return $this->data->$pk_col_name; |
||
159 | } |
||
160 | } |
||
161 | return false; |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Get the value of this Record's title column. |
||
166 | * |
||
167 | * @return string |
||
168 | */ |
||
169 | public function get_title() { |
||
170 | $title_col = $this->table->get_title_column(); |
||
171 | if ( $title_col !== $this->table->get_pk_column() ) { |
||
172 | $title_col_name = $title_col->get_name(); |
||
173 | return $this->data->$title_col_name; |
||
174 | } else { |
||
175 | $title_parts = array(); |
||
176 | foreach ( $this->table->get_columns() as $col ) { |
||
177 | $col_name = $col->get_name() . self::FKTITLE; |
||
178 | $title_parts[] = $this->$col_name(); |
||
179 | } |
||
180 | return '[ ' . join( ' | ', $title_parts ) . ' ]'; |
||
181 | } |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Get the record that is referenced by this one from the column given. |
||
186 | * |
||
187 | * @param string $column_name The name of the column. |
||
188 | * @return boolean|\WordPress\Tabulate\DB\Record |
||
189 | */ |
||
190 | public function get_referenced_record( $column_name ) { |
||
191 | if ( ! isset( $this->data->$column_name ) ) { |
||
192 | return false; |
||
193 | } |
||
194 | return $this->table |
||
195 | ->get_column( $column_name ) |
||
196 | ->get_referenced_table() |
||
197 | ->get_record( $this->data->$column_name ); |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Get a list of records that reference this record in one of their columns. |
||
202 | * |
||
203 | * @param string|\WordPress\Tabulate\DB\Table $foreign_table The foreign table. |
||
204 | * @param string|\WordPress\Tabulate\DB\Column $foreign_column The column in the foreign table that references this record's table. |
||
205 | * @param boolean $with_pagination Whether to only return the top N records. |
||
206 | * @return \WordPress\Tabulate\DB\Record[] |
||
207 | */ |
||
208 | public function get_referencing_records( $foreign_table, $foreign_column, $with_pagination = true ) { |
||
209 | $foreign_table->reset_filters(); |
||
210 | $foreign_table->add_filter( $foreign_column, '=', $this->get_primary_key(), true ); |
||
211 | return $foreign_table->get_records( $with_pagination ); |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Get an Admin Area URL. |
||
216 | * |
||
217 | * @param string $action The action. |
||
218 | * @param boolean $include_ident Whether to include the record Primary Key. |
||
219 | * @param string[] $extra_params Other parameters to append to the URL. |
||
220 | * @return string The URL. |
||
221 | */ |
||
222 | public function get_url( $action = 'index', $include_ident = true, $extra_params = false ) { |
||
223 | $params = array( |
||
224 | 'page' => 'tabulate', |
||
225 | 'controller' => 'record', |
||
226 | 'action' => $action, |
||
227 | 'table' => $this->table->get_name(), |
||
228 | ); |
||
229 | if ( $include_ident && false !== $this->get_primary_key() ) { |
||
230 | $params['ident'] = $this->get_primary_key(); |
||
231 | } |
||
232 | if ( is_array( $extra_params ) ) { |
||
233 | $params = array_merge( $params, $extra_params ); |
||
234 | } |
||
235 | return admin_url( 'admin.php?' . http_build_query( $params ) ); |
||
236 | } |
||
237 | |||
238 | /** |
||
239 | * Get most recent changes. |
||
240 | * |
||
241 | * @return string[] |
||
242 | */ |
||
243 | public function get_changes() { |
||
244 | $wpdb = $this->table->get_database()->get_wpdb(); |
||
245 | $sql = "SELECT cs.id AS changeset_id, c.id AS change_id, date_and_time, " |
||
246 | . "user_nicename, table_name, record_ident, column_name, old_value, " |
||
247 | . "new_value, comment " |
||
248 | . "FROM " . ChangeTracker::changes_name() . " c " |
||
249 | . " JOIN " . ChangeTracker::changesets_name() . " cs ON (c.changeset_id=cs.id) " |
||
250 | . " JOIN {$wpdb->prefix}users u ON (u.ID=cs.user_id) " |
||
251 | . "WHERE table_name = %s AND record_ident = %s" |
||
252 | . "ORDER BY date_and_time DESC, cs.id DESC " |
||
253 | . "LIMIT 15 "; |
||
254 | $params = array( $this->table->get_name(), $this->get_primary_key() ); |
||
255 | return $wpdb->get_results( $wpdb->prepare( $sql, $params ) ); |
||
256 | } |
||
257 | } |
||
258 |