Complex classes like View 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 View, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 17 | class View implements \ArrayAccess { |
||
| 18 | |||
| 19 | /** |
||
| 20 | * @var \WP_Post The backing post instance. |
||
| 21 | */ |
||
| 22 | private $post; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var \GV\View_Settings The settings. |
||
| 26 | * |
||
| 27 | * @api |
||
| 28 | * @since 2.0 |
||
| 29 | */ |
||
| 30 | public $settings; |
||
| 31 | |||
| 32 | /** |
||
| 33 | * @var \GV\Widget_Collection The widets attached here. |
||
| 34 | * |
||
| 35 | * @api |
||
| 36 | * @since 2.0 |
||
| 37 | */ |
||
| 38 | public $widgets; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * @var \GV\GF_Form|\GV\Form The backing form for this view. |
||
| 42 | * |
||
| 43 | * Contains the form that is sourced for entries in this view. |
||
| 44 | * |
||
| 45 | * @api |
||
| 46 | * @since 2.0 |
||
| 47 | */ |
||
| 48 | public $form; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var \GV\Field_Collection The fields for this view. |
||
| 52 | * |
||
| 53 | * Contains all the fields that are attached to this view. |
||
| 54 | * |
||
| 55 | * @api |
||
| 56 | * @since 2.0 |
||
| 57 | */ |
||
| 58 | public $fields; |
||
| 59 | |||
| 60 | /** |
||
| 61 | * @var array |
||
| 62 | * |
||
| 63 | * Internal static cache for gets, and whatnot. |
||
| 64 | * This is not persistent, resets across requests. |
||
| 65 | |||
| 66 | * @internal |
||
| 67 | */ |
||
| 68 | private static $cache = array(); |
||
| 69 | |||
| 70 | /** |
||
| 71 | * @var \GV\Join[] The joins for all sources in this view. |
||
| 72 | * |
||
| 73 | * @api |
||
| 74 | * @since future |
||
| 75 | */ |
||
| 76 | public $joins = array(); |
||
| 77 | |||
| 78 | /** |
||
| 79 | * The constructor. |
||
| 80 | */ |
||
| 81 | 113 | public function __construct() { |
|
| 86 | |||
| 87 | /** |
||
| 88 | * Register the gravityview WordPress Custom Post Type. |
||
| 89 | * |
||
| 90 | * @internal |
||
| 91 | * @return void |
||
| 92 | */ |
||
| 93 | public static function register_post_type() { |
||
| 197 | |||
| 198 | /** |
||
| 199 | * Add extra rewrite endpoints. |
||
| 200 | * |
||
| 201 | * @return void |
||
| 202 | */ |
||
| 203 | 1 | public static function add_rewrite_endpoint() { |
|
| 221 | |||
| 222 | /** |
||
| 223 | * A renderer filter for the View post type content. |
||
| 224 | * |
||
| 225 | * @param string $content Should be empty, as we don't store anything there. |
||
| 226 | * |
||
| 227 | * @return string $content The view content as output by the renderers. |
||
| 228 | */ |
||
| 229 | 10 | public static function content( $content ) { |
|
| 364 | |||
| 365 | /** |
||
| 366 | * Checks whether this view can be accessed or not. |
||
| 367 | * |
||
| 368 | * @param string[] $context The context we're asking for access from. |
||
| 369 | * Can any and as many of one of: |
||
| 370 | * edit An edit context. |
||
| 371 | * single A single context. |
||
| 372 | * cpt The custom post type single page acessed. |
||
| 373 | * shortcode Embedded as a shortcode. |
||
| 374 | * oembed Embedded as an oEmbed. |
||
| 375 | * rest A REST call. |
||
| 376 | * @param \GV\Request $request The request |
||
| 377 | * |
||
| 378 | * @return bool|\WP_Error An error if this View shouldn't be rendered here. |
||
| 379 | */ |
||
| 380 | 19 | public function can_render( $context = null, $request = null ) { |
|
| 381 | 19 | if ( ! $request ) { |
|
| 382 | 1 | $request = gravityview()->request; |
|
| 383 | } |
||
| 384 | |||
| 385 | 19 | if ( ! is_array( $context ) ) { |
|
| 386 | 5 | $context = array(); |
|
| 387 | } |
||
| 388 | |||
| 389 | /** |
||
| 390 | * @filter `gravityview/view/can_render` Whether the view can be rendered or not. |
||
| 391 | * @param bool|\WP_Error $result The result. Default: null. |
||
| 392 | * @param \GV\View $view The view. |
||
| 393 | * @param string[] $context See \GV\View::can_render |
||
| 394 | * @param \GV\Request $request The request. |
||
| 395 | */ |
||
| 396 | 19 | if ( ! is_null( $result = apply_filters( 'gravityview/view/can_render', null, $this, $context, $request ) ) ) { |
|
| 397 | return $result; |
||
| 398 | } |
||
| 399 | |||
| 400 | 19 | if ( in_array( 'rest', $context ) ) { |
|
| 401 | // REST |
||
| 402 | 6 | if ( gravityview()->plugin->settings->get( 'rest_api' ) === '1' && $this->settings->get( 'rest_disable' ) === '1' ) { |
|
| 403 | 1 | return new \WP_Error( 'gravityview/rest_disabled' ); |
|
| 404 | 6 | } elseif ( gravityview()->plugin->settings->get( 'rest_api' ) !== '1' && $this->settings->get( 'rest_enable' ) !== '1' ) { |
|
| 405 | 1 | return new \WP_Error( 'gravityview/rest_disabled' ); |
|
| 406 | } |
||
| 407 | } |
||
| 408 | |||
| 409 | 19 | if ( in_array( 'csv', $context ) ) { |
|
| 410 | 1 | if ( $this->settings->get( 'csv_enable' ) !== '1' ) { |
|
| 411 | 1 | return new \WP_Error( 'gravityview/csv_disabled', 'The CSV endpoint is not enabled for this View' ); |
|
| 412 | } |
||
| 413 | } |
||
| 414 | |||
| 415 | /** |
||
| 416 | * This View is password protected. Nothing to do here. |
||
| 417 | */ |
||
| 418 | 19 | if ( post_password_required( $this->ID ) ) { |
|
| 419 | 3 | gravityview()->log->notice( 'Post password is required for View #{view_id}', array( 'view_id' => $this->ID ) ); |
|
| 420 | 3 | return new \WP_Error( 'gravityview/post_password_required' ); |
|
| 421 | } |
||
| 422 | |||
| 423 | 19 | if ( ! $this->form ) { |
|
| 424 | gravityview()->log->notice( 'View #{id} has no form attached to it.', array( 'id' => $this->ID ) ); |
||
| 425 | return new \WP_Error( 'gravityview/no_form_attached' ); |
||
| 426 | } |
||
| 427 | |||
| 428 | 19 | if ( ! in_array( 'shortcode', $context ) ) { |
|
| 429 | /** |
||
| 430 | * Is this View directly accessible via a post URL? |
||
| 431 | * |
||
| 432 | * @see https://codex.wordpress.org/Function_Reference/register_post_type#public |
||
| 433 | */ |
||
| 434 | |||
| 435 | /** |
||
| 436 | * @filter `gravityview_direct_access` Should Views be directly accessible, or only visible using the shortcode? |
||
| 437 | * @deprecated |
||
| 438 | * @param[in,out] boolean `true`: allow Views to be accessible directly. `false`: Only allow Views to be embedded. Default: `true` |
||
| 439 | * @param int $view_id The ID of the View currently being requested. `0` for general setting |
||
| 440 | */ |
||
| 441 | 12 | $direct_access = apply_filters( 'gravityview_direct_access', true, $this->ID ); |
|
| 442 | |||
| 443 | /** |
||
| 444 | * @filter `gravityview/request/output/direct` Should this View be directly accessbile? |
||
| 445 | * @since 2.0 |
||
| 446 | * @param[in,out] boolean Accessible or not. Default: accessbile. |
||
| 447 | * @param \GV\View $view The View we're trying to directly render here. |
||
| 448 | * @param \GV\Request $request The current request. |
||
| 449 | */ |
||
| 450 | 12 | if ( ! apply_filters( 'gravityview/view/output/direct', $direct_access, $this, $request ) ) { |
|
| 451 | return new \WP_Error( 'gravityview/no_direct_access' ); |
||
| 452 | } |
||
| 453 | |||
| 454 | /** |
||
| 455 | * Is this View an embed-only View? If so, don't allow rendering here, |
||
| 456 | * as this is a direct request. |
||
| 457 | */ |
||
| 458 | 12 | if ( $this->settings->get( 'embed_only' ) && ! \GVCommon::has_cap( 'read_private_gravityviews' ) ) { |
|
| 459 | 1 | return new \WP_Error( 'gravityview/embed_only' ); |
|
| 460 | } |
||
| 461 | } |
||
| 462 | |||
| 463 | /** Private, pending, draft, etc. */ |
||
| 464 | 19 | $public_states = get_post_stati( array( 'public' => true ) ); |
|
| 465 | 19 | if ( ! in_array( $this->post_status, $public_states ) && ! \GVCommon::has_cap( 'read_gravityview', $this->ID ) ) { |
|
| 466 | 3 | gravityview()->log->notice( 'The current user cannot access this View #{view_id}', array( 'view_id' => $this->ID ) ); |
|
| 467 | 3 | return new \WP_Error( 'gravityview/not_public' ); |
|
| 468 | } |
||
| 469 | |||
| 470 | 19 | return true; |
|
| 471 | } |
||
| 472 | |||
| 473 | /** |
||
| 474 | * Get joins associated with a view |
||
| 475 | * |
||
| 476 | * @param \WP_Post $post GravityView CPT to get joins for |
||
| 477 | * |
||
| 478 | * @api |
||
| 479 | * @since 2.0.11 |
||
| 480 | * |
||
| 481 | * @return \GV\Join[] Array of \GV\Join instances |
||
| 482 | */ |
||
| 483 | 113 | public static function get_joins( $post ) { |
|
| 520 | |||
| 521 | /** |
||
| 522 | * Get joined forms associated with a view |
||
| 523 | * |
||
| 524 | * @since 2.0.11 |
||
| 525 | * |
||
| 526 | * @api |
||
| 527 | * @since 2.0 |
||
| 528 | * @param int $post_id ID of the View |
||
| 529 | * |
||
| 530 | * @return \GV\GF_Form[] Array of \GV\GF_Form instances |
||
| 531 | */ |
||
| 532 | public static function get_joined_forms( $post_id ) { |
||
| 567 | |||
| 568 | /** |
||
| 569 | * Construct a \GV\View instance from a \WP_Post. |
||
| 570 | * |
||
| 571 | * @param \WP_Post $post The \WP_Post instance to wrap. |
||
| 572 | * |
||
| 573 | * @api |
||
| 574 | * @since 2.0 |
||
| 575 | * @return \GV\View|null An instance around this \WP_Post if valid, null otherwise. |
||
| 576 | */ |
||
| 577 | 114 | public static function from_post( $post ) { |
|
| 678 | |||
| 679 | /** |
||
| 680 | * Flush the view cache. |
||
| 681 | * |
||
| 682 | * @param int $view_id The View to reset cache for. Optional. Default: resets everything. |
||
| 683 | * |
||
| 684 | * @internal |
||
| 685 | */ |
||
| 686 | 128 | public static function _flush_cache( $view_id = null ) { |
|
| 693 | |||
| 694 | /** |
||
| 695 | * Construct a \GV\View instance from a post ID. |
||
| 696 | * |
||
| 697 | * @param int|string $post_id The post ID. |
||
| 698 | * |
||
| 699 | * @api |
||
| 700 | * @since 2.0 |
||
| 701 | * @return \GV\View|null An instance around this \WP_Post or null if not found. |
||
| 702 | */ |
||
| 703 | 72 | public static function by_id( $post_id ) { |
|
| 709 | |||
| 710 | /** |
||
| 711 | * Determines if a view exists to begin with. |
||
| 712 | * |
||
| 713 | * @param int|\WP_Post|null $view The WordPress post ID, a \WP_Post object or null for global $post; |
||
| 714 | * |
||
| 715 | * @api |
||
| 716 | * @since 2.0 |
||
| 717 | * @return bool Whether the post exists or not. |
||
| 718 | */ |
||
| 719 | 13 | public static function exists( $view ) { |
|
| 722 | |||
| 723 | /** |
||
| 724 | * ArrayAccess compatibility layer with GravityView_View_Data::$views |
||
| 725 | * |
||
| 726 | * @internal |
||
| 727 | * @deprecated |
||
| 728 | * @since 2.0 |
||
| 729 | * @return bool Whether the offset exists or not, limited to GravityView_View_Data::$views element keys. |
||
| 730 | */ |
||
| 731 | 13 | public function offsetExists( $offset ) { |
|
| 735 | |||
| 736 | /** |
||
| 737 | * ArrayAccess compatibility layer with GravityView_View_Data::$views |
||
| 738 | * |
||
| 739 | * Maps the old keys to the new data; |
||
| 740 | * |
||
| 741 | * @internal |
||
| 742 | * @deprecated |
||
| 743 | * @since 2.0 |
||
| 744 | * |
||
| 745 | * @return mixed The value of the requested view data key limited to GravityView_View_Data::$views element keys. |
||
| 746 | */ |
||
| 747 | 13 | public function offsetGet( $offset ) { |
|
| 771 | |||
| 772 | /** |
||
| 773 | * ArrayAccess compatibility layer with GravityView_View_Data::$views |
||
| 774 | * |
||
| 775 | * @internal |
||
| 776 | * @deprecated |
||
| 777 | * @since 2.0 |
||
| 778 | * |
||
| 779 | * @return void |
||
| 780 | */ |
||
| 781 | 1 | public function offsetSet( $offset, $value ) { |
|
| 784 | |||
| 785 | /** |
||
| 786 | * ArrayAccess compatibility layer with GravityView_View_Data::$views |
||
| 787 | * |
||
| 788 | * @internal |
||
| 789 | * @deprecated |
||
| 790 | * @since 2.0 |
||
| 791 | * @return void |
||
| 792 | */ |
||
| 793 | 1 | public function offsetUnset( $offset ) { |
|
| 796 | |||
| 797 | /** |
||
| 798 | * Be compatible with the old data object. |
||
| 799 | * |
||
| 800 | * Some external code expects an array (doing things like foreach on this, or array_keys) |
||
| 801 | * so let's return an array in the old format for such cases. Do not use unless using |
||
| 802 | * for back-compatibility. |
||
| 803 | * |
||
| 804 | * @internal |
||
| 805 | * @deprecated |
||
| 806 | * @since 2.0 |
||
| 807 | * @return array |
||
| 808 | */ |
||
| 809 | 16 | public function as_data() { |
|
| 821 | |||
| 822 | /** |
||
| 823 | * Retrieve the entries for the current view and request. |
||
| 824 | * |
||
| 825 | * @param \GV\Request The request. Unused for now. |
||
| 826 | * |
||
| 827 | * @return \GV\Entry_Collection The entries. |
||
| 828 | */ |
||
| 829 | 36 | public function get_entries( $request = null ) { |
|
| 830 | 36 | $entries = new \GV\Entry_Collection(); |
|
| 831 | 36 | if ( $this->form ) { |
|
| 832 | /** |
||
| 833 | * @todo: Stop using _frontend and use something like $request->get_search_criteria() instead |
||
| 834 | */ |
||
| 835 | 36 | $parameters = \GravityView_frontend::get_view_entries_parameters( $this->settings->as_atts(), $this->form->ID ); |
|
| 836 | 36 | $parameters['context_view_id'] = $this->ID; |
|
| 837 | 36 | $parameters = \GVCommon::calculate_get_entries_criteria( $parameters, $this->form->ID ); |
|
| 838 | |||
| 839 | 36 | if ( $request instanceof REST\Request ) { |
|
| 840 | 4 | $atts = $this->settings->as_atts(); |
|
| 841 | 4 | $paging_parameters = wp_parse_args( $request->get_paging(), array( |
|
| 842 | 4 | 'paging' => array( 'page_size' => $atts['page_size'] ), |
|
| 843 | ) ); |
||
| 844 | 4 | $parameters['paging'] = $paging_parameters['paging']; |
|
| 845 | } |
||
| 846 | |||
| 847 | 36 | $page = Utils::get( $parameters['paging'], 'current_page' ) ? |
|
| 848 | 36 | : ( ( ( $parameters['paging']['offset'] - $this->settings->get( 'offset' ) ) / $parameters['paging']['page_size'] ) + 1 ); |
|
| 849 | |||
| 850 | /** |
||
| 851 | * Cleanup duplicate field_filter parameters to simplify the query. |
||
| 852 | */ |
||
| 853 | 36 | $unique_field_filters = array(); |
|
| 854 | 36 | foreach ( $parameters['search_criteria']['field_filters'] as $key => $filter ) { |
|
| 855 | 7 | if ( 'mode' === $key ) { |
|
| 856 | 7 | $unique_field_filters['mode'] = $filter; |
|
| 857 | 7 | } else if ( ! in_array( $filter, $unique_field_filters ) ) { |
|
| 858 | 7 | $unique_field_filters[] = $filter; |
|
| 859 | } |
||
| 860 | } |
||
| 861 | 36 | $parameters['search_criteria']['field_filters'] = $unique_field_filters; |
|
| 862 | |||
| 863 | 36 | if ( ! empty( $parameters['search_criteria']['field_filters'] ) ) { |
|
| 864 | 7 | gravityview()->log->notice( 'search_criteria/field_filters is not empty, third-party code may be using legacy search_criteria filters.' ); |
|
| 865 | } |
||
| 866 | |||
| 867 | 36 | if ( gravityview()->plugin->supports( Plugin::FEATURE_GFQUERY ) ) { |
|
| 868 | /** |
||
| 869 | * New \GF_Query stuff :) |
||
| 870 | */ |
||
| 871 | 36 | $query = new \GF_Query( $this->form->ID, $parameters['search_criteria'], $parameters['sorting'] ); |
|
| 872 | |||
| 873 | 36 | $query->limit( $parameters['paging']['page_size'] ) |
|
| 874 | 36 | ->offset( ( ( $page - 1 ) * $parameters['paging']['page_size'] ) + $this->settings->get( 'offset' ) ); |
|
| 875 | |||
| 876 | /** |
||
| 877 | * Any joins? |
||
| 878 | */ |
||
| 879 | 36 | if ( Plugin::FEATURE_JOINS && count( $this->joins ) ) { |
|
| 880 | 4 | foreach ( $this->joins as $join ) { |
|
| 881 | 4 | $query = $join->as_query_join( $query ); |
|
| 882 | } |
||
| 883 | } |
||
| 884 | |||
| 885 | /** |
||
| 886 | * @action `gravityview/view/query` Override the \GF_Query before the get() call. |
||
| 887 | * @param \GF_Query $query The current query object reference |
||
| 888 | * @param \GV\View $this The current view object |
||
| 889 | * @param \GV\Request $request The request object |
||
| 890 | */ |
||
| 891 | 36 | do_action_ref_array( 'gravityview/view/query', array( &$query, $this, $request ) ); |
|
| 892 | |||
| 893 | 36 | gravityview()->log->debug( 'GF_Query parameters: ', array( 'data' => Utils::gf_query_debug( $query ) ) ); |
|
| 894 | |||
| 895 | /** |
||
| 896 | * Map from Gravity Forms entries arrays to an Entry_Collection. |
||
| 897 | */ |
||
| 898 | 36 | if ( count( $this->joins ) ) { |
|
| 899 | 4 | foreach ( $query->get() as $entry ) { |
|
| 900 | 4 | $entries->add( |
|
| 901 | 4 | Multi_Entry::from_entries( array_map( '\GV\GF_Entry::from_entry', $entry ) ) |
|
| 902 | ); |
||
| 903 | } |
||
| 904 | } else { |
||
| 905 | 32 | array_map( array( $entries, 'add' ), array_map( '\GV\GF_Entry::from_entry', $query->get() ) ); |
|
| 906 | } |
||
| 907 | |||
| 908 | /** |
||
| 909 | * Add total count callback. |
||
| 910 | */ |
||
| 911 | 36 | $entries->add_count_callback( function() use ( $query ) { |
|
| 912 | 23 | return $query->total_found; |
|
| 913 | 36 | } ); |
|
| 914 | } else { |
||
| 915 | $entries = $this->form->entries |
||
| 916 | ->filter( \GV\GF_Entry_Filter::from_search_criteria( $parameters['search_criteria'] ) ) |
||
| 917 | ->offset( $this->settings->get( 'offset' ) ) |
||
| 918 | ->limit( $parameters['paging']['page_size'] ) |
||
| 919 | ->page( $page ); |
||
| 920 | |||
| 921 | if ( ! empty( $parameters['sorting'] ) && ! empty( $parameters['sorting']['key'] ) ) { |
||
| 922 | $field = new \GV\Field(); |
||
| 923 | $field->ID = $parameters['sorting']['key']; |
||
| 924 | $direction = strtolower( $parameters['sorting']['direction'] ) == 'asc' ? \GV\Entry_Sort::ASC : \GV\Entry_Sort::DESC; |
||
| 925 | $entries = $entries->sort( new \GV\Entry_Sort( $field, $direction ) ); |
||
| 926 | } |
||
| 927 | } |
||
| 928 | } |
||
| 929 | |||
| 930 | /** |
||
| 931 | * @filter `gravityview/view/entries` Modify the entry fetching filters, sorts, offsets, limits. |
||
| 932 | * @param \GV\Entry_Collection $entries The entries for this view. |
||
| 933 | * @param \GV\View $view The view. |
||
| 934 | * @param \GV\Request $request The request. |
||
| 935 | */ |
||
| 936 | 36 | return apply_filters( 'gravityview/view/entries', $entries, $this, $request ); |
|
| 937 | } |
||
| 938 | |||
| 939 | /** |
||
| 940 | * Last chance to configure the output. |
||
| 941 | * |
||
| 942 | * Used for CSV output, for example. |
||
| 943 | * |
||
| 944 | * @return void |
||
| 945 | */ |
||
| 946 | 1 | public static function template_redirect() { |
|
| 947 | /** |
||
| 948 | * CSV output. |
||
| 949 | */ |
||
| 950 | 1 | if ( ! get_query_var( 'csv' ) ) { |
|
| 951 | 1 | return; |
|
| 952 | } |
||
| 953 | |||
| 954 | 1 | if ( ! $view = gravityview()->request->is_view() ) { |
|
| 955 | 1 | return; |
|
| 956 | } |
||
| 957 | |||
| 958 | 1 | if ( is_wp_error( $error = $view->can_render( array( 'csv' ) ) ) ) { |
|
| 959 | 1 | gravityview()->log->error( 'Not rendering CSV: ' . $error->get_error_message() ); |
|
| 960 | 1 | return; |
|
| 961 | } |
||
| 962 | |||
| 963 | /** |
||
| 964 | * Modify the name of the generated CSV file. Name will be sanitized using sanitize_file_name() before output. |
||
| 965 | * @see sanitize_file_name() |
||
| 966 | * @since 2.1 |
||
| 967 | * @param string $filename File name used when downloading a CSV. Default is "{View title}.csv" |
||
| 968 | * @param \GV\View $view Current View being rendered |
||
| 969 | */ |
||
| 970 | 1 | $filename = apply_filters( 'gravityview/output/csv/filename', get_the_title( $view->post ), $view ); |
|
| 971 | |||
| 972 | 1 | if ( ! defined( 'DOING_GRAVITYVIEW_TESTS' ) ) { |
|
| 973 | header( sprintf( 'Content-Disposition: attachment;filename="%s.csv"', sanitize_file_name( $filename ) ) ); |
||
| 974 | header( 'Content-Transfer-Encoding: binary' ); |
||
| 975 | header( 'Content-Type: text/csv' ); |
||
| 976 | } |
||
| 977 | |||
| 978 | 1 | ob_start(); |
|
| 979 | 1 | $csv = fopen( 'php://output', 'w' ); |
|
| 980 | |||
| 981 | /** |
||
| 982 | * Add da' BOM if GF uses it |
||
| 983 | * @see GFExport::start_export() |
||
| 984 | */ |
||
| 985 | 1 | if ( apply_filters( 'gform_include_bom_export_entries', true, $view->form ? $view->form->form : null ) ) { |
|
| 986 | fputs( $csv, "\xef\xbb\xbf" ); |
||
| 987 | } |
||
| 988 | |||
| 989 | 1 | $entries = $view->get_entries(); |
|
| 990 | |||
| 991 | 1 | $headers_done = false; |
|
| 992 | 1 | $allowed = $headers = array(); |
|
| 993 | |||
| 994 | 1 | foreach ( $view->fields->by_position( "directory_*" )->by_visible()->all() as $field ) { |
|
| 995 | 1 | $allowed[ $field->ID ] = $field; |
|
| 996 | } |
||
| 997 | |||
| 998 | 1 | $renderer = new Field_Renderer(); |
|
| 999 | |||
| 1000 | 1 | foreach ( $entries->all() as $entry ) { |
|
| 1001 | |||
| 1002 | 1 | $return = array(); |
|
| 1003 | |||
| 1004 | /** |
||
| 1005 | * @filter `gravityview/csv/entry/fields` Whitelist more entry fields that are output in CSV requests. |
||
| 1006 | * @param[in,out] array $allowed The allowed ones, default by_visible, by_position( "context_*" ), i.e. as set in the View. |
||
| 1007 | * @param \GV\View $view The view. |
||
| 1008 | * @param \GV\Entry $entry WordPress representation of the item. |
||
| 1009 | */ |
||
| 1010 | 1 | $allowed_field_ids = apply_filters( 'gravityview/csv/entry/fields', array_keys( $allowed ), $view, $entry ); |
|
| 1011 | |||
| 1012 | 1 | foreach ( $allowed_field_ids as $field_id ) { |
|
| 1013 | 1 | $source = is_numeric( $field_id ) ? $view->form : new \GV\Internal_Source(); |
|
| 1014 | |||
| 1015 | 1 | if ( isset( $allowed[ $field_id ] ) ) { |
|
| 1016 | 1 | $field = $allowed[ $field_id ]; |
|
| 1017 | } else { |
||
| 1018 | $field = is_numeric( $field_id ) ? \GV\GF_Field::by_id( $view->form, $field_id ) : \GV\Internal_Field::by_id( $field_id ); |
||
| 1019 | } |
||
| 1020 | |||
| 1021 | 1 | $return[ $field->ID ] = $renderer->render( $field, $view, $source, $entry, gravityview()->request, '\GV\Field_CSV_Template' ); |
|
| 1022 | |||
| 1023 | 1 | if ( ! $headers_done ) { |
|
| 1024 | 1 | $label = $field->get_label( $view, $source, $entry ); |
|
| 1025 | 1 | $headers[ $field->ID ] = $label ? $label : $field->ID; |
|
| 1026 | } |
||
| 1027 | } |
||
| 1028 | |||
| 1029 | 1 | if ( ! $headers_done ) { |
|
| 1030 | 1 | $headers_done = fputcsv( $csv, array_map( array( '\GV\Utils', 'strip_excel_formulas' ), array_values( $headers ) ) ); |
|
| 1031 | } |
||
| 1032 | |||
| 1033 | 1 | fputcsv( $csv, array_map( array( '\GV\Utils', 'strip_excel_formulas' ), $return ) ); |
|
| 1034 | } |
||
| 1035 | |||
| 1036 | 1 | fflush( $csv ); |
|
| 1037 | |||
| 1038 | 1 | echo rtrim( ob_get_clean() ); |
|
| 1039 | |||
| 1040 | 1 | if ( ! defined( 'DOING_GRAVITYVIEW_TESTS' ) ) { |
|
| 1041 | exit; |
||
| 1042 | } |
||
| 1043 | 1 | } |
|
| 1044 | |||
| 1045 | 113 | public function __get( $key ) { |
|
| 1052 | } |
||
| 1053 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.