Complex classes like GF_Form often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use GF_Form, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 14 | class GF_Form extends Form implements \ArrayAccess { |
||
|
|
|||
| 15 | |||
| 16 | /** |
||
| 17 | * @var string The identifier of the backend used for this form. |
||
| 18 | * @api |
||
| 19 | * @since 2.0 |
||
| 20 | */ |
||
| 21 | public static $backend = self::BACKEND_GRAVITYFORMS; |
||
| 22 | |||
| 23 | /** |
||
| 24 | * Initialization. |
||
| 25 | */ |
||
| 26 | 181 | private function __construct() { |
|
| 31 | |||
| 32 | /** |
||
| 33 | * Construct a \GV\GF_Form instance by ID. |
||
| 34 | * |
||
| 35 | * @param int|string $form_id The internal form ID. |
||
| 36 | * |
||
| 37 | * @api |
||
| 38 | * @since 2.0 |
||
| 39 | * @return \GV\GF_Form|null An instance of this form or null if not found. |
||
| 40 | */ |
||
| 41 | 182 | public static function by_id( $form_id ) { |
|
| 62 | |||
| 63 | /** |
||
| 64 | * Construct a \GV\Form instance from a Gravity Forms form array. |
||
| 65 | * |
||
| 66 | * @since 2.0.7 |
||
| 67 | * |
||
| 68 | * @param array $form The form array |
||
| 69 | * |
||
| 70 | * @return \GV\GF_Form|null An instance of this form or null if not found. |
||
| 71 | */ |
||
| 72 | public static function from_form( $form ) { |
||
| 83 | |||
| 84 | /** |
||
| 85 | * Return the query class for this View. |
||
| 86 | * |
||
| 87 | * @return string The class name. |
||
| 88 | */ |
||
| 89 | 72 | public function get_query_class( $view ) { |
|
| 98 | |||
| 99 | /** |
||
| 100 | * Get all entries for this form. |
||
| 101 | * |
||
| 102 | * @api |
||
| 103 | * @since 2.0 |
||
| 104 | * |
||
| 105 | * @param \GV\View $view The View context. |
||
| 106 | * |
||
| 107 | * @return \GV\Entry_Collection The \GV\Entry_Collection |
||
| 108 | */ |
||
| 109 | 72 | public function get_entries( $view ) { |
|
| 110 | 72 | $entries = new \GV\Entry_Collection(); |
|
| 111 | |||
| 112 | 72 | $form = &$this; |
|
| 113 | |||
| 114 | 72 | if ( gravityview()->plugin->supports( Plugin::FEATURE_GFQUERY ) ) { // @todo switch to GFAPI:: once they start supporting nested and joins stuff |
|
| 115 | $entries->add_fetch_callback( function( $filters, $sorts, $offset ) use ( $view, &$form ) { |
||
| 116 | 72 | $atts = $view->settings->as_atts(); |
|
| 117 | |||
| 118 | 72 | $entries = new \GV\Entry_Collection(); |
|
| 119 | |||
| 120 | 72 | $search_criteria = array(); |
|
| 121 | 72 | $sorting = array(); |
|
| 122 | 72 | $paging = array(); |
|
| 123 | |||
| 124 | /** Apply the filters */ |
||
| 125 | 72 | foreach ( $filters as $filter ) { |
|
| 126 | 72 | $search_criteria = $filter::merge_search_criteria( $search_criteria, $filter->as_search_criteria() ); |
|
| 127 | } |
||
| 128 | |||
| 129 | /** Apply the sorts */ |
||
| 130 | 72 | foreach ( $sorts as $sort ) { |
|
| 131 | /** Gravity Forms does not have multi-sorting, so just overwrite. */ |
||
| 132 | $sorting = array( |
||
| 133 | 9 | 'key' => $sort->field->ID, |
|
| 134 | 9 | 'direction' => $sort->direction, |
|
| 135 | 9 | 'is_numeric' => $sort->mode == Entry_Sort::NUMERIC, |
|
| 136 | ); |
||
| 137 | } |
||
| 138 | |||
| 139 | /** The offset and limit */ |
||
| 140 | 72 | if ( ! empty( $offset->limit ) ) { |
|
| 141 | 72 | $paging['page_size'] = $offset->limit; |
|
| 142 | } |
||
| 143 | |||
| 144 | 72 | if ( ! empty( $offset->offset ) ) { |
|
| 145 | 2 | $paging['offset'] = $offset->offset; |
|
| 146 | } |
||
| 147 | |||
| 148 | 72 | $query_class = $form->get_query_class( $view ); |
|
| 149 | |||
| 150 | /** @var \GF_Query $query */ |
||
| 151 | 72 | $query = new $query_class( $form->ID, $search_criteria, $sorting, $paging ); |
|
| 152 | |||
| 153 | /** |
||
| 154 | * Apply multisort. |
||
| 155 | */ |
||
| 156 | 72 | if ( is_array( $sort_fields = \GV\Utils::get( $atts, 'sort_field' ) ) && ! empty( $sort_fields ) ) { |
|
| 157 | 2 | $view_setting_sort_field_ids = \GV\Utils::get( $atts, 'sort_field', array() ); |
|
| 158 | 2 | $view_setting_sort_directions = \GV\Utils::get( $atts, 'sort_direction', array() ); |
|
| 159 | |||
| 160 | 2 | $has_sort_query_param = ! empty( $_GET['sort'] ) && is_array( $_GET['sort'] ); |
|
| 161 | |||
| 162 | 2 | if( $has_sort_query_param ) { |
|
| 163 | $has_sort_query_param = array_filter( array_values( $_GET['sort'] ) ); |
||
| 164 | } |
||
| 165 | |||
| 166 | 2 | if ( $view->settings->get( 'sort_columns' ) && $has_sort_query_param ) { |
|
| 167 | $sort_field_ids = array_keys( $_GET['sort'] ); |
||
| 168 | $sort_directions = array_values( $_GET['sort'] ); |
||
| 169 | } else { |
||
| 170 | 2 | $sort_field_ids = $view_setting_sort_field_ids; |
|
| 171 | 2 | $sort_directions = $view_setting_sort_directions; |
|
| 172 | } |
||
| 173 | |||
| 174 | 2 | $skip_first = false; |
|
| 175 | |||
| 176 | 2 | foreach ( (array) $sort_field_ids as $key => $sort_field_id ) { |
|
| 177 | |||
| 178 | 2 | if ( ! $skip_first && ! $has_sort_query_param ) { |
|
| 179 | 2 | $skip_first = true; // Skip the first one, it's already in the query |
|
| 180 | 2 | continue; |
|
| 181 | } |
||
| 182 | |||
| 183 | 1 | $sort_field_id = \GravityView_frontend::_override_sorting_id_by_field_type( $sort_field_id, $form->ID ); |
|
| 184 | 1 | $sort_direction = strtoupper( \GV\Utils::get( $sort_directions, $key, 'ASC' ) ); |
|
| 185 | |||
| 186 | 1 | if ( ! empty( $sort_field_id ) ) { |
|
| 187 | 1 | $order = new \GF_Query_Column( $sort_field_id, $form->ID ); |
|
| 188 | 1 | if ( \GVCommon::is_field_numeric( $form->ID, $sort_field_id ) ) { |
|
| 189 | $order = \GF_Query_Call::CAST( $order, defined( 'GF_Query::TYPE_DECIMAL' ) ? \GF_Query::TYPE_DECIMAL : \GF_Query::TYPE_SIGNED ); |
||
| 190 | } |
||
| 191 | |||
| 192 | 1 | $query->order( $order, $sort_direction ); |
|
| 193 | } |
||
| 194 | } |
||
| 195 | } |
||
| 196 | |||
| 197 | /** |
||
| 198 | * Merge time subfield sorts. |
||
| 199 | */ |
||
| 200 | add_filter( 'gform_gf_query_sql', $gf_query_timesort_sql_callback = function( $sql ) use ( &$query ) { |
||
| 201 | 72 | $q = $query->_introspect(); |
|
| 202 | 72 | $orders = array(); |
|
| 203 | |||
| 204 | 72 | $merged_time = false; |
|
| 205 | |||
| 206 | 72 | foreach ( $q['order'] as $oid => $order ) { |
|
| 207 | 72 | if ( $order[0] instanceof \GF_Query_Column ) { |
|
| 208 | 72 | $column = $order[0]; |
|
| 209 | } else if ( $order[0] instanceof \GF_Query_Call ) { |
||
| 210 | if ( count( $order[0]->columns ) != 1 || ! $order[0]->columns[0] instanceof \GF_Query_Column ) { |
||
| 211 | $orders[ $oid ] = $order; |
||
| 212 | continue; // Need something that resembles a single sort |
||
| 213 | } |
||
| 214 | $column = $order[0]->columns[0]; |
||
| 215 | } |
||
| 216 | |||
| 217 | 72 | if ( ( ! $field = \GFAPI::get_field( $column->source, $column->field_id ) ) || $field->type !== 'time' ) { |
|
| 218 | 71 | $orders[ $oid ] = $order; |
|
| 219 | 71 | continue; // Not a time field |
|
| 220 | } |
||
| 221 | |||
| 222 | 1 | if ( ! class_exists( '\GV\Mocks\GF_Query_Call_TIMESORT' ) ) { |
|
| 223 | 1 | require_once gravityview()->plugin->dir( 'future/_mocks.timesort.php' ); |
|
| 224 | } |
||
| 225 | |||
| 226 | 1 | $orders[ $oid ] = array( |
|
| 227 | 1 | new \GV\Mocks\GF_Query_Call_TIMESORT( 'timesort', array( $column, $sql ) ), |
|
| 228 | 1 | $order[1] // Mock it! |
|
| 229 | ); |
||
| 230 | |||
| 231 | 1 | $merged_time = true; |
|
| 232 | } |
||
| 233 | |||
| 234 | 72 | if ( $merged_time ) { |
|
| 235 | /** |
||
| 236 | * ORDER again. |
||
| 237 | */ |
||
| 238 | 1 | if ( ! empty( $orders ) && $_orders = $query->_order_generate( $orders ) ) { |
|
| 239 | 1 | $sql['order'] = 'ORDER BY ' . implode( ', ', $_orders ); |
|
| 240 | } |
||
| 241 | } |
||
| 242 | |||
| 243 | 72 | return $sql; |
|
| 244 | 72 | } ); |
|
| 245 | |||
| 246 | /** |
||
| 247 | * Any joins? |
||
| 248 | */ |
||
| 249 | 72 | if ( gravityview()->plugin->supports( Plugin::FEATURE_JOINS ) && count( $view->joins ) ) { |
|
| 250 | |||
| 251 | 12 | $is_admin_and_can_view = $view->settings->get( 'admin_show_all_statuses' ) && \GVCommon::has_cap( 'gravityview_moderate_entries', $view->ID ); |
|
| 252 | |||
| 253 | 12 | foreach ( $view->joins as $join ) { |
|
| 254 | 12 | $query = $join->as_query_join( $query ); |
|
| 255 | |||
| 256 | 12 | if ( $view->settings->get( 'multiple_forms_disable_null_joins' ) ) { |
|
| 257 | |||
| 258 | // Disable NULL outputs |
||
| 259 | $condition = new \GF_Query_Condition( |
||
| 260 | new \GF_Query_Column( $join->join_on_column->ID, $join->join_on->ID ), |
||
| 261 | \GF_Query_Condition::NEQ, |
||
| 262 | new \GF_Query_Literal( '' ) |
||
| 263 | ); |
||
| 264 | |||
| 265 | $query_parameters = $query->_introspect(); |
||
| 266 | |||
| 267 | $query->where( \GF_Query_Condition::_and( $query_parameters['where'], $condition ) ); |
||
| 268 | } |
||
| 269 | |||
| 270 | /** |
||
| 271 | * This is a temporary stub filter, until GF_Query supports NULL conditions. |
||
| 272 | * Do not use! This filter will be removed. |
||
| 273 | */ |
||
| 274 | 12 | if ( defined( 'GF_Query_Condition::NULL' ) ) { |
|
| 275 | 12 | $is_null_condition_native = true; |
|
| 276 | } else { |
||
| 277 | $is_null_condition_class = apply_filters( 'gravityview/query/is_null_condition', null ); |
||
| 278 | $is_null_condition_native = false; |
||
| 279 | } |
||
| 280 | |||
| 281 | // Filter to active entries only |
||
| 282 | 12 | $condition = new \GF_Query_Condition( |
|
| 283 | 12 | new \GF_Query_Column( 'status', $join->join_on->ID ), |
|
| 284 | 12 | \GF_Query_Condition::EQ, |
|
| 285 | 12 | new \GF_Query_Literal( 'active' ) |
|
| 286 | ); |
||
| 287 | |||
| 288 | 12 | if ( $is_null_condition_native ) { |
|
| 289 | 12 | $condition = \GF_Query_Condition::_or( $condition, new \GF_Query_Condition( |
|
| 290 | 12 | new \GF_Query_Column( 'status', $join->join_on->ID ), |
|
| 291 | 12 | \GF_Query_Condition::IS, |
|
| 292 | 12 | \GF_Query_Condition::NULL |
|
| 293 | ) ); |
||
| 294 | } else if ( ! is_null( $is_null_condition_class ) ) { |
||
| 295 | $condition = \GF_Query_Condition::_or( $condition, new $is_null_condition_class( |
||
| 296 | new \GF_Query_Column( 'status', $join->join_on->ID ) |
||
| 297 | ) ); |
||
| 298 | } |
||
| 299 | |||
| 300 | 12 | $q = $query->_introspect(); |
|
| 301 | 12 | $query->where( \GF_Query_Condition::_and( $q['where'], $condition ) ); |
|
| 302 | |||
| 303 | 12 | if ( $view->settings->get( 'show_only_approved' ) && ! $is_admin_and_can_view ) { |
|
| 304 | |||
| 305 | // Show only approved joined entries |
||
| 306 | 1 | $condition = new \GF_Query_Condition( |
|
| 307 | 1 | new \GF_Query_Column( \GravityView_Entry_Approval::meta_key, $join->join_on->ID ), |
|
| 308 | 1 | \GF_Query_Condition::EQ, |
|
| 309 | 1 | new \GF_Query_Literal( \GravityView_Entry_Approval_Status::APPROVED ) |
|
| 310 | ); |
||
| 311 | |||
| 312 | 1 | if ( $is_null_condition_native ) { |
|
| 313 | 1 | $condition = \GF_Query_Condition::_or( $condition, new \GF_Query_Condition( |
|
| 314 | 1 | new \GF_Query_Column( \GravityView_Entry_Approval::meta_key, $join->join_on->ID ), |
|
| 315 | 1 | \GF_Query_Condition::IS, |
|
| 316 | 1 | \GF_Query_Condition::NULL |
|
| 317 | ) ); |
||
| 318 | } else if ( ! is_null( $is_null_condition_class ) ) { |
||
| 319 | $condition = \GF_Query_Condition::_or( $condition, new $is_null_condition_class( |
||
| 320 | new \GF_Query_Column( \GravityView_Entry_Approval::meta_key, $join->join_on->ID ) |
||
| 321 | ) ); |
||
| 322 | } |
||
| 323 | |||
| 324 | 1 | $query_parameters = $query->_introspect(); |
|
| 325 | |||
| 326 | 1 | $query->where( \GF_Query_Condition::_and( $query_parameters['where'], $condition ) ); |
|
| 327 | } |
||
| 328 | } |
||
| 329 | /** |
||
| 330 | * Unions? |
||
| 331 | */ |
||
| 332 | 60 | } else if ( gravityview()->plugin->supports( Plugin::FEATURE_UNIONS ) && count( $view->unions ) ) { |
|
| 333 | 1 | $query_parameters = $query->_introspect(); |
|
| 334 | |||
| 335 | 1 | $unions_sql = array(); |
|
| 336 | |||
| 337 | /** |
||
| 338 | * @param \GF_Query_Condition $condition |
||
| 339 | * @param array $fields |
||
| 340 | * @param $recurse |
||
| 341 | * |
||
| 342 | * @return \GF_Query_Condition |
||
| 343 | */ |
||
| 344 | $where_union_substitute = function( $condition, $fields, $recurse ) { |
||
| 345 | 1 | if ( $condition->expressions ) { |
|
| 346 | 1 | $conditions = array(); |
|
| 347 | |||
| 348 | 1 | foreach ( $condition->expressions as $_condition ) { |
|
| 349 | 1 | $conditions[] = $recurse( $_condition, $fields, $recurse ); |
|
| 350 | } |
||
| 351 | |||
| 352 | 1 | return call_user_func_array( |
|
| 353 | 1 | array( '\GF_Query_Condition', $condition->operator == 'AND' ? '_and' : '_or' ), |
|
| 354 | 1 | $conditions |
|
| 355 | ); |
||
| 356 | } |
||
| 357 | |||
| 358 | 1 | if ( ! ( $condition->left && $condition->left instanceof \GF_Query_Column ) || ( ! $condition->left->is_entry_column() && ! $condition->left->is_meta_column() ) ) { |
|
| 359 | 1 | return new \GF_Query_Condition( |
|
| 360 | 1 | new \GF_Query_Column( $fields[ $condition->left->field_id ]->ID ), |
|
| 361 | 1 | $condition->operator, |
|
| 362 | 1 | $condition->right |
|
| 363 | ); |
||
| 364 | } |
||
| 365 | |||
| 366 | 1 | return $condition; |
|
| 367 | 1 | }; |
|
| 368 | |||
| 369 | 1 | foreach ( $view->unions as $form_id => $fields ) { |
|
| 370 | |||
| 371 | // Build a new query for every unioned form |
||
| 372 | |||
| 373 | /** @var \GF_Query|\GF_Patched_Query $q */ |
||
| 374 | 1 | $q = new $query_class( $form_id ); |
|
| 375 | |||
| 376 | // Copy the WHERE clauses but substitute the field_ids to the respective ones |
||
| 377 | 1 | $q->where( $where_union_substitute( $query_parameters['where'], $fields, $where_union_substitute ) ); |
|
| 378 | |||
| 379 | // Copy the ORDER clause and substitute the field_ids to the respective ones |
||
| 380 | 1 | foreach ( $query_parameters['order'] as $order ) { |
|
| 381 | 1 | list( $column, $_order ) = $order; |
|
| 382 | |||
| 383 | 1 | if ( $column && $column instanceof \GF_Query_Column ) { |
|
| 384 | 1 | if ( ! $column->is_entry_column() && ! $column->is_meta_column() ) { |
|
| 385 | 1 | $column = new \GF_Query_Column( $fields[ $column->field_id ]->ID ); |
|
| 386 | } |
||
| 387 | |||
| 388 | 1 | $q->order( $column, $_order ); |
|
| 389 | } |
||
| 390 | } |
||
| 391 | |||
| 392 | add_filter( 'gform_gf_query_sql', $gf_query_sql_callback = function( $sql ) use ( &$unions_sql ) { |
||
| 393 | // Remove SQL_CALC_FOUND_ROWS as it's not needed in UNION clauses |
||
| 394 | 1 | $select = 'UNION ALL ' . str_replace( 'SQL_CALC_FOUND_ROWS ', '', $sql['select'] ); |
|
| 395 | |||
| 396 | // Record the SQL |
||
| 397 | 1 | $unions_sql[] = array( |
|
| 398 | // Remove columns, we'll rebuild them |
||
| 399 | 1 | 'select' => preg_replace( '#DISTINCT (.*)#', 'DISTINCT ', $select ), |
|
| 400 | 1 | 'from' => $sql['from'], |
|
| 401 | 1 | 'join' => $sql['join'], |
|
| 402 | 1 | 'where' => $sql['where'], |
|
| 403 | // Remove order and limit |
||
| 404 | ); |
||
| 405 | |||
| 406 | // Return empty query, no need to call the database |
||
| 407 | 1 | return array(); |
|
| 408 | 1 | } ); |
|
| 409 | |||
| 410 | 1 | do_action_ref_array( 'gravityview/view/query', array( &$q, $view, gravityview()->request ) ); |
|
| 411 | |||
| 412 | 1 | $q->get(); // Launch |
|
| 413 | |||
| 414 | 1 | remove_filter( 'gform_gf_query_sql', $gf_query_sql_callback ); |
|
| 415 | } |
||
| 416 | |||
| 417 | add_filter( 'gform_gf_query_sql', $gf_query_sql_callback = function( $sql ) use ( $unions_sql ) { |
||
| 418 | // Remove SQL_CALC_FOUND_ROWS as it's not needed in UNION clauses |
||
| 419 | 1 | $sql['select'] = str_replace( 'SQL_CALC_FOUND_ROWS ', '', $sql['select'] ); |
|
| 420 | |||
| 421 | // Remove columns, we'll rebuild them |
||
| 422 | 1 | preg_match( '#DISTINCT (`[motc]\d+`.`.*?`)#', $sql['select'], $select_match ); |
|
| 423 | 1 | $sql['select'] = preg_replace( '#DISTINCT (.*)#', 'DISTINCT ', $sql['select'] ); |
|
| 424 | |||
| 425 | 1 | $unions = array(); |
|
| 426 | |||
| 427 | // Transform selected columns to shared alias names |
||
| 428 | $column_to_alias = function( $column ) { |
||
| 429 | 1 | $column = str_replace( '`', '', $column ); |
|
| 430 | 1 | return '`' . str_replace( '.', '_', $column ) . '`'; |
|
| 431 | 1 | }; |
|
| 432 | |||
| 433 | // Add all the order columns into the selects, so we can order by the whole union group |
||
| 434 | 1 | preg_match_all( '#(`[motc]\d+`.`.*?`)#', $sql['order'], $order_matches ); |
|
| 435 | |||
| 436 | $columns = array( |
||
| 437 | 1 | sprintf( '%s AS %s', $select_match[1], $column_to_alias( $select_match[1] ) ) |
|
| 438 | ); |
||
| 439 | |||
| 440 | 1 | foreach ( array_slice( $order_matches, 1 ) as $match ) { |
|
| 441 | 1 | $columns[] = sprintf( '%s AS %s', $match[0], $column_to_alias( $match[0] ) ); |
|
| 442 | |||
| 443 | // Rewrite the order columns to the shared aliases |
||
| 444 | 1 | $sql['order'] = str_replace( $match[0], $column_to_alias( $match[0] ), $sql['order'] ); |
|
| 445 | } |
||
| 446 | |||
| 447 | 1 | $columns = array_unique( $columns ); |
|
| 448 | |||
| 449 | // Add the columns to every UNION |
||
| 450 | 1 | foreach ( $unions_sql as $union_sql ) { |
|
| 451 | 1 | $union_sql['select'] .= implode( ', ', $columns ); |
|
| 452 | 1 | $unions []= implode( ' ', $union_sql ); |
|
| 453 | } |
||
| 454 | |||
| 455 | // Add the columns to the main SELECT, but only grab the entry id column |
||
| 456 | 1 | $sql['select'] = 'SELECT SQL_CALC_FOUND_ROWS t1_id FROM (' . $sql['select'] . implode( ', ', $columns ); |
|
| 457 | 1 | $sql['order'] = implode( ' ', $unions ) . ') AS u ' . $sql['order']; |
|
| 458 | |||
| 459 | 1 | return $sql; |
|
| 460 | 1 | } ); |
|
| 461 | } |
||
| 462 | |||
| 463 | /** |
||
| 464 | * @action `gravityview/view/query` Override the \GF_Query before the get() call. |
||
| 465 | * @param \GF_Query $query The current query object reference |
||
| 466 | * @param \GV\View $view The current view object |
||
| 467 | * @param \GV\Request $request The request object |
||
| 468 | */ |
||
| 469 | 72 | do_action_ref_array( 'gravityview/view/query', array( &$query, $view, gravityview()->request ) ); |
|
| 470 | |||
| 471 | 72 | gravityview()->log->debug( 'GF_Query parameters: ', array( 'data' => Utils::gf_query_debug( $query ) ) ); |
|
| 472 | |||
| 473 | /** |
||
| 474 | * Map from Gravity Forms entries arrays to an Entry_Collection. |
||
| 475 | */ |
||
| 476 | 72 | if ( count( $view->joins ) ) { |
|
| 477 | 12 | foreach ( $query->get() as $entry ) { |
|
| 478 | 12 | $entries->add( |
|
| 479 | 12 | Multi_Entry::from_entries( array_map( '\GV\GF_Entry::from_entry', $entry ) ) |
|
| 480 | ); |
||
| 481 | } |
||
| 482 | } else { |
||
| 483 | 60 | array_map( array( $entries, 'add' ), array_map( '\GV\GF_Entry::from_entry', $query->get() ) ); |
|
| 484 | } |
||
| 485 | |||
| 486 | 72 | if ( isset( $gf_query_sql_callback ) ) { |
|
| 487 | 1 | remove_action( 'gform_gf_query_sql', $gf_query_sql_callback ); |
|
| 488 | } |
||
| 489 | |||
| 490 | 72 | if ( isset( $gf_query_timesort_sql_callback ) ) { |
|
| 491 | 72 | remove_action( 'gform_gf_query_sql', $gf_query_timesort_sql_callback ); |
|
| 492 | } |
||
| 493 | |||
| 494 | 72 | return $entries; |
|
| 495 | 72 | } ); |
|
| 496 | |||
| 497 | $entries->add_count_callback( function( $filters ) use ( $entries ) { |
||
| 498 | 32 | $query = null; |
|
| 499 | |||
| 500 | add_action( 'gravityview/view/query', $q_callback = function( &$q ) use ( &$query ) { |
||
| 501 | 32 | $query = $q; |
|
| 502 | 32 | } ); |
|
| 503 | |||
| 504 | 32 | foreach ( $filters as $filter ) { |
|
| 505 | 32 | $entries = $entries->filter( $filter ); |
|
| 506 | } |
||
| 507 | 32 | $entries->fetch(); // Gravity Forms requires a fetch before total can be had |
|
| 508 | |||
| 509 | 32 | remove_action( 'gravityview/view/query', $q_callback ); |
|
| 510 | |||
| 511 | 32 | if ( ! is_object( $query ) ) { |
|
| 512 | return 0; |
||
| 513 | } |
||
| 514 | |||
| 515 | 32 | return $query->total_found; |
|
| 516 | 72 | } ); |
|
| 517 | } else { |
||
| 518 | /** Add the fetcher lazy callback. */ |
||
| 519 | $entries->add_fetch_callback( function( $filters, $sorts, $offset ) use ( $form ) { |
||
| 520 | $entries = new \GV\Entry_Collection(); |
||
| 521 | |||
| 522 | $search_criteria = array(); |
||
| 523 | $sorting = array(); |
||
| 524 | $paging = array(); |
||
| 525 | |||
| 526 | /** Apply the filters */ |
||
| 527 | foreach ( $filters as $filter ) { |
||
| 528 | $search_criteria = $filter::merge_search_criteria( $search_criteria, $filter->as_search_criteria() ); |
||
| 529 | } |
||
| 530 | |||
| 531 | /** Apply the sorts */ |
||
| 532 | foreach ( $sorts as $sort ) { |
||
| 533 | /** Gravity Forms does not have multi-sorting, so just overwrite. */ |
||
| 534 | $sorting = array( |
||
| 535 | 'key' => $sort->field->ID, |
||
| 536 | 'direction' => $sort->direction, |
||
| 537 | 'is_numeric' => $sort->mode == Entry_Sort::NUMERIC, |
||
| 538 | ); |
||
| 539 | } |
||
| 540 | |||
| 541 | /** The offset and limit */ |
||
| 542 | if ( ! empty( $offset->limit ) ) { |
||
| 543 | $paging['page_size'] = $offset->limit; |
||
| 544 | } |
||
| 545 | |||
| 546 | if ( ! empty( $offset->offset ) ) { |
||
| 547 | $paging['offset'] = $offset->offset; |
||
| 548 | } |
||
| 549 | |||
| 550 | foreach ( \GFAPI::get_entries( $form->ID, $search_criteria, $sorting, $paging ) as $entry ) { |
||
| 551 | $entries->add( \GV\GF_Entry::from_entry( $entry ) ); |
||
| 552 | } |
||
| 553 | |||
| 554 | return $entries; |
||
| 555 | } ); |
||
| 556 | |||
| 557 | /** Add the counter lazy callback. */ |
||
| 558 | $entries->add_count_callback( function( $filters ) use ( $form ) { |
||
| 559 | $search_criteria = array(); |
||
| 560 | $sorting = array(); |
||
| 561 | |||
| 562 | /** Apply the filters */ |
||
| 563 | /** @var \GV\GF_Entry_Filter|\GV\Entry_Filter $filter */ |
||
| 564 | foreach ( $filters as $filter ) { |
||
| 565 | $search_criteria = $filter::merge_search_criteria( $search_criteria, $filter->as_search_criteria() ); |
||
| 566 | } |
||
| 567 | |||
| 568 | return \GFAPI::count_entries( $form->ID, $search_criteria ); |
||
| 569 | } ); |
||
| 570 | } |
||
| 571 | |||
| 572 | 72 | return $entries; |
|
| 573 | } |
||
| 574 | |||
| 575 | /** |
||
| 576 | * Get a \GV\Field by Form and Field ID for this data source. |
||
| 577 | * |
||
| 578 | * @param \GV\GF_Form $form The Gravity Form form ID. |
||
| 579 | * @param int $field_id The Gravity Form field ID for the $form_id. |
||
| 580 | * |
||
| 581 | * @return \GV\Field|null The requested field or null if not found. |
||
| 582 | */ |
||
| 583 | 3 | public static function get_field( /** varargs */ ) { |
|
| 597 | |||
| 598 | /** |
||
| 599 | * Get an array of GV Fields for this data source |
||
| 600 | * |
||
| 601 | * @return \GV\Field[]|array Empty array if no fields |
||
| 602 | */ |
||
| 603 | public function get_fields() { |
||
| 617 | |||
| 618 | /** |
||
| 619 | * Proxies. |
||
| 620 | * |
||
| 621 | * @param string $key The property to get. |
||
| 622 | * |
||
| 623 | * @return mixed |
||
| 624 | */ |
||
| 625 | public function __get( $key ) { |
||
| 633 | |||
| 634 | /** |
||
| 635 | * ArrayAccess compatibility layer with a Gravity Forms form array. |
||
| 636 | * |
||
| 637 | * @internal |
||
| 638 | * @deprecated |
||
| 639 | * @since 2.0 |
||
| 640 | * @return bool Whether the offset exists or not. |
||
| 641 | */ |
||
| 642 | 27 | public function offsetExists( $offset ) { |
|
| 645 | |||
| 646 | /** |
||
| 647 | * ArrayAccess compatibility layer with a Gravity Forms form array. |
||
| 648 | * |
||
| 649 | * Maps the old keys to the new data; |
||
| 650 | * |
||
| 651 | * @internal |
||
| 652 | * @deprecated |
||
| 653 | * @since 2.0 |
||
| 654 | * |
||
| 655 | * @return mixed The value of the requested form data. |
||
| 656 | */ |
||
| 657 | 20 | public function offsetGet( $offset ) { |
|
| 660 | |||
| 661 | /** |
||
| 662 | * ArrayAccess compatibility layer with a Gravity Forms form array. |
||
| 663 | * |
||
| 664 | * @internal |
||
| 665 | * @deprecated |
||
| 666 | * @since 2.0 |
||
| 667 | * |
||
| 668 | * @return void |
||
| 669 | */ |
||
| 670 | public function offsetSet( $offset, $value ) { |
||
| 673 | |||
| 674 | /** |
||
| 675 | * ArrayAccess compatibility layer with a Gravity Forms form array. |
||
| 676 | * |
||
| 677 | * @internal |
||
| 678 | * @deprecated |
||
| 679 | * @since 2.0 |
||
| 680 | * @return void |
||
| 681 | */ |
||
| 682 | public function offsetUnset( $offset ) { |
||
| 685 | } |
||
| 686 |