Check that method contracts are obeyed on return types with regard to error conditions
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 |