5 if ( ! defined(
'GRAVITYVIEW_DIR' ) ) {
17 class View implements \ArrayAccess {
77 private static $cache = array();
85 public $joins = array();
102 public $unions = array();
122 if ( post_type_exists(
'gravityview' ) ) {
132 $is_hierarchical = (bool)apply_filters(
'gravityview_is_hierarchical',
false );
134 $supports = array(
'title',
'revisions' );
136 if ( $is_hierarchical ) {
137 $supports[] =
'page-attributes';
147 $supports = apply_filters(
'gravityview_post_type_support', $supports, $is_hierarchical );
151 'name' => _x(
'Views',
'Post Type General Name',
'gk-gravityview' ),
152 'singular_name' => _x(
'View',
'Post Type Singular Name',
'gk-gravityview' ),
153 'menu_name' => _x(
'Views',
'Menu name',
'gk-gravityview' ),
154 'parent_item_colon' => __(
'Parent View:',
'gk-gravityview' ),
155 'all_items' => __(
'All Views',
'gk-gravityview' ),
156 'view_item' => _x(
'View',
'View Item',
'gk-gravityview' ),
157 'add_new_item' => __(
'Add New View',
'gk-gravityview' ),
158 'add_new' => __(
'New View',
'gk-gravityview' ),
159 'edit_item' => __(
'Edit View',
'gk-gravityview' ),
160 'update_item' => __(
'Update View',
'gk-gravityview' ),
161 'search_items' => __(
'Search Views',
'gk-gravityview' ),
163 'not_found_in_trash' => __(
'No Views found in Trash',
'gk-gravityview' ),
164 'filter_items_list' => __(
'Filter Views list',
'gk-gravityview' ),
165 'items_list_navigation' => __(
'Views list navigation',
'gk-gravityview' ),
166 'items_list' => __(
'Views list',
'gk-gravityview' ),
167 'view_items' => __(
'See Views',
'gk-gravityview' ),
168 'attributes' => __(
'View Attributes',
'gk-gravityview' ),
169 'item_updated' => __(
'View updated.',
'gk-gravityview' ),
170 'item_published' => __(
'View published.',
'gk-gravityview' ),
171 'item_reverted_to_draft' => __(
'View reverted to draft.',
'gk-gravityview' ),
172 'item_scheduled' => __(
'View scheduled.',
'gk-gravityview' ),
176 'label' => __(
'view',
'gk-gravityview' ),
177 'description' => __(
'Create views based on a Gravity Forms form',
'gk-gravityview' ),
179 'supports' => $supports,
180 'hierarchical' => $is_hierarchical,
188 'public' => apply_filters(
'gravityview_direct_access',
gravityview()->plugin->is_compatible(), 0 ),
189 'show_ui' =>
gravityview()->plugin->is_compatible(),
190 'show_in_menu' =>
false,
191 'show_in_nav_menus' =>
true,
192 'show_in_admin_bar' =>
true,
193 'menu_position' => 17,
195 'can_export' =>
true,
201 'has_archive' => apply_filters(
'gravityview_has_archive',
false ),
202 'exclude_from_search' =>
true,
209 'slug' => apply_filters(
'gravityview_slug',
'view' ),
220 'with_front' => apply_filters(
'gravityview/post_type/with_front',
true ),
222 'capability_type' =>
'gravityview',
223 'map_meta_cap' =>
true,
226 register_post_type(
'gravityview',
$args );
240 $slug = apply_filters(
'gravityview_slug',
'view' );
241 $slug = (
'/' !== $wp_rewrite->front ) ? sprintf(
'%s/%s', trim( $wp_rewrite->front,
'/' ), $slug ) : $slug;
242 $csv_rule = array( sprintf(
'%s/([^/]+)/csv/?', $slug ),
'index.php?gravityview=$matches[1]&csv=1',
'top' );
243 $tsv_rule = array( sprintf(
'%s/([^/]+)/tsv/?', $slug ),
'index.php?gravityview=$matches[1]&tsv=1',
'top' );
245 add_filter(
'query_vars',
function( $query_vars ) {
246 $query_vars[] =
'csv';
247 $query_vars[] =
'tsv';
251 if ( ! isset( $wp_rewrite->extra_rules_top[ $csv_rule[0] ] ) ) {
252 call_user_func_array(
'add_rewrite_rule', $csv_rule );
253 call_user_func_array(
'add_rewrite_rule', $tsv_rule );
268 if ( ! defined(
'DOING_GRAVITYVIEW_TESTS' ) ) {
269 if ( ! did_action(
'loop_start' ) ) {
270 gravityview()->log->debug(
'Not processing yet: loop_start hasn\'t run yet. Current action: {action}', array(
'action' => current_filter() ) );
275 remove_filter(
'the_content', array( __CLASS__, __METHOD__ ) );
284 if ( ! $view = $request->is_view() ) {
291 while ( $error = $view->can_render( null, $request ) ) {
292 if ( ! is_wp_error( $error ) )
295 switch ( str_replace(
'gravityview/',
'', $error->get_error_code() ) ) {
296 case 'post_password_required':
297 return get_the_password_form( $view->ID );
298 case 'no_form_attached':
300 gravityview()->log->error(
'View #{view_id} cannot render: {error_code} {error_message}', array(
'error_code' => $error->get_error_code(),
'error_message' => $error->get_error_message() ) );
306 if ( \
GVCommon::has_cap( array(
'edit_gravityviews',
'edit_gravityview' ), $view->ID ) ) {
308 $title = sprintf( __(
'This View is not configured properly. Start by <a href="%s">selecting a form</a>.',
'gk-gravityview' ), esc_url( get_edit_post_link( $view->ID,
false ) ) );
310 $message = esc_html__(
'You can only see this message because you are able to edit this View.',
'gk-gravityview' );
312 $image = sprintf(
'<img alt="%s" src="%s" style="margin-top: 10px;" />', esc_attr__(
'Data Source',
'gk-gravityview' ), esc_url( plugins_url(
'assets/images/screenshots/data-source.png',
GRAVITYVIEW_FILE ) ) );
314 return \GVCommon::generate_notice(
'<h3>' .
$title .
'</h3>' . wpautop( $message .
$image ),
'notice' );
319 if ( \
GVCommon::has_cap( array(
'edit_gravityviews',
'edit_gravityview' ), $view->ID ) ) {
320 $notice = sprintf( __(
'This View is in the Trash. You can <a href="%s">restore the View here</a>.',
'gk-gravityview' ), esc_url( get_edit_post_link( $view->ID,
false ) ) );
322 return \GVCommon::generate_notice(
'<h3>' . $notice .
'</h3>',
'notice', array(
'edit_gravityviews',
'edit_gravityview' ), $view->ID );
327 case 'no_direct_access':
331 gravityview()->log->notice(
'View #{view_id} cannot render: {error_code} {error_message}', array(
'error_code' => $error->get_error_code(),
'error_message' => $error->get_error_message() ) );
332 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
338 $is_admin_and_can_view = $view->settings->get(
'admin_show_all_statuses' ) &&
\GVCommon::has_cap(
'gravityview_moderate_entries', $view->ID );
343 if (
$entry = $request->is_edit_entry( $view->form ? $view->form->ID : 0 ) ) {
344 if (
$entry[
'status'] !=
'active' ) {
345 gravityview()->log->notice(
'Entry ID #{entry_id} is not active', array(
'entry_id' =>
$entry->ID ) );
346 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
349 if ( apply_filters(
'gravityview_custom_entry_slug',
false ) &&
$entry->slug != get_query_var( \
GV\Entry::get_endpoint_name() ) ) {
350 gravityview()->log->error(
'Entry ID #{entry_id} was accessed by a bad slug', array(
'entry_id' =>
$entry->ID ) );
351 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
354 if ( $view->settings->get(
'show_only_approved' ) && ! $is_admin_and_can_view ) {
356 gravityview()->log->error(
'Entry ID #{entry_id} is not approved for viewing', array(
'entry_id' =>
$entry->ID ) );
357 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
362 return $renderer->render(
$entry, $view, $request );
367 }
else if (
$entry = $request->is_entry( $view->form ? $view->form->ID : 0 ) ) {
371 $custom_slug = apply_filters(
'gravityview_custom_entry_slug',
false );
372 $ids = explode(
',', get_query_var( \
GV\Entry::get_endpoint_name() ) );
374 $show_only_approved = $view->settings->get(
'show_only_approved' );
376 foreach ( $entryset as $e ) {
378 if (
'active' !== $e[
'status'] ) {
379 gravityview()->log->notice(
'Entry ID #{entry_id} is not active', array(
'entry_id' => $e->ID ) );
380 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
383 if ( $custom_slug && ! in_array( $e->slug, $ids ) ) {
384 gravityview()->log->error(
'Entry ID #{entry_id} was accessed by a bad slug', array(
'entry_id' => $e->ID ) );
385 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
388 if ( $show_only_approved && ! $is_admin_and_can_view ) {
390 gravityview()->log->error(
'Entry ID #{entry_id} is not approved for viewing', array(
'entry_id' => $e->ID ) );
391 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
397 if ( is_wp_error( $error ) ) {
398 gravityview()->log->error(
'Entry ID #{entry_id} is not approved for viewing: {message}', array(
'entry_id' => $e->ID,
'message' => $error->get_error_message() ) );
399 return __(
'You are not allowed to view this content.',
'gk-gravityview' );
404 return $renderer->render(
$entry, $view, $request );
411 return $renderer->render( $view, $request );
429 public function can_render( $context = null, $request = null ) {
434 if ( ! is_array( $context ) ) {
445 if ( ! is_null( $result = apply_filters(
'gravityview/view/can_render', null, $this, $context, $request ) ) ) {
449 if ( in_array(
'rest', $context ) ) {
451 if (
gravityview()->plugin->settings->get(
'rest_api' ) && $this->settings->get(
'rest_disable' ) ===
'1' ) {
452 return new \WP_Error(
'gravityview/rest_disabled' );
453 } elseif ( !
gravityview()->plugin->settings->get(
'rest_api' ) && $this->settings->get(
'rest_enable' ) !==
'1' ) {
454 return new \WP_Error(
'gravityview/rest_disabled' );
458 if ( in_array(
'csv', $context ) ) {
459 if ( $this->settings->get(
'csv_enable' ) !==
'1' ) {
460 return new \WP_Error(
'gravityview/csv_disabled',
'The CSV endpoint is not enabled for this View' );
467 if ( post_password_required( $this->ID ) ) {
468 gravityview()->log->notice(
'Post password is required for View #{view_id}', array(
'view_id' => $this->ID ) );
469 return new \WP_Error(
'gravityview/post_password_required' );
472 if ( ! $this->form ) {
473 gravityview()->log->notice(
'View #{id} has no form attached to it.', array(
'id' => $this->ID ) );
474 return new \WP_Error(
'gravityview/no_form_attached' );
477 if ( ! in_array(
'shortcode', $context ) ) {
490 $direct_access = apply_filters(
'gravityview_direct_access',
true, $this->ID );
499 if ( ! apply_filters(
'gravityview/view/output/direct', $direct_access, $this, $request ) ) {
500 return new \WP_Error(
'gravityview/no_direct_access' );
507 if ( $this->settings->get(
'embed_only' ) && !
\GVCommon::has_cap(
'read_private_gravityviews' ) ) {
508 return new \WP_Error(
'gravityview/embed_only' );
513 $public_states = get_post_stati( array(
'public' =>
true ) );
514 if ( ! in_array( $this->post_status, $public_states ) && ! \
GVCommon::has_cap(
'read_gravityview', $this->ID ) ) {
515 gravityview()->log->notice(
'The current user cannot access this View #{view_id}', array(
'view_id' => $this->ID ) );
516 return new \WP_Error(
'gravityview/not_public' );
535 if ( !
gravityview()->plugin->supports( Plugin::FEATURE_JOINS ) ) {
536 gravityview()->log->info(
'Cannot get joined forms; joins feature not supported.' );
540 if ( !
$post ||
'gravityview' !== get_post_type(
$post ) ) {
541 gravityview()->log->error(
'Only "gravityview" post types can be \GV\View instances.' );
545 $joins_meta = get_post_meta(
$post->ID,
'_gravityview_form_joins',
true );
547 if ( empty( $joins_meta ) ) {
551 foreach ( $joins_meta as $meta ) {
552 if ( ! is_array( $meta ) || count( $meta ) != 4 ) {
556 list( $join, $join_column, $join_on, $join_on_column ) = $meta;
558 $join = GF_Form::by_id( $join );
559 $join_on = GF_Form::by_id( $join_on );
561 $join_column = is_numeric( $join_column ) ? GF_Field::by_id( $join, $join_column ) : Internal_Field::by_id( $join_column );
562 $join_on_column = is_numeric( $join_on_column ) ? GF_Field::by_id( $join_on, $join_on_column ) : Internal_Field::by_id( $join_on_column );
564 $joins [] =
new Join( $join, $join_column, $join_on, $join_on_column );
585 if ( !
gravityview()->plugin->supports( Plugin::FEATURE_JOINS ) ) {
586 gravityview()->log->info(
'Cannot get joined forms; joins feature not supported.' );
590 if ( ! $post_id || !
gravityview()->plugin->supports( Plugin::FEATURE_JOINS ) ) {
594 if ( empty( $post_id ) ) {
595 gravityview()->log->error(
'Cannot get joined forms; $post_id was empty' );
599 $joins_meta = get_post_meta( $post_id,
'_gravityview_form_joins',
true );
601 if ( empty( $joins_meta ) ) {
605 foreach ( $joins_meta as $meta ) {
606 if ( ! is_array( $meta ) || count( $meta ) != 4 ) {
610 list( $join, $join_column, $join_on, $join_on_column ) = $meta;
612 if (
$form = GF_Form::by_id( $join_on ) ) {
616 if (
$form = GF_Form::by_id( $join ) ) {
637 if ( !
$post ||
'gravityview' !== get_post_type(
$post ) ) {
638 gravityview()->log->error(
'Only "gravityview" post types can be \GV\View instances.' );
642 $fields = get_post_meta(
$post->ID,
'_gravityview_directory_fields',
true );
644 if ( empty( $fields ) ) {
648 foreach ( $fields as $location => $_fields ) {
649 if ( strpos( $location,
'directory_' ) !== 0 ) {
653 foreach ( $_fields as
$field ) {
654 if ( ! empty( $field[
'unions'] ) ) {
656 if ( ! isset( $unions[
$form_id ] ) ) {
660 $unions[
$form_id ][ $field[
'id'] ] =
670 if ( !
gravityview()->plugin->supports( Plugin::FEATURE_UNIONS ) ) {
671 gravityview()->log->error(
'Cannot get unions; unions feature not supported.' );
691 if ( !
$post ||
'gravityview' !== get_post_type(
$post ) ) {
692 gravityview()->log->error(
'Only gravityview post types can be \GV\View instances.' );
696 if ( $view = Utils::get( self::$cache,
"View::from_post:{$post->ID}" ) ) {
702 do_action_ref_array(
'gravityview/view/get', array( &$view ) );
711 $view->form = GF_Form::by_id( $view->_gravityview_form_id );
713 if ( ! $view->form &&
'post-new.php' !== $pagenow ) {
714 gravityview()->log->error(
'View #{view_id} tried attaching non-existent Form #{form_id} to it.', array(
715 'view_id' => $view->ID,
716 'form_id' => $view->_gravityview_form_id ? : 0,
720 $view->joins = $view::get_joins(
$post );
722 $view->unions = $view::get_unions(
$post );
733 $configuration = apply_filters(
'gravityview/configuration/fields', (array)$view->_gravityview_directory_fields, $view->ID );
742 $configuration = apply_filters(
'gravityview/view/configuration/fields', $configuration, $view );
751 $view->fields = apply_filters(
'gravityview/view/fields', Field_Collection::from_configuration( $configuration ), $view );
760 $configuration = apply_filters(
'gravityview/view/configuration/widgets', (array)$view->_gravityview_directory_widgets, $view );
769 $view->widgets = apply_filters(
'gravityview/view/widgets', Widget_Collection::from_configuration( $configuration ), $view );
778 $view->settings->update( array(
782 self::$cache[
"View::from_post:{$post->ID}" ] = &$view;
789 do_action_ref_array(
'gravityview/view/get', array( &$view ) );
803 unset( self::$cache[
"View::from_post:$view_id" ] );
806 self::$cache = array();
818 public static function by_id( $post_id ) {
819 if ( ! $post_id || !
$post = get_post( $post_id ) ) {
822 return self::from_post(
$post );
835 return get_post_type( $view ) ==
'gravityview';
846 #[\ReturnTypeWillChange] 848 $data_keys = array(
'id',
'view_id',
'form_id',
'template_id',
'atts',
'fields',
'widgets',
'form' );
849 return in_array( $offset, $data_keys );
863 #[\ReturnTypeWillChange] 866 gravityview()->log->notice(
'This is a \GV\View object should not be accessed as an array.' );
868 if ( ! isset( $this[ $offset ] ) ) {
879 return $this->form ? $this->form->ID : null;
881 return $this->settings->as_atts();
883 return $this->settings->get(
'template' );
885 return $this->widgets->as_configuration();
900 #[\ReturnTypeWillChange] 902 gravityview()->log->error(
'The old view data is no longer mutable. This is a \GV\View object should not be accessed as an array.' );
913 #[\ReturnTypeWillChange] 915 gravityview()->log->error(
'The old view data is no longer mutable. This is a \GV\View object should not be accessed as an array.' );
933 'view_id' => $this->ID,
934 'form_id' => $this->form ? $this->form->ID : null,
936 'atts' => $this->settings->as_atts(),
937 'fields' => $this->fields->by_visible( $this )->as_configuration(),
938 'template_id' => $this->settings->get(
'template' ),
939 'widgets' => $this->widgets->as_configuration(),
951 $entries = new \GV\Entry_Collection();
953 if ( ! $this->form ) {
955 return apply_filters(
'gravityview/view/entries',
$entries, $this, $request );
958 $parameters = $this->settings->as_atts();
964 if ( ! empty( $parameters[
'sort_field'] ) && is_array( $parameters[
'sort_field'] ) ) {
965 $has_multisort =
true;
966 $parameters[
'sort_field'] = reset( $parameters[
'sort_field'] );
967 if ( ! empty( $parameters[
'sort_direction'] ) && is_array( $parameters[
'sort_direction'] ) ) {
968 $parameters[
'sort_direction'] = reset( $parameters[
'sort_direction'] );
975 $parameters = \GravityView_frontend::get_view_entries_parameters( $parameters, $this->form->ID );
977 $parameters[
'context_view_id'] = $this->ID;
980 if ( ! is_array( $parameters ) ) {
981 $parameters = array();
984 if ( ! is_array( $parameters[
'search_criteria'] ) ) {
985 $parameters[
'search_criteria'] = array();
988 if ( ( ! isset( $parameters[
'search_criteria'][
'field_filters'] ) ) || ( ! is_array( $parameters[
'search_criteria'][
'field_filters'] ) ) ) {
989 $parameters[
'search_criteria'][
'field_filters'] = array();
992 if ( $request instanceof REST\
Request ) {
993 $atts = $this->settings->as_atts();
994 $paging_parameters = wp_parse_args( $request->get_paging(), array(
995 'paging' => array(
'page_size' => $atts[
'page_size'] ),
997 $parameters[
'paging'] = $paging_parameters[
'paging'];
1000 $page = Utils::get( $parameters[
'paging'],
'current_page' ) ?
1001 : ( ( ( $parameters[
'paging'][
'offset'] - $this->settings->get(
'offset' ) ) / \
GV\Utils::get( $parameters,
'paging/page_size', 25 ) ) + 1 );
1006 $unique_field_filters = array();
1007 foreach ( Utils::get( $parameters,
'search_criteria/field_filters', array() ) as $key => $filter ) {
1008 if (
'mode' === $key ) {
1009 $unique_field_filters[
'mode'] = $filter;
1010 }
else if ( ! in_array( $filter, $unique_field_filters ) ) {
1011 $unique_field_filters[] = $filter;
1014 $parameters[
'search_criteria'][
'field_filters'] = $unique_field_filters;
1016 if ( ! empty( $parameters[
'search_criteria'][
'field_filters'] ) ) {
1017 gravityview()->log->notice(
'search_criteria/field_filters is not empty, third-party code may be using legacy search_criteria filters.' );
1020 if (
gravityview()->plugin->supports( Plugin::FEATURE_GFQUERY ) ) {
1022 $query_class = $this->get_query_class();
1025 $query =
new $query_class( $this->form->ID, $parameters[
'search_criteria'], Utils::get( $parameters,
'sorting' ) );
1030 if ( ! empty( $has_multisort ) ) {
1031 $atts = $this->settings->as_atts();
1033 $view_setting_sort_field_ids =
\GV\Utils::get( $atts,
'sort_field', array() );
1034 $view_setting_sort_directions =
\GV\Utils::get( $atts,
'sort_direction', array() );
1036 $has_sort_query_param = ! empty( $_GET[
'sort'] ) && is_array( $_GET[
'sort'] );
1038 if( $has_sort_query_param ) {
1039 $has_sort_query_param = array_filter( array_values( $_GET[
'sort'] ) );
1042 if ( $this->settings->get(
'sort_columns' ) && $has_sort_query_param ) {
1043 $sort_field_ids = array_keys( $_GET[
'sort'] );
1044 $sort_directions = array_values( $_GET[
'sort'] );
1046 $sort_field_ids = $view_setting_sort_field_ids;
1047 $sort_directions = $view_setting_sort_directions;
1050 $skip_first =
false;
1052 foreach ( (array) $sort_field_ids as $key => $sort_field_id ) {
1054 if ( ! $skip_first && ! $has_sort_query_param ) {
1060 $sort_direction = strtoupper( \
GV\Utils::get( $sort_directions, $key,
'ASC' ) );
1062 if ( ! empty( $sort_field_id ) ) {
1063 $order = new \GF_Query_Column( $sort_field_id, $this->form->ID );
1065 $order = \GF_Query_Call::CAST( $order, defined(
'GF_Query::TYPE_DECIMAL' ) ? \GF_Query::TYPE_DECIMAL : \GF_Query::TYPE_SIGNED );
1068 $query->order( $order, $sort_direction );
1076 add_filter(
'gform_gf_query_sql', $gf_query_timesort_sql_callback =
function( $sql ) use ( &$query ) {
1077 $q = $query->_introspect();
1080 $merged_time =
false;
1082 foreach ( $q[
'order'] as $oid => $order ) {
1086 if ( $order[0] instanceof \GF_Query_Column ) {
1087 $column = $order[0];
1088 }
else if ( $order[0] instanceof \GF_Query_Call ) {
1089 if ( count( $order[0]->columns ) != 1 || ! $order[0]->columns[0] instanceof \GF_Query_Column ) {
1090 $orders[ $oid ] = $order;
1093 $column = $order[0]->columns[0];
1096 if ( ! $column || ( !
$field = \GFAPI::get_field( $column->source, $column->field_id ) ) ||
$field->type !==
'time' ) {
1097 $orders[ $oid ] = $order;
1101 if ( ! class_exists(
'\GV\Mocks\GF_Query_Call_TIMESORT' ) ) {
1102 require_once
gravityview()->plugin->dir(
'future/_mocks.timesort.php' );
1105 $orders[ $oid ] = array(
1106 new \
GV\Mocks\GF_Query_Call_TIMESORT(
'timesort', array( $column, $sql ) ),
1110 $merged_time =
true;
1113 if ( $merged_time ) {
1117 if ( ! empty( $orders ) && $_orders = $query->_order_generate( $orders ) ) {
1118 $sql[
'order'] =
'ORDER BY ' . implode(
', ', $_orders );
1125 $query->limit( $parameters[
'paging'][
'page_size'] )
1126 ->offset( ( ( $page - 1 ) * $parameters[
'paging'][
'page_size'] ) + $this->settings->get(
'offset' ) );
1131 if (
gravityview()->plugin->supports( Plugin::FEATURE_JOINS ) && count( $this->joins ) ) {
1133 $is_admin_and_can_view = $this->settings->get(
'admin_show_all_statuses' ) &&
\GVCommon::has_cap(
'gravityview_moderate_entries', $this->ID );
1135 foreach ( $this->joins as $join ) {
1136 $query = $join->as_query_join( $query );
1138 if ( $this->settings->get(
'multiple_forms_disable_null_joins' ) ) {
1141 $condition = new \GF_Query_Condition(
1142 new \GF_Query_Column( $join->join_on_column->ID, $join->join_on->ID ),
1143 \GF_Query_Condition::NEQ,
1144 new \GF_Query_Literal(
'' )
1147 $query_parameters = $query->_introspect();
1149 $query->where( \GF_Query_Condition::_and( $query_parameters[
'where'], $condition ) );
1156 if ( defined(
'GF_Query_Condition::NULL' ) ) {
1157 $is_null_condition_native =
true;
1159 $is_null_condition_class = apply_filters(
'gravityview/query/is_null_condition', null );
1160 $is_null_condition_native =
false;
1164 $condition = new \GF_Query_Condition(
1165 new \GF_Query_Column(
'status', $join->join_on->ID ),
1166 \GF_Query_Condition::EQ,
1167 new \GF_Query_Literal(
'active' )
1170 if ( $is_null_condition_native ) {
1171 $condition = \GF_Query_Condition::_or( $condition,
new \GF_Query_Condition(
1172 new \GF_Query_Column(
'status', $join->join_on->ID ),
1173 \GF_Query_Condition::IS,
1174 \GF_Query_Condition::NULL
1176 }
else if ( ! is_null( $is_null_condition_class ) ) {
1177 $condition = \GF_Query_Condition::_or( $condition,
new $is_null_condition_class(
1178 new \GF_Query_Column(
'status', $join->join_on->ID )
1182 $q = $query->_introspect();
1183 $query->where( \GF_Query_Condition::_and( $q[
'where'], $condition ) );
1185 if ( $this->settings->get(
'show_only_approved' ) && ! $is_admin_and_can_view ) {
1188 $condition = new \GF_Query_Condition(
1190 \GF_Query_Condition::EQ,
1194 if ( $is_null_condition_native ) {
1195 $condition = \GF_Query_Condition::_or( $condition,
new \GF_Query_Condition(
1197 \GF_Query_Condition::IS,
1198 \GF_Query_Condition::NULL
1200 }
else if ( ! is_null( $is_null_condition_class ) ) {
1201 $condition = \GF_Query_Condition::_or( $condition,
new $is_null_condition_class(
1206 $query_parameters = $query->_introspect();
1208 $query->where( \GF_Query_Condition::_and( $query_parameters[
'where'], $condition ) );
1215 }
else if (
gravityview()->plugin->supports( Plugin::FEATURE_UNIONS ) && count( $this->unions ) ) {
1216 $query_parameters = $query->_introspect();
1218 $unions_sql = array();
1227 $where_union_substitute =
function( $condition, $fields, $recurse ) {
1228 if ( $condition->expressions ) {
1229 $conditions = array();
1231 foreach ( $condition->expressions as $_condition ) {
1232 $conditions[] = $recurse( $_condition, $fields, $recurse );
1235 return call_user_func_array(
1236 array(
'\GF_Query_Condition', $condition->operator ==
'AND' ?
'_and' :
'_or' ),
1241 if ( ! ( $condition->left && $condition->left instanceof \GF_Query_Column ) || ( ! $condition->left->is_entry_column() && ! $condition->left->is_meta_column() ) ) {
1242 return new \GF_Query_Condition(
1243 new \GF_Query_Column( $fields[ $condition->left->field_id ]->ID ),
1244 $condition->operator,
1252 foreach ( $this->unions as
$form_id => $fields ) {
1255 $query_class = $this->get_query_class();
1261 $q->where( $where_union_substitute( $query_parameters[
'where'], $fields, $where_union_substitute ) );
1264 foreach ( $query_parameters[
'order'] as $order ) {
1265 list( $column, $_order ) = $order;
1267 if ( $column && $column instanceof \GF_Query_Column ) {
1268 if ( ! $column->is_entry_column() && ! $column->is_meta_column() ) {
1269 $column = new \GF_Query_Column( $fields[ $column->field_id ]->ID );
1272 $q->order( $column, $_order );
1276 add_filter(
'gform_gf_query_sql', $gf_query_sql_callback =
function( $sql ) use ( &$unions_sql ) {
1278 $select =
'UNION ALL ' . str_replace(
'SQL_CALC_FOUND_ROWS ',
'', $sql[
'select'] );
1281 $unions_sql[] = array(
1283 'select' => preg_replace(
'#DISTINCT (.*)#',
'DISTINCT ', $select ),
1284 'from' => $sql[
'from'],
1285 'join' => $sql[
'join'],
1286 'where' => $sql[
'where'],
1294 do_action_ref_array(
'gravityview/view/query', array( &$q, $this, $request ) );
1298 remove_filter(
'gform_gf_query_sql', $gf_query_sql_callback );
1301 add_filter(
'gform_gf_query_sql', $gf_query_sql_callback =
function( $sql ) use ( $unions_sql ) {
1303 $sql[
'select'] = str_replace(
'SQL_CALC_FOUND_ROWS ',
'', $sql[
'select'] );
1306 preg_match(
'#DISTINCT (`[motc]\d+`.`.*?`)#', $sql[
'select'], $select_match );
1307 $sql[
'select'] = preg_replace(
'#DISTINCT (.*)#',
'DISTINCT ', $sql[
'select'] );
1312 $column_to_alias =
function( $column ) {
1313 $column = str_replace(
'`',
'', $column );
1314 return '`' . str_replace(
'.',
'_', $column ) .
'`';
1318 preg_match_all(
'#(`[motc]\d+`.`.*?`)#', $sql[
'order'], $order_matches );
1321 sprintf(
'%s AS %s', $select_match[1], $column_to_alias( $select_match[1] ) )
1324 foreach ( array_slice( $order_matches, 1 ) as $match ) {
1325 $columns[] = sprintf(
'%s AS %s', $match[0], $column_to_alias( $match[0] ) );
1328 $sql[
'order'] = str_replace( $match[0], $column_to_alias( $match[0] ), $sql[
'order'] );
1331 $columns = array_unique( $columns );
1334 foreach ( $unions_sql as $union_sql ) {
1335 $union_sql[
'select'] .= implode(
', ', $columns );
1336 $unions []= implode(
' ', $union_sql );
1340 $sql[
'select'] =
'SELECT SQL_CALC_FOUND_ROWS t1_id FROM (' . $sql[
'select'] . implode(
', ', $columns );
1341 $sql[
'order'] = implode(
' ', $unions ) .
') AS u ' . $sql[
'order'];
1353 do_action_ref_array(
'gravityview/view/query', array( &$query, $this, $request ) );
1355 gravityview()->log->debug(
'GF_Query parameters: ', array(
'data' => Utils::gf_query_debug( $query ) ) );
1360 if ( count( $this->joins ) ) {
1361 foreach ( $query->get() as
$entry ) {
1363 Multi_Entry::from_entries( array_map(
'\GV\GF_Entry::from_entry',
$entry ) )
1367 array_map( array(
$entries,
'add' ), array_map(
'\GV\GF_Entry::from_entry', $query->get() ) );
1370 if ( isset( $gf_query_sql_callback ) ) {
1371 remove_action(
'gform_gf_query_sql', $gf_query_sql_callback );
1374 if ( isset( $gf_query_timesort_sql_callback ) ) {
1375 remove_action(
'gform_gf_query_sql', $gf_query_timesort_sql_callback );
1381 $entries->add_count_callback(
function() use ( $query ) {
1382 return $query->total_found;
1386 ->filter( \
GV\GF_Entry_Filter::from_search_criteria( $parameters[
'search_criteria'] ) )
1387 ->offset( $this->settings->get(
'offset' ) )
1388 ->limit( $parameters[
'paging'][
'page_size'] )
1391 if ( ! empty( $parameters[
'sorting'] ) && is_array( $parameters[
'sorting'] && ! isset( $parameters[
'sorting'][
'key'] ) ) ) {
1393 $parameters[
'sorting'] = $parameters[
'sorting'][0];
1396 if ( ! empty( $parameters[
'sorting'] ) && ! empty( $parameters[
'sorting'][
'key'] ) ) {
1397 $field = new \GV\Field();
1398 $field->ID = $parameters[
'sorting'][
'key'];
1410 return apply_filters(
'gravityview/view/entries',
$entries, $this, $request );
1422 $is_csv = get_query_var(
'csv' );
1423 $is_tsv = get_query_var(
'tsv' );
1428 if ( ! $is_csv && ! $is_tsv ) {
1438 $error_csv = $view->can_render( array(
'csv' ) );
1440 if ( is_wp_error( $error_csv ) ) {
1441 gravityview()->log->error(
'Not rendering CSV or TSV: ' . $error_csv->get_error_message() );
1445 $file_type = $is_csv ?
'csv' :
'tsv';
1454 $filename = apply_filters(
'gravityview/output/' . $file_type .
'/filename', get_the_title( $view->post ), $view );
1456 if ( ! defined(
'DOING_GRAVITYVIEW_TESTS' ) ) {
1457 header( sprintf(
'Content-Disposition: attachment;filename="%s.' . $file_type .
'"', sanitize_file_name( $filename ) ) );
1458 header(
'Content-Transfer-Encoding: binary' );
1459 header(
'Content-Type: text/' . $file_type );
1463 $csv_or_tsv = fopen(
'php://output',
'w' );
1469 if ( apply_filters(
'gform_include_bom_export_entries',
true, $view->form ? $view->form->form : null ) ) {
1470 fputs( $csv_or_tsv,
"\xef\xbb\xbf" );
1473 if ( $view->settings->get(
'csv_nolimit' ) ) {
1474 $view->settings->update( array(
'page_size' => -1 ) );
1479 $headers_done =
false;
1480 $allowed = $headers = array();
1482 foreach ( $view->fields->by_position(
"directory_*" )->by_visible( $view )->all() as $id =>
$field ) {
1498 $allowed_field_ids = apply_filters(
'gravityview/csv/entry/fields', wp_list_pluck( $allowed,
'ID' ), $view,
$entry );
1500 $allowed = array_filter( $allowed,
function(
$field ) use ( $allowed_field_ids ) {
1501 return in_array(
$field->ID, $allowed_field_ids,
true );
1504 foreach ( array_diff( $allowed_field_ids, wp_list_pluck( $allowed,
'ID' ) ) as
$field_id ) {
1508 foreach ( $allowed as
$field ) {
1509 $source = is_numeric( $field->ID ) ? $view->form : new \GV\Internal_Source();
1511 $return[] = $renderer->render( $field, $view, $source,
$entry,
gravityview()->request,
'\GV\Field_CSV_Template' );
1513 if ( ! $headers_done ) {
1520 $delimiter = (
'tsv' === $file_type ) ?
"\t" :
',';
1522 if ( ! $headers_done ) {
1523 $headers_done = fputcsv( $csv_or_tsv, array_map( array(
'\GV\Utils',
'strip_excel_formulas' ), array_values( $headers ) ), $delimiter );
1526 fputcsv( $csv_or_tsv, array_map( array(
'\GV\Utils',
'strip_excel_formulas' ), $return ), $delimiter );
1529 fflush( $csv_or_tsv );
1531 echo rtrim( ob_get_clean() );
1533 if ( ! defined(
'DOING_GRAVITYVIEW_TESTS' ) ) {
1549 $query_class = apply_filters(
'gravityview/query/class',
'\GF_Query', $this );
1550 return $query_class;
1577 if ( ! apply_filters(
'gravityview/security/require_unfiltered_html',
true, $cap, $user_id ) ) {
1582 case 'edit_gravityview':
1583 case 'edit_gravityviews':
1584 case 'edit_others_gravityviews':
1585 case 'edit_private_gravityviews':
1586 case 'edit_published_gravityviews':
1587 if ( ! user_can( $user_id,
'unfiltered_html' ) ) {
1588 if ( ! user_can( $user_id,
'gravityview_full_access' ) ) {
1589 return array(
'do_not_allow' );
1595 if (
'gravityview' === get_post_type( array_pop(
$args ) ) ) {
1596 return self::restrict( $caps,
'edit_gravityview', $user_id,
$args );
1613 $this->anchor_id = sprintf(
'gv-view-%d-%d', $this->ID, (
int) $counter );
1630 return apply_filters(
'gravityview/view/anchor_id', $this->anchor_id, $this );
1634 if ( $this->post ) {
1635 $raw_post = $this->post->filter(
'raw' );
1636 return $raw_post->{$key};
1638 return isset( $this->{$key} ) ? $this->{$key} : null;
1649 return $this->post ? $this->post : null;
If this file is called directly, abort.
static get_joins( $post)
Get joins associated with a view.
If this file is called directly, abort.
__construct()
The constructor.
static content( $content)
A renderer filter for the View post type content.
static calculate_get_entries_criteria( $passed_criteria=array(), $form_ids=array())
Calculates the Search Criteria used on the self::get_entries / self::get_entry methods.
static _override_sorting_id_by_field_type( $sort_field_id, $form_id)
Override sorting per field.
static restrict( $caps, $cap, $user_id, $args)
Restrict View access to specific capabilities.
as_data()
Be compatible with the old data object.
offsetUnset( $offset)
ArrayAccess compatibility layer with GravityView_View_Data::$views.
offsetSet( $offset, $value)
ArrayAccess compatibility layer with GravityView_View_Data::$views.
can_render( $context=null, $request=null)
Checks whether this view can be accessed or not.
gravityview_get_form( $form_id)
Returns the form object for a given Form ID.
gravityview_get_template_settings( $post_id)
Get all the settings for a View.
If this file is called directly, abort.
offsetGet( $offset)
ArrayAccess compatibility layer with GravityView_View_Data::$views.
if(gravityview() ->plugin->is_GF_25()) $form
static by_id( $form, $field_id)
Get a by and Field ID.
if(empty( $field_settings['content'])) $content
static _flush_cache( $view_id=null)
Flush the view cache.
static no_views_text()
Get text for no views found.
static check_entry_display( $entry, $view=null)
Checks if a certain entry is valid according to the View search filters (specially the Adv Filters) ...
get_post()
Return associated WP post.
If this file is called directly, abort.
static exists( $view)
Determines if a view exists to begin with.
static is_field_numeric( $form=null, $field='')
Checks if the field type is a 'numeric' field type (e.g.
static by_id( $post_id)
Construct a instance from a post ID.
If this file is called directly, abort.
static add_rewrite_endpoint()
Add extra rewrite endpoints.
const GRAVITYVIEW_FILE
Full path to the GravityView file "GRAVITYVIEW_FILE" "./gravityview.php".
offsetExists( $offset)
ArrayAccess compatibility layer with GravityView_View_Data::$views.
set_anchor_id( $counter=1)
Sets the anchor ID of a View, without the prefix.
static template_redirect()
Last chance to configure the output.
static by_id( $field_id)
Get a from an internal Gravity Forms field ID.
if(empty( $created_by)) $form_id
If this file is called directly, abort.
static get( $array, $key, $default=null)
Grab a value from an array or an object or default.
If this file is called directly, abort.
gravityview()
The main GravityView wrapper function.
If this file is called directly, abort.
gravityview_get_template_id( $post_id)
Get the template ID (list, table, datatables, map) for a View.
get_entries( $request=null)
Retrieve the entries for the current view and request.
static get_joined_forms( $post_id)
Get joined forms associated with a view In no particular order.
static is_approved( $status)
If this file is called directly, abort.
static has_cap( $caps='', $object_id=null, $user_id=null)
Alias of GravityView_Roles_Capabilities::has_cap()
get_anchor_id()
Returns the anchor ID to be used in the View container HTML id attribute.
if(false !==strpos( $value, '00:00')) $field_id
string $field_id ID of the field being displayed
static register_post_type()
Register the gravityview WordPress Custom Post Type.
static get_unions( $post)
Get unions associated with a view.
static from_post( $post)
Construct a instance from a .
If this file is called directly, abort.
get_query_class()
Return the query class for this View.