PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.40
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.40
5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 5.5.42 All 160 releases
wp-data-access / WPDataProjects / List_Table / WPDP_List_Table_Lookup.php

WPDP_List_Table_Lookup.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.40, at WPDataProjects/List_Table/WPDP_List_Table_Lookup.php

329 lines 11.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 *
6 * @package WPDataProjects\List_Table
7 */
8
9 namespace WPDataProjects\List_Table {
10
11 use WPDataAccess\Connection\WPDADB;
12 use WPDataAccess\WPDA;
13 use WPDataAccess\List_Table\WPDA_List_Table;
14 use WPDataProjects\Data_Dictionary\WPDP_List_Columns_Cache;
15 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Design_Table_Model;
16
17 /**
18 * Class WPDP_List_Table_Lookup extends WPDA_List_Table
19 *
20 * This class implements the lookup functionality. A lookup is the opposite of a one to many relationship.
21 * (1) A lookup provides the user with a listbox of possible values
22 * (2) A lookup offers the user comfort to search in lookup strings (e.g. titles or descriptions)
23 *
24 * @see WPDA_List_Table
25 *
26 * @author Peter Schulz
27 * @since 2.0.0
28 */
29 class WPDP_List_Table_Lookup extends WPDA_List_Table {
30
31 /**
32 * Column options for the given table
33 *
34 * @var array|null
35 */
36 protected $column_options_listtable;
37
38 /**
39 * Options set name
40 *
41 * @var string
42 */
43 protected $setname = 'default';
44
45 protected $page_id = null;
46 protected $has_default_where = false;
47
48 /**
49 * WPDP_List_Table_Lookup constructor
50 *
51 * @param array $args
52 *
53 * @see WPDA_List_Table
54 */
55 public function __construct( $args = array() ) {
56 $args['pid'] = isset( $args['pid'] ) ? $args['pid'] : '';
57
58 parent::__construct( $args );
59
60 $this->setname = $this->wpda_list_columns->get_setname();
61 $this->column_options_listtable = WPDP_Project_Design_Table_Model::get_column_options( $this->table_name, 'listtable', $this->setname, $this->schema_name );
62 $this->has_default_where = isset( $args['where_clause'] ) && null !== $args['where_clause'] && '' !== trim( $args['where_clause'] );
63 $this->page_id = $args['pid'];
64 }
65
66 /**
67 * Overwrites method get_sortable_columns
68 *
69 * @return array
70 * @see WPDA_List_Table::get_sortable_columns()
71 */
72 public function get_sortable_columns() {
73 if ( false !== strpos( $this->orderby, '-' ) ) {
74 return array();
75 }
76
77 if ( null != $this->column_options_listtable ) {
78 $columns = array();
79 foreach ( $this->column_options_listtable as $column_option ) {
80 if ( isset( $column_option->lookup ) && $column_option->lookup !== false ) {
81 // Sorting on lookup columns is not possible.
82 } else {
83 $columns[ $column_option->column_name ] = array( $column_option->column_name, false );
84 }
85 }
86
87 return $columns;
88 } else {
89 return parent::get_sortable_columns();
90 }
91 }
92
93 /**
94 * Overwrites method column_default
95 *
96 * @param array $item List of all available items
97 * @param string $column_name Database column name
98 *
99 * @return mixed|string
100 * @see WPDA_List_Table::column_default()
101 */
102 public function column_default( $item, $column_name ) {
103 if ( null != $this->column_options_listtable ) {
104 foreach ( $this->column_options_listtable as $column_option ) {
105 if ( isset( $column_option->lookup ) ) {
106 if ( $column_option->column_name === $column_name && $column_option->lookup !== false ) {
107 $column_options_relationships = WPDP_Project_Design_Table_Model::get_column_options( $this->table_name, 'relationships', $this->setname, $this->schema_name );
108 if ( null !== $column_options_relationships ) {
109 foreach ( $column_options_relationships['relationships'] as $column_options_relationship ) {
110 if (
111 (
112 'lookup' === $column_options_relationship->relation_type ||
113 'autocomplete' === $column_options_relationship->relation_type
114 ) &&
115 $column_options_relationship->source_column_name[0] === $column_name
116 ) {
117 if ( isset( $column_options_relationship->target_schema_name ) ) {
118 $target_schema_name = $column_options_relationship->target_schema_name;
119 } else {
120 $target_schema_name = $this->schema_name;
121 }
122 $target_table_name = $column_options_relationship->target_table_name;
123 $target_column_name = $column_options_relationship->target_column_name[0];
124
125 $data_type = null;
126 foreach ( $column_options_relationships['table'] as $tableinfo ) {
127 if ( $tableinfo->column_name === $column_name ) {
128 $data_type = $tableinfo->data_type;
129 }
130 }
131
132 $wpdadb = WPDADB::get_db_connection( $target_schema_name );
133 if ( null !== $wpdadb ) {
134 $where = '';
135 for ( $i = 1; $i < count( $column_options_relationship->source_column_name ); $i++ ) {//phpcs:ignore - 8.1 proof
136 if ( isset( $item[ $column_options_relationship->source_column_name[ $i ] ] ) ) {
137 $value = $item[ $column_options_relationship->source_column_name[ $i ] ];
138 $data_type_lookup = null;
139 foreach ( $column_options_relationships['table'] as $tableinfo ) {
140 if ( $tableinfo->column_name === $column_options_relationship->source_column_name[ $i ] ) {
141 $data_type_lookup = $tableinfo->data_type;
142 }
143 }
144 if ( 'number' == WPDA::get_type( $data_type_lookup ) ) {
145 $where .= $wpdadb->prepare( " and {$column_options_relationship->target_column_name[ $i ]} = %d", array( $value ) );
146 } else {
147 $where .= $wpdadb->prepare( " and {$column_options_relationship->target_column_name[ $i ]} = %s", array( $value ) );
148 }
149 }
150 }
151
152 $lookup_value = $this->column_lookup(
153 $target_column_name,
154 $target_table_name,
155 $column_option->lookup,
156 $item[ $column_name ],
157 $data_type,
158 $where,
159 $target_schema_name
160 );
161
162 $item[ "lookup_id_$column_name" ] = $item[ $column_name ];
163 $item[ "lookup_column_$column_name" ] = $column_option->lookup;
164 $item[ "lookup_value_$column_name" ] = null === $lookup_value || '' === $lookup_value ? '' : $lookup_value;
165 }
166 }
167 }
168 }
169 }
170 }
171 }
172 }
173
174 return parent::column_default( $item, $column_name );
175 }
176
177 /**
178 * Performs lookup query
179 *
180 * @param string $target_column_name Lookup key column
181 * @param string $target_table_name Lookup table name
182 * @param string $source_column_name Source column name
183 * @param mixed $value Lookup key value
184 * @param string $data_type Lookup key data type
185 * @param string $and Extension of where clause
186 * @param string $target_schema_name Database schema name
187 *
188 * @return mixed Lookup value
189 */
190 protected function column_lookup( $target_column_name, $target_table_name, $source_column_name, $value, $data_type, $and, $target_schema_name ) {
191 $wpdadb = WPDADB::get_db_connection( $target_schema_name );
192 if ( $wpdadb === null ) {
193 return null;
194 }
195
196 // Value is taken from database query. No need to prepare.
197 if ( '' === $target_schema_name ) {
198 $lookup_sql_table_name = '`' . str_replace( '`', '', $target_table_name ) . '`';
199 } else {
200 $lookup_sql_table_name = "`{$wpdadb->dbname}`.`" . str_replace( '`', '', $target_table_name ) . '`';
201 }
202 $sql = 'select `' . str_replace( '`', '', $source_column_name ) . "` from $lookup_sql_table_name where `" . str_replace( '`', '', $target_column_name ) . '` = ';
203 if ( 'number' === WPDA::get_type( $data_type ) ) {
204 $sql = $wpdadb->prepare( $sql . "%d $and", array( $value ) );
205 } else {
206 $sql = $wpdadb->prepare( $sql . "%s $and", array( $value ) );
207 }
208 $set = $wpdadb->get_results( $sql, 'ARRAY_A' );
209
210 if ( 1 === $wpdadb->num_rows ) {
211 return $set[0][ $source_column_name ];
212 } else {
213 return null;
214 }
215 }
216
217 /**
218 * Constructs the where clause
219 *
220 * Uses the table options to determine lookup table and columns. A subquery is added if a lookup is found.
221 */
222 protected function construct_where_clause() {
223 $perform_default_method = true;
224 if ( null !== $this->search_value && '' !== $this->search_value ) {
225 if ( null != $this->column_options_listtable ) {
226 global $wpdb;
227 $nowhere = ( '' === $this->where );
228 $search_values = '%' . esc_attr( $this->search_value ) . '%';
229 $where_current = '';
230 $where_first = true;
231 foreach ( $this->column_options_listtable as $column_option ) {
232 if ( isset( $column_option->lookup ) && $column_option->lookup !== false ) {
233 // Add a subquery for text columns.
234 $column_options_relationships = WPDP_Project_Design_Table_Model::get_column_options( $this->table_name, 'relationships', $this->setname, $this->schema_name );
235 if ( null !== $column_options_relationships ) {
236 foreach ( $column_options_relationships['relationships'] as $column_options_relationship ) {
237 if (
238 (
239 'lookup' === $column_options_relationship->relation_type ||
240 'autocomplete' === $column_options_relationship->relation_type
241 ) &&
242 $column_options_relationship->source_column_name[0] === $column_option->column_name
243 ) {
244 $target_table_name = str_replace( '`', '', $column_options_relationship->target_table_name );
245 $target_column_name = str_replace( '`', '', $column_options_relationship->target_column_name[0] );
246
247 $relationship_table = WPDP_List_Columns_Cache::get_list_columns( $wpdb->dbname, $target_table_name, 'listtable', $this->setname );
248 $relationship_table_columns = $relationship_table->get_table_columns();
249 foreach ( $relationship_table_columns as $relationship_table_column ) {
250 if ( $column_option->lookup === $relationship_table_column['column_name'] ) {
251 if ( 'varchar' === $relationship_table_column['data_type'] || 'enum' === $relationship_table_column['data_type'] ) {
252 if ( '' === $this->schema_name ) {
253 $lookup_sql_table_name = "`$target_table_name`";
254 } else {
255 $lookup_sql_table_name = "`{$this->schema_name}`.`$target_table_name`";
256 }
257 $where_current_prepare = "`{$column_option->column_name}` in (select `$target_column_name` from $lookup_sql_table_name where `{$column_option->lookup}` like %s)";
258 if ( ! $where_first ) {
259 $where_current .= ' or ';
260 }
261 $where_current .= $wpdb->prepare( $where_current_prepare, $search_values ); // phpcs:ignore WordPress.DB.PreparedSQL
262 $where_first = false;
263 }
264 break;
265 }
266 }
267 }
268 }
269 }
270 } else {
271 // This is already handled by the parent.
272 }
273 }
274
275 $where_user_search = $this->get_where_clause();
276 if ( '' !== $where_user_search ) {
277 if ( '' === $where_current ) {
278 $where_current = $where_user_search;
279 } else {
280 $where_current = "($where_current or $where_user_search)";
281 }
282 }
283
284 if ( '' !== $where_current ) {
285 $this->where = $nowhere ? " where $where_current " : " {$this->where} and ($where_current) ";
286 $perform_default_method = false;
287 }
288 }
289 }
290
291 if ( $perform_default_method ) {
292 parent::construct_where_clause();
293 } else {
294 $whereclause = $this->get_where_clause();
295
296 if ( '' === $this->where ) {
297 $this->where = " where {$whereclause} ";
298 }
299
300 if ( ' (1=2) ' !== $whereclause ) {
301 // TODO Add other (non lookup) columns
302 // $this->where .= " and {$whereclause} "; // Needs to be tested
303 }
304 }
305 }
306
307 protected function get_order_by() {
308 $orderby = parent::get_order_by();
309
310 if ( '' === $orderby && null !== $this->orderby && '' !== trim( $this->orderby ) ) {
311 $orderby =
312 ' order by ' .
313 trim( str_replace( 'order by ', '', $this->orderby ) );
314 }
315
316 return $orderby;
317 }
318
319 protected function add_full_table_downloads_add_args() {
320 if ( $this->has_default_where && '' !== trim( $this->page_id ) ) {
321 $esc_attr = 'esc_attr';
322 echo "<input type='hidden' name='pid_default_where' value='{$esc_attr( $this->page_id )}'/>";
323 }
324 }
325
326 }
327
328 }
329